⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 service.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#ifdef WIN32#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <process.h>#include <direct.h>#include "httpd.h"#include "http_conf_globals.h"#include "http_log.h"#include "http_main.h"#include "multithread.h"#include "service.h"#include "registry.h"#include "Win9xConHook.h"#define SERVICE_APACHE_RESTART 128static struct{    int (*main_fn)(int, char **);    int connected;    SERVICE_STATUS_HANDLE hServiceStatus;    char *name;    int exit_status;    SERVICE_STATUS ssStatus;    FILE *logFile;} globdat;/* statics for atexit processing or shared between threads */static BOOL  die_on_logoff = FALSE;static HWND  console_wnd = NULL;static int   is_service = -1;static void WINAPI service_main_fn(DWORD, LPTSTR *);static void WINAPI service_ctrl(DWORD ctrlCode);static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint);static int ap_start_service(SC_HANDLE, DWORD argc, char **argv);static int ap_stop_service(SC_HANDLE);static int ap_restart_service(SC_HANDLE);/* exit() for Win32 is macro mapped (horrible, we agree) that allows us  * to catch the non-zero conditions and inform the console process that * the application died, and hang on to the console a bit longer. * * The macro only maps for http_main.c and other sources that include * the service.h header, so we best assume it's an error to exit from * _any_ other module. * * If real_exit_code is not set to 2, it will not be set or trigger this * behavior on exit.  All service and child processes are expected to * reset this flag to zero to avoid undesireable side effects.  The value * 1 simply tells the system it is safe to enable the feature (set to 2), * while 0 prohibits the feature from being enabled. */int real_exit_code = 1;void hold_console_open_on_error(void){    HANDLE hConIn;    HANDLE hConErr;    DWORD result;    DWORD mode;    time_t start;    time_t remains;    char *msg = "Note the errors or messages above, "                "and press the <ESC> key to exit.  ";    CONSOLE_SCREEN_BUFFER_INFO coninfo;    INPUT_RECORD in;    char count[16];#ifdef WIN32    /* The service parent cannot just 'pop' out of the main thread,     * as it is about to try to do...     * We must end this thread properly so the service control     * thread exits gracefully.  atexit()s registered in the running     * apache_main thread _should_ have already been handled, so now     * we can exit this thread and allow the service thread to exit.     */    if (isWindowsNT() && isProcessService() && globdat.connected) {        service_set_status(SERVICE_STOPPED);        ExitThread(0);    }#endif    if (!real_exit_code)        return;    hConIn = GetStdHandle(STD_INPUT_HANDLE);    hConErr = GetStdHandle(STD_ERROR_HANDLE);    if ((hConIn == INVALID_HANDLE_VALUE) || (hConErr == INVALID_HANDLE_VALUE))        return;    if (!WriteConsole(hConErr, msg, strlen(msg), &result, NULL) || !result)        return;    if (!GetConsoleScreenBufferInfo(hConErr, &coninfo))        return;    if (isWindowsNT())        mode = ENABLE_MOUSE_INPUT | 0x80;    else        mode = ENABLE_MOUSE_INPUT;    if (!SetConsoleMode(hConIn, mode))        return;            start = time(NULL);    do    {        while (PeekConsoleInput(hConIn, &in, 1, &result) && result)        {            if (!ReadConsoleInput(hConIn, &in, 1, &result) || !result)                return;            if ((in.EventType == KEY_EVENT) && in.Event.KeyEvent.bKeyDown                     && (in.Event.KeyEvent.uChar.AsciiChar == 27))                return;            if (in.EventType == MOUSE_EVENT                     && (in.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))                return;        }        remains = ((start + 30) - time(NULL));         sprintf (count, "%d...", remains);        if (!SetConsoleCursorPosition(hConErr, coninfo.dwCursorPosition))            return;        if (!WriteConsole(hConErr, count, strlen(count), &result, NULL)                 || !result)            return;    }    while ((remains > 0) && WaitForSingleObject(hConIn, 1000) != WAIT_FAILED);}/* Console Control handler for processing Ctrl-C/Ctrl-Break and * on Windows NT also user logoff and system shutdown, * this also used for the Win9x hidden service and child process */static BOOL CALLBACK ap_control_handler(DWORD ctrl_type){    switch (ctrl_type)    {        case CTRL_C_EVENT:        case CTRL_BREAK_EVENT:            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                         "Ctrl+C/Break initiated, shutting down server.");            real_exit_code = 0;            /* for Interrupt signals, shut down the server.             * Tell the system we have dealt with the signal             * without waiting for Apache to terminate.             */            ap_start_shutdown();            return TRUE;        case CTRL_LOGOFF_EVENT:            if (!die_on_logoff)                return TRUE;            /* or fall through... */        case CTRL_CLOSE_EVENT:        case CTRL_SHUTDOWN_EVENT:            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                         "Close/Logoff/Shutdown initiated, shutting down server.");            /* for Terminate signals, shut down the server.             * Wait for Apache to terminate, but respond             * after a reasonable time to tell the system             * that we have already tried to shut down.             */            real_exit_code = 0;            fprintf(stderr, "Apache server shutdown initiated...\n");            ap_start_shutdown();            Sleep(30000);            return TRUE;    }     /* We should never get here, but this is (mostly) harmless */    return FALSE;}/* Once we are running a child process in our tty, it can no longer  * determine which console window is our own, since the window * reports that it is owned by the child process. */static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd){    char tmp[20], *tty;    if (isWindowsNT())        tty = "ConsoleWindowClass";    else        tty = "tty";    if (GetClassName(wnd, tmp, sizeof(tmp)) && !strcmp(tmp, tty))     {        DWORD wndproc, thisproc = GetCurrentProcessId();        GetWindowThreadProcessId(wnd, &wndproc);        if (wndproc == thisproc) {            *((HWND*)retwnd) = wnd;            return FALSE;        }    }    return TRUE;}void stop_child_monitor(void){    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                 "Unhooking the child process monitor for shutdown.");    FixConsoleCtrlHandler(ap_control_handler, 0);}/* * The Win32 Apache child cannot loose its console since 16bit cgi  * processes will hang (9x) or fail (NT) if they are not launched  * from a 32bit console app into that app's console window.   * Mark the 9x child as a service process and let the parent process  * clean it up as necessary. */void ap_start_child_console(int is_child_of_service){    int maxwait = 100;    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                 "Hooking up the child process monitor to watch for shutdown.");    /* The child is never exactly a service */    is_service = 0;        /* Prevent holding open the (hidden) console */    real_exit_code = 0;    /* We only die on logoff if we not a service's child */    die_on_logoff = !is_child_of_service;    if (isWindowsNT()) {        if (!is_child_of_service) {            /*             * Console mode Apache/WinNT needs to detach from the parent             * console and create and hide it's own console window.             * Not only is logout and shutdown more stable under W2K,             * but this eliminates the mystery 'flicker' that users see             * when invoking CGI apps (e.g. the titlebar or icon of the             * console window changing to the cgi process's identifiers.)             */            FreeConsole();            AllocConsole();            EnumWindows(EnumttyWindow, (long)(&console_wnd));            if (console_wnd)                ShowWindow(console_wnd, SW_HIDE);        }        /*         * Apache/WinNT installs no child console handler, otherwise         * logoffs interfere with the service's child process!         * The child process must have a later shutdown priority         * than the parent, or the parent cannot shut down the         * child process properly.  (The parent's default is 0x280.)         */        SetProcessShutdownParameters(0x200, 0);        return;    }    if (!is_child_of_service) {        FreeConsole();        AllocConsole();    }    while (!console_wnd && maxwait-- > 0) {         EnumWindows(EnumttyWindow, (long)(&console_wnd));        Sleep(100);    }    if (console_wnd) {        FixConsoleCtrlHandler(ap_control_handler, die_on_logoff ? 1 : 2);        ShowWindow(console_wnd, SW_HIDE);        atexit(stop_child_monitor);    }}void stop_console_monitor(void){    /* Remove the control handler at the end of the day. */    SetConsoleCtrlHandler(ap_control_handler, FALSE);    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                 "Unhooking the console monitor for shutdown.");    if (!isWindowsNT())        FixConsoleCtrlHandler(ap_control_handler, 0);}void ap_start_console_monitor(void){    HANDLE console_input;    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                 "Hooking up the console monitor to watch for shutdown.");    die_on_logoff = TRUE;    is_service = 0;    console_input = GetStdHandle(STD_INPUT_HANDLE);    /* Assure we properly accept Ctrl+C as an interrupt...     * Win/2000 definately makes some odd assumptions about      * ctrl+c and the reserved console mode bits!     */    if (console_input != INVALID_HANDLE_VALUE)    {        /* The SetConsoleCtrlHandler(NULL... would fault under Win9x          * WinNT also includes an undocumented 0x80 bit for console mode         * that preserves the console window behavior, and prevents the         * bogus 'selection' mode from being accedently triggered.         */        if (isWindowsNT()) {	    SetConsoleCtrlHandler(NULL, FALSE);            SetConsoleMode(console_input, ENABLE_LINE_INPUT                                         | ENABLE_ECHO_INPUT                                         | ENABLE_PROCESSED_INPUT                                        | 0x80);        }	else {            SetConsoleMode(console_input, ENABLE_LINE_INPUT                                         | ENABLE_ECHO_INPUT                                         | ENABLE_PROCESSED_INPUT);        }    }        if (!isWindowsNT())        FixConsoleCtrlHandler(ap_control_handler, die_on_logoff ? 1 : 2);    SetConsoleCtrlHandler(ap_control_handler, TRUE);    atexit(stop_console_monitor);}void stop_service_monitor(void){    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                 "Unhooking up the service monitor for shutdown.");    Windows9xServiceCtrlHandler(ap_control_handler, FALSE);}int service95_main(int (*main_fn)(int, char **), int argc, char **argv, 		   char *display_name){    /* Windows 95/98 */    char *service_name;    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                 "Hooking up the service monitor to watch for shutdown.");    is_service = 1;    die_on_logoff = FALSE;    /* Set up the Win9x server name, as WinNT would */    ap_server_argv0 = globdat.name = display_name;    /* Remove spaces from display name to create service name */    service_name = strdup(display_name);    ap_remove_spaces(service_name, display_name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -