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

📄 service.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 4 页
字号:
             * The system will also signal the parent process,             * which will terminate Apache, so we need to wait.             */            Sleep(30000);            return TRUE;    }     /* We should never get here, but this is (mostly) harmless */    return FALSE;}static void stop_child_console_handler(void){    SetConsoleCtrlHandler(child_control_handler, FALSE);}void mpm_start_child_console_handler(void){    if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {        FreeConsole();    }    else    {        SetConsoleCtrlHandler(child_control_handler, TRUE);        atexit(stop_child_console_handler);    }}/**********************************  WinNT service control management **********************************/static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint){    static int checkPoint = 1;    int rv = APR_SUCCESS;        if (globdat.hServiceStatus)    {        if (currentState == SERVICE_RUNNING) {            globdat.ssStatus.dwWaitHint = 0;            globdat.ssStatus.dwCheckPoint = 0;            globdat.ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;        }        else if (currentState == SERVICE_STOPPED) {            globdat.ssStatus.dwWaitHint = 0;            globdat.ssStatus.dwCheckPoint = 0;            if (!exitCode && globdat.ssStatus.dwCurrentState                                            != SERVICE_STOP_PENDING) {                /* An unexpected exit?  Better to error! */                exitCode = 1;            }            if (exitCode) {                globdat.ssStatus.dwWin32ExitCode =ERROR_SERVICE_SPECIFIC_ERROR;                globdat.ssStatus.dwServiceSpecificExitCode = exitCode;            }        }        else {            globdat.ssStatus.dwCheckPoint = ++checkPoint;	    globdat.ssStatus.dwControlsAccepted = 0;            if(waitHint)                globdat.ssStatus.dwWaitHint = waitHint;        }        globdat.ssStatus.dwCurrentState = currentState;                rv = SetServiceStatus(globdat.hServiceStatus, &globdat.ssStatus);    }    return(rv);}/* Set the service description regardless of platform. * We revert to set_service_description on NT/9x, the * very long way so any Apache management program can grab the * description.  This would be bad on Win2000, since it wouldn't * notify the service control manager of the name change. *//* borrowed from mpm_winnt.c */extern apr_pool_t *pconf;/* Windows 2000 alone supports ChangeServiceConfig2 in order to * register our server_version string... so we need some fixups * to avoid binding to that function if we are on WinNT/9x. */static void set_service_description(void){    const char *full_description;    SC_HANDLE schSCManager;    BOOL ret = 0;    /* Nothing to do if we are a console     */    if (!mpm_service_name)        return;    /* Time to fix up the description, upon each successful restart     */    full_description = ap_get_server_version();    if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT)           && (osver.dwMajorVersion > 4)           && (ChangeServiceConfig2)          && (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)))    {            SC_HANDLE schService = OpenService(schSCManager, mpm_service_name,                                           SERVICE_CHANGE_CONFIG);        if (schService) {            /* Cast is necessary, ChangeServiceConfig2 handles multiple             * object types, some volatile, some not.             */            /* ###: utf-ize */            if (ChangeServiceConfig2(schService,                                     1 /* SERVICE_CONFIG_DESCRIPTION */,                                     (LPVOID) &full_description)) {                full_description = NULL;            }            CloseServiceHandle(schService);        }        CloseServiceHandle(schSCManager);    }    if (full_description)     {        char szPath[MAX_PATH];        ap_regkey_t *svckey;        apr_status_t rv;        /* Find the Service key that Monitor Applications iterate */        apr_snprintf(szPath, sizeof(szPath),                      "SYSTEM\\CurrentControlSet\\Services\\%s",                      mpm_service_name);        rv = ap_regkey_open(&svckey, AP_REGKEY_LOCAL_MACHINE, szPath,                            APR_READ | APR_WRITE, pconf);        if (rv != APR_SUCCESS) {            return;        }        /* Attempt to set the Description value for our service */        ap_regkey_value_set(svckey, "Description", full_description, 0, pconf);        ap_regkey_close(svckey);    }}/* handle the SCM's ControlService() callbacks to our service */static VOID WINAPI service_nt_ctrl(DWORD dwCtrlCode){    if (dwCtrlCode == SERVICE_CONTROL_STOP)    {        ap_signal_parent(SIGNAL_PARENT_SHUTDOWN);        ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 30000);        return;    }    if (dwCtrlCode == SERVICE_APACHE_RESTART)    {        ap_signal_parent(SIGNAL_PARENT_RESTART);        ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000);        return;    }        ReportStatusToSCMgr(globdat.ssStatus.dwCurrentState, NO_ERROR, 0);            }/* service_nt_main_fn is outside of the call stack and outside of the * primary server thread... so now we _really_ need a placeholder! * The winnt_rewrite_args has created and shared mpm_new_argv with us. */extern apr_array_header_t *mpm_new_argv;/* ###: utf-ize */static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv){    const char *ignored;    /* args and service names live in the same pool */    mpm_service_set_name(mpm_new_argv->pool, &ignored, argv[0]);    memset(&globdat.ssStatus, 0, sizeof(globdat.ssStatus));    globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;    globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING;    globdat.ssStatus.dwCheckPoint = 1;    /* ###: utf-ize */    if (!(globdat.hServiceStatus = RegisterServiceCtrlHandler(argv[0], service_nt_ctrl)))    {        ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(),                      NULL, "Failure registering service handler");        return;    }    /* Report status, no errors, and buy 3 more seconds */    ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000);    /* We need to append all the command arguments passed via StartService()      * to our running service... which just got here via the SCM...     * but we hvae no interest in argv[0] for the mpm_new_argv list.     */    if (argc > 1)     {        char **cmb_data;        mpm_new_argv->nalloc = mpm_new_argv->nelts + argc - 1;        cmb_data = malloc(mpm_new_argv->nalloc * sizeof(const char *));        /* mpm_new_argv remains first (of lower significance) */        memcpy (cmb_data, mpm_new_argv->elts,                 mpm_new_argv->elt_size * mpm_new_argv->nelts);                /* Service args follow from StartService() invocation */        memcpy (cmb_data + mpm_new_argv->nelts, argv + 1,                 mpm_new_argv->elt_size * (argc - 1));                /* The replacement arg list is complete */        mpm_new_argv->elts = (char *)cmb_data;        mpm_new_argv->nelts = mpm_new_argv->nalloc;    }    /* Let the main thread continue now... but hang on to the     * signal_monitor event so we can take further action     */    SetEvent(globdat.service_init);    WaitForSingleObject(globdat.service_term, INFINITE);}DWORD WINAPI service_nt_dispatch_thread(LPVOID nada){    apr_status_t rv = APR_SUCCESS;    SERVICE_TABLE_ENTRY dispatchTable[] =    {        { "", service_nt_main_fn },        { NULL, NULL }    };    /* ###: utf-ize */    if (!StartServiceCtrlDispatcher(dispatchTable))    {        /* This is a genuine failure of the SCM. */        rv = apr_get_os_error();        ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,                     "Error starting service control dispatcher");    }    return (rv);}apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name,                                   const char *set_name){    char key_name[MAX_PATH];    ap_regkey_t *key;    apr_status_t rv;    /* ### Needs improvement, on Win2K the user can _easily_      * change the display name to a string that doesn't reflect      * the internal service name + whitespace!     */    mpm_service_name = apr_palloc(p, strlen(set_name) + 1);    apr_collapse_spaces((char*) mpm_service_name, set_name);    apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name);    rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ, pconf);    if (rv == APR_SUCCESS) {        rv = ap_regkey_value_get(&mpm_display_name, key, "DisplayName", pconf);        ap_regkey_close(key);    }    if (rv != APR_SUCCESS) {        /* Take the given literal name if there is no service entry */        mpm_display_name = apr_pstrdup(p, set_name);    }     *display_name = mpm_display_name;    return rv;}apr_status_t mpm_merge_service_args(apr_pool_t *p,                                    apr_array_header_t *args,                                    int fixed_args){    apr_array_header_t *svc_args = NULL;    char conf_key[MAX_PATH];    char **cmb_data;    apr_status_t rv;    ap_regkey_t *key;    apr_snprintf(conf_key, sizeof(conf_key), SERVICEPARAMS, mpm_service_name);    rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, conf_key, APR_READ, p);    if (rv == APR_SUCCESS) {        rv = ap_regkey_value_array_get(&svc_args, key, "ConfigArgs", p);        ap_regkey_close(key);    }    if (rv != APR_SUCCESS) {        if (rv == ERROR_FILE_NOT_FOUND) {            ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL,                         "No ConfigArgs registered for %s, perhaps "                         "this service is not installed?",                          mpm_service_name);            return APR_SUCCESS;        }        else            return (rv);            }    if (!svc_args || svc_args->nelts == 0) {        return (APR_SUCCESS);    }    /* Now we have the mpm_service_name arg, and the mpm_runservice_nt()     * call appended the arguments passed by StartService(), so it's       * time to _prepend_ the default arguments for the server from      * the service's default arguments (all others override them)...     */    args->nalloc = args->nelts + svc_args->nelts;    cmb_data = malloc(args->nalloc * sizeof(const char *));    /* First three args (argv[0], -f, path) remain first */    memcpy(cmb_data, args->elts, args->elt_size * fixed_args);        /* Service args follow from service registry array */    memcpy(cmb_data + fixed_args, svc_args->elts,            svc_args->elt_size * svc_args->nelts);        /* Remaining new args follow  */    memcpy(cmb_data + fixed_args + svc_args->nelts,           (const char **)args->elts + fixed_args,            args->elt_size * (args->nelts - fixed_args));        args->elts = (char *)cmb_data;    args->nelts = args->nalloc;    return APR_SUCCESS;

⌨️ 快捷键说明

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