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

📄 mpm_winnt.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
        exit(APEXIT_CHILDINIT);    }    SetEvent(ready_event);    CloseHandle(ready_event);    if (!ReadFile(pipe, child_exit_event, sizeof(HANDLE),                  &BytesRead, (LPOVERLAPPED) NULL)        || (BytesRead != sizeof(HANDLE))) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Child %d: Unable to retrieve the exit event from the parent", my_pid);        exit(APEXIT_CHILDINIT);    }    if (!ReadFile(pipe, &os_start, sizeof(os_start),                  &BytesRead, (LPOVERLAPPED) NULL)        || (BytesRead != sizeof(os_start))) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Child %d: Unable to retrieve the start_mutex from the parent", my_pid);        exit(APEXIT_CHILDINIT);    }    *child_start_mutex = NULL;    if ((rv = apr_os_proc_mutex_put(child_start_mutex, &os_start, s->process->pool))            != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Child %d: Unable to access the start_mutex from the parent", my_pid);        exit(APEXIT_CHILDINIT);    }    if (!ReadFile(pipe, &hScore, sizeof(hScore),                  &BytesRead, (LPOVERLAPPED) NULL)        || (BytesRead != sizeof(hScore))) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Child %d: Unable to retrieve the scoreboard from the parent", my_pid);        exit(APEXIT_CHILDINIT);    }    *scoreboard_shm = NULL;    if ((rv = apr_os_shm_put(scoreboard_shm, &hScore, s->process->pool))             != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Child %d: Unable to access the scoreboard from the parent", my_pid);        exit(APEXIT_CHILDINIT);    }    rv = ap_reopen_scoreboard(s->process->pool, scoreboard_shm, 1);    if (rv || !(sb_shared = apr_shm_baseaddr_get(*scoreboard_shm))) {	ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,                      "Child %d: Unable to reopen the scoreboard from the parent", my_pid);        exit(APEXIT_CHILDINIT);    }    /* We must 'initialize' the scoreboard to relink all the     * process-local pointer arrays into the shared memory block.     */    ap_init_scoreboard(sb_shared);    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                 "Child %d: Retrieved our scoreboard from the parent.", my_pid);}static int send_handles_to_child(apr_pool_t *p,                                  HANDLE child_ready_event,                                 HANDLE child_exit_event,                                  apr_proc_mutex_t *child_start_mutex,                                 apr_shm_t *scoreboard_shm,                                 HANDLE hProcess,                                  apr_file_t *child_in){    apr_status_t rv;    HANDLE hCurrentProcess = GetCurrentProcess();    HANDLE hDup;    HANDLE os_start;    HANDLE hScore;    DWORD BytesWritten;    if (!DuplicateHandle(hCurrentProcess, child_ready_event, hProcess, &hDup,        EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Parent: Unable to duplicate the ready event handle for the child");        return -1;    }    if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten))            != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Unable to send the exit event handle to the child");        return -1;    }    if (!DuplicateHandle(hCurrentProcess, child_exit_event, hProcess, &hDup,                         EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Parent: Unable to duplicate the exit event handle for the child");        return -1;    }    if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten))            != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Unable to send the exit event handle to the child");        return -1;    }    if ((rv = apr_os_proc_mutex_get(&os_start, child_start_mutex)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Unable to retrieve the start mutex for the child");        return -1;    }    if (!DuplicateHandle(hCurrentProcess, os_start, hProcess, &hDup,                         SYNCHRONIZE, FALSE, 0)) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Parent: Unable to duplicate the start mutex to the child");        return -1;    }    if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten))            != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Unable to send the start mutex to the child");        return -1;    }    if ((rv = apr_os_shm_get(&hScore, scoreboard_shm)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Unable to retrieve the scoreboard handle for the child");        return -1;    }    if (!DuplicateHandle(hCurrentProcess, hScore, hProcess, &hDup,                         FILE_MAP_READ | FILE_MAP_WRITE, FALSE, 0)) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Parent: Unable to duplicate the scoreboard handle to the child");        return -1;    }    if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten))            != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Unable to send the scoreboard handle to the child");        return -1;    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                 "Parent: Sent the scoreboard to the child");    return 0;}/*  * get_listeners_from_parent() * The listen sockets are opened in the parent. This function, which runs * exclusively in the child process, receives them from the parent and * makes them availeble in the child. */void get_listeners_from_parent(server_rec *s){    WSAPROTOCOL_INFO WSAProtocolInfo;    ap_listen_rec *lr;    DWORD BytesRead;    int lcnt = 0;    SOCKET nsd;    /* Set up a default listener if necessary */    if (ap_listeners == NULL) {        ap_listen_rec *lr;        lr = apr_palloc(s->process->pool, sizeof(ap_listen_rec));        lr->sd = NULL;        lr->next = ap_listeners;        ap_listeners = lr;    }    /* Open the pipe to the parent process to receive the inherited socket     * data. The sockets have been set to listening in the parent process.     *     * *** We now do this was back in winnt_rewrite_args     * pipe = GetStdHandle(STD_INPUT_HANDLE);     */    for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) {        if (!ReadFile(pipe, &WSAProtocolInfo, sizeof(WSAPROTOCOL_INFO),                       &BytesRead, (LPOVERLAPPED) NULL)) {            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                         "setup_inherited_listeners: Unable to read socket data from parent");            exit(APEXIT_CHILDINIT);        }        nsd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,                        &WSAProtocolInfo, 0, 0);        if (nsd == INVALID_SOCKET) {            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf,                         "Child %d: setup_inherited_listeners(), WSASocket failed to open the inherited socket.", my_pid);            exit(APEXIT_CHILDINIT);        }        if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {            HANDLE hProcess = GetCurrentProcess();            HANDLE dup;            if (DuplicateHandle(hProcess, (HANDLE) nsd, hProcess, &dup,                                 0, FALSE, DUPLICATE_SAME_ACCESS)) {                closesocket(nsd);                nsd = (SOCKET) dup;            }        }        else {            /* A different approach.  Many users report errors such as              * (32538)An operation was attempted on something that is not              * a socket.  : Parent: WSADuplicateSocket failed...             *             * This appears that the duplicated handle is no longer recognized             * as a socket handle.  SetHandleInformation should overcome that             * problem by not altering the handle identifier.  But this won't             * work on 9x - it's unsupported.             */            if (!SetHandleInformation((HANDLE)nsd, HANDLE_FLAG_INHERIT, 0)) {                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), ap_server_conf,                             "set_listeners_noninheritable: SetHandleInformation failed.");            }        }        apr_os_sock_put(&lr->sd, &nsd, s->process->pool);    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                 "Child %d: retrieved %d listeners from parent", my_pid, lcnt);}static int send_listeners_to_child(apr_pool_t *p, DWORD dwProcessId,                                    apr_file_t *child_in){    apr_status_t rv;    int lcnt = 0;    ap_listen_rec *lr;    LPWSAPROTOCOL_INFO  lpWSAProtocolInfo;    DWORD BytesWritten;    /* Run the chain of open sockets. For each socket, duplicate it      * for the target process then send the WSAPROTOCOL_INFO      * (returned by dup socket) to the child.     */    for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) {        int nsd;        lpWSAProtocolInfo = apr_pcalloc(p, sizeof(WSAPROTOCOL_INFO));        apr_os_sock_get(&nsd,lr->sd);        ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf,                     "Parent: Duplicating socket %d and sending it to child process %d",                      nsd, dwProcessId);        if (WSADuplicateSocket(nsd, dwProcessId,                               lpWSAProtocolInfo) == SOCKET_ERROR) {            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf,                         "Parent: WSADuplicateSocket failed for socket %d. Check the FAQ.", lr->sd );            return -1;        }        if ((rv = apr_file_write_full(child_in, lpWSAProtocolInfo,                                       sizeof(WSAPROTOCOL_INFO), &BytesWritten))                != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                         "Parent: Unable to write duplicated socket %d to the child.", lr->sd );            return -1;        }    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                 "Parent: Sent %d listeners to child %d", lcnt, dwProcessId);    return 0;}enum waitlist_e {    waitlist_ready = 0,    waitlist_term = 1};static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_event,                           DWORD *child_pid){    /* These NEVER change for the lifetime of this parent      */    static char **args = NULL;    static char **env = NULL;    static char pidbuf[28];    apr_status_t rv;    apr_pool_t *ptemp;    apr_procattr_t *attr;    apr_proc_t new_child;    apr_file_t *child_out, *child_err;    HANDLE hExitEvent;    HANDLE waitlist[2];  /* see waitlist_e */    char *cmd;    char *cwd;    apr_pool_sub_make(&ptemp, p, NULL);    /* Build the command line. Should look something like this:     * C:/apache/bin/apache.exe -f ap_server_confname      * First, get the path to the executable...     */    apr_procattr_create(&attr, ptemp);    apr_procattr_cmdtype_set(attr, APR_PROGRAM);    apr_procattr_detach_set(attr, 1);    if (((rv = apr_filepath_get(&cwd, 0, ptemp)) != APR_SUCCESS)           || ((rv = apr_procattr_dir_set(attr, cwd)) != APR_SUCCESS)) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                     "Parent: Failed to get the current path");    }    if (!args) {        /* Build the args array, only once since it won't change          * for the lifetime of this parent process.         */        if ((rv = ap_os_proc_filepath(&cmd, ptemp))                != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_CRIT, ERROR_BAD_PATHNAME, ap_server_conf,                         "Parent: Failed to get full path of %s",                          ap_server_conf->process->argv[0]);            apr_pool_destroy(ptemp);            return -1;        }                args = malloc((ap_server_conf->process->argc + 1) * sizeof (char*));        memcpy(args + 1, ap_server_conf->process->argv + 1,                (ap_server_conf->process->argc - 1) * sizeof (char*));        args[0] = malloc(strlen(cmd) + 1);        strcpy(args[0], cmd);        args[ap_server_conf->process->argc] = NULL;    }    else {        cmd = args[0];    }    /* Create a pipe to send handles to the child */    if ((rv = apr_procattr_io_set(attr, APR_FULL_BLOCK,                                   APR_NO_PIPE, APR_NO_PIPE)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,                        "Parent: Unable to create child stdin pipe.");        apr_pool_destroy(ptemp);        return -1;    }    /* httpd-2.0/2.2 specific to work around apr_proc_create bugs */    if (((rv = apr_file_open_stdout(&child_out, p))            != APR_SUCCESS) ||        ((rv = apr_procattr_child_out_set(attr, child_out, NULL))            != APR_SUCCESS)) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,                     "Parent: Could not set child process stdout");    }    if (((rv = apr_file_open_stderr(&child_err, p))            != APR_SUCCESS) ||        ((rv = apr_procattr_child_err_set(attr, child_err, NULL))            != APR_SUCCESS)) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,                     "Parent: Could not set child process stderr");    }    /* Create the child_ready_event */    waitlist[waitlist_ready] = CreateEvent(NULL, TRUE, FALSE, NULL);    if (!waitlist[waitlist_ready]) {        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,                     "Parent: Could not create ready event for child process");        apr_pool_destroy (ptemp);

⌨️ 快捷键说明

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