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

📄 mpm_winnt.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
    return APR_ENOTIMPL;} #define SERVICE_UNSET (-1)static apr_status_t service_set = SERVICE_UNSET;static apr_status_t service_to_start_success;static int inst_argc;static const char * const *inst_argv;static char *service_name = NULL;    void winnt_rewrite_args(process_rec *process) {    /* Handle the following SCM aspects in this phase:     *     *   -k runservice [transition for WinNT, nothing for Win9x]     *   -k (!)install [error out if name is not installed]     *   -k uninstall     *   -k stop     *   -k shutdown (same as -k stop). Maintained for backward compatability.     *     * We can't leave this phase until we know our identity     * and modify the command arguments appropriately.     *     * We do not care if the .conf file exists or is parsable when     * attempting to stop or uninstall a service.     */    apr_status_t rv;    char *def_server_root;    char *binpath;    char optbuf[3];    const char *optarg;    int fixed_args;    char *pid;    apr_getopt_t *opt;    int running_as_service = 1;    int errout = 0;    pconf = process->pconf;    osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);    GetVersionEx(&osver);    /* AP_PARENT_PID is only valid in the child */    pid = getenv("AP_PARENT_PID");    if (pid)     {        HANDLE filehand;        HANDLE hproc = GetCurrentProcess();        /* This is the child */        my_pid = GetCurrentProcessId();        parent_pid = (DWORD) atol(pid);        /* Prevent holding open the (nonexistant) console */        real_exit_code = 0;        /* The parent gave us stdin, we need to remember this         * handle, and no longer inherit it at our children         * (we can't slurp it up now, we just aren't ready yet).         * The original handle is closed below, at apr_file_dup2()         */        pipe = GetStdHandle(STD_INPUT_HANDLE);        if (DuplicateHandle(hproc, pipe,                            hproc, &filehand, 0, FALSE,                            DUPLICATE_SAME_ACCESS)) {            pipe = filehand;        }        /* The parent gave us stdout of the NUL device,         * and expects us to suck up stdin of all of our         * shared handles and data from the parent.         * Don't infect child processes with our stdin         * handle, use another handle to NUL!         */        {            apr_file_t *infile, *outfile;            if ((apr_file_open_stdout(&outfile, process->pool) == APR_SUCCESS)             && (apr_file_open_stdin(&infile, process->pool) == APR_SUCCESS))                apr_file_dup2(infile, outfile, process->pool);        }        /* This child needs the existing stderr opened for logging,         * already          */        /* The parent is responsible for providing the         * COMPLETE ARGUMENTS REQUIRED to the child.         *         * No further argument parsing is needed, but         * for good measure we will provide a simple         * signal string for later testing.         */        signal_arg = "runchild";        return;    }        /* This is the parent, we have a long way to go :-) */    parent_pid = my_pid = GetCurrentProcessId();    /* This behavior is voided by setting real_exit_code to 0 */    atexit(hold_console_open_on_error);    /* Rewrite process->argv[];      *     * strip out -k signal into signal_arg     * strip out -n servicename and set the names     * add default -d serverroot from the path of this executable     *      * The end result will look like:     *     * The invocation command (%0)     *     The -d serverroot default from the running executable     *         The requested service's (-n) registry ConfigArgs     *             The WinNT SCM's StartService() args     */    if ((rv = ap_os_proc_filepath(&binpath, process->pconf))            != APR_SUCCESS) {        ap_log_error(APLOG_MARK,APLOG_CRIT, rv, NULL,                      "Failed to get the full path of %s", process->argv[0]);        exit(APEXIT_INIT);    }    /* WARNING: There is an implict assumption here that the     * executable resides in ServerRoot or ServerRoot\bin     */    def_server_root = (char *) apr_filename_of_pathname(binpath);    if (def_server_root > binpath) {        *(def_server_root - 1) = '\0';        def_server_root = (char *) apr_filename_of_pathname(binpath);        if (!strcasecmp(def_server_root, "bin"))            *(def_server_root - 1) = '\0';    }    apr_filepath_merge(&def_server_root, NULL, binpath,                        APR_FILEPATH_TRUENAME, process->pool);    /* Use process->pool so that the rewritten argv     * lasts for the lifetime of the server process,     * because pconf will be destroyed after the      * initial pre-flight of the config parser.     */    mpm_new_argv = apr_array_make(process->pool, process->argc + 2,                                  sizeof(const char *));    *(const char **)apr_array_push(mpm_new_argv) = process->argv[0];    *(const char **)apr_array_push(mpm_new_argv) = "-d";    *(const char **)apr_array_push(mpm_new_argv) = def_server_root;    fixed_args = mpm_new_argv->nelts;    optbuf[0] = '-';    optbuf[2] = '\0';    apr_getopt_init(&opt, process->pool, process->argc, (char**) process->argv);    opt->errfn = NULL;    while ((rv = apr_getopt(opt, "wn:k:" AP_SERVER_BASEARGS,                             optbuf + 1, &optarg)) == APR_SUCCESS) {        switch (optbuf[1]) {        /* Shortcuts; include the -w option to hold the window open on error.         * This must not be toggled once we reset real_exit_code to 0!         */        case 'w':            if (real_exit_code)                real_exit_code = 2;            break;        case 'n':            service_set = mpm_service_set_name(process->pool, &service_name,                                                optarg);            break;        case 'k':            signal_arg = optarg;            break;        case 'E':            errout = 1;            /* Fall through so the Apache main() handles the 'E' arg */        default:            *(const char **)apr_array_push(mpm_new_argv) =                apr_pstrdup(process->pool, optbuf);            if (optarg) {                *(const char **)apr_array_push(mpm_new_argv) = optarg;            }            break;        }    }        /* back up to capture the bad argument */    if (rv == APR_BADCH || rv == APR_BADARG) {        opt->ind--;    }    while (opt->ind < opt->argc) {        *(const char **)apr_array_push(mpm_new_argv) =            apr_pstrdup(process->pool, opt->argv[opt->ind++]);    }    /* Track the number of args actually entered by the user */    inst_argc = mpm_new_argv->nelts - fixed_args;    /* Provide a default 'run' -k arg to simplify signal_arg tests */    if (!signal_arg)    {        signal_arg = "run";        running_as_service = 0;    }    if (!strcasecmp(signal_arg, "runservice"))     {        /* Start the NT Service _NOW_ because the WinNT SCM is          * expecting us to rapidly assume control of our own          * process, the SCM will tell us our service name, and         * may have extra StartService() command arguments to         * add for us.         *         * The SCM will generally invoke the executable with         * the c:\win\system32 default directory.  This is very         * lethal if folks use ServerRoot /foopath on windows         * without a drive letter.  Change to the default root         * (path to apache root, above /bin) for safety.         */        apr_filepath_set(def_server_root, process->pool);                /* Any other process has a console, so we don't to begin         * a Win9x service until the configuration is parsed and         * any command line errors are reported.         *         * We hold the return value so that we can die in pre_config         * after logging begins, and the failure can land in the log.         */        if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)         {            apr_file_t *nullfile;            if (!errout) {                mpm_nt_eventlog_stderr_open(service_name, process->pool);            }            service_to_start_success = mpm_service_to_start(&service_name,                                                            process->pool);            if (service_to_start_success == APR_SUCCESS) {                service_set = APR_SUCCESS;            }            /* Open a null handle to soak stdout in this process.             * Windows service processes are missing any file handle             * usable for stdin/out/err.  This was the cause of later              * trouble with invocations of apr_file_open_stdout()             */            if ((rv = apr_file_open(&nullfile, "NUL",                                    APR_READ | APR_WRITE, APR_OS_DEFAULT,                                    process->pool)) == APR_SUCCESS) {                apr_file_t *nullstdout;                if (apr_file_open_stdout(&nullstdout, process->pool)                        == APR_SUCCESS)                    apr_file_dup2(nullstdout, nullfile, process->pool);                apr_file_close(nullfile);            }        }    }    /* Get the default for any -k option, except run */    if (service_set == SERVICE_UNSET && strcasecmp(signal_arg, "run")) {        service_set = mpm_service_set_name(process->pool, &service_name,                                           AP_DEFAULT_SERVICE_NAME);    }    if (!strcasecmp(signal_arg, "install")) /* -k install */    {        if (service_set == APR_SUCCESS)         {            ap_log_error(APLOG_MARK,APLOG_ERR, 0, NULL,                 "%s: Service is already installed.", service_name);            exit(APEXIT_INIT);        }    }    else if (running_as_service)    {        if (service_set == APR_SUCCESS)         {            /* Attempt to Uninstall, or stop, before              * we can read the arguments or .conf files             */            if (!strcasecmp(signal_arg, "uninstall")) {                rv = mpm_service_uninstall();                exit(rv);            }            if ((!strcasecmp(signal_arg, "stop")) ||                 (!strcasecmp(signal_arg, "shutdown"))) {                mpm_signal_service(process->pool, 0);                exit(0);            }            rv = mpm_merge_service_args(process->pool, mpm_new_argv,                                         fixed_args);            if (rv == APR_SUCCESS) {                ap_log_error(APLOG_MARK,APLOG_INFO, 0, NULL,                             "Using ConfigArgs of the installed service "                             "\"%s\".", service_name);            }            else  {                ap_log_error(APLOG_MARK,APLOG_WARNING, rv, NULL,                             "No installed ConfigArgs for the service "                             "\"%s\", using Apache defaults.", service_name);            }        }        else        {            ap_log_error(APLOG_MARK,APLOG_ERR, service_set, NULL,                 "No installed service named \"%s\".", service_name);            exit(APEXIT_INIT);        }    }    if (strcasecmp(signal_arg, "install") && service_set && service_set != SERVICE_UNSET)     {        ap_log_error(APLOG_MARK,APLOG_ERR, service_set, NULL,             "No installed service named \"%s\".", service_name);        exit(APEXIT_INIT);    }        /* Track the args actually entered by the user.     * These will be used for the -k install parameters, as well as     * for the -k start service override arguments.     */    inst_argv = (const char * const *)mpm_new_argv->elts        + mpm_new_argv->nelts - inst_argc;    process->argc = mpm_new_argv->nelts;     process->argv = (const char * const *) mpm_new_argv->elts;}static int winnt_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *ptemp) {    /* Handle the following SCM aspects in this phase:     *     *   -k runservice [WinNT errors logged from rewrite_args]     */    /* Initialize shared static objects.      */    pconf = pconf_;    if (ap_exists_config_define("ONE_PROCESS") ||        ap_exists_config_define("DEBUG"))        one_process = -1;    if (!strcasecmp(signal_arg, "runservice")            && (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)            && (service_to_start_success != APR_SUCCESS)) {        ap_log_error(APLOG_MARK,APLOG_CRIT, service_to_start_success, NULL,                      "%s: Unable to start the service manager.",

⌨️ 快捷键说明

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