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

📄 mpm_common.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
     * keep trying because maybe we'll never successfully     * write again...  but then maybe we'll leave would-be     * readers stranded (a number of them could be tied up for     * a while serving time-consuming requests)     */    for (i = 0; i < num && rv == APR_SUCCESS; i++) {        rv = dummy_connection(pod);    }}#endif /* #ifdef AP_MPM_USES_POD *//* standard mpm configuration handling */#ifdef AP_MPM_WANT_SET_PIDFILEconst char *ap_pid_fname = NULL;const char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy,                               const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    if (cmd->server->is_virtual) {        return "PidFile directive not allowed in <VirtualHost>";    }    ap_pid_fname = arg;    return NULL;}#endif#ifdef AP_MPM_WANT_SET_SCOREBOARDconst char * ap_mpm_set_scoreboard(cmd_parms *cmd, void *dummy,                                   const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    ap_scoreboard_fname = arg;    return NULL;}#endif#ifdef AP_MPM_WANT_SET_LOCKFILEconst char *ap_lock_fname = NULL;const char *ap_mpm_set_lockfile(cmd_parms *cmd, void *dummy,                                const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    ap_lock_fname = arg;    return NULL;}#endif#ifdef AP_MPM_WANT_SET_MAX_REQUESTSint ap_max_requests_per_child = 0;const char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy,                                    const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    ap_max_requests_per_child = atoi(arg);    return NULL;}#endif#ifdef AP_MPM_WANT_SET_COREDUMPDIRchar ap_coredump_dir[MAX_STRING_LEN];int ap_coredumpdir_configured;const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy,                                   const char *arg){    apr_status_t rv;    apr_finfo_t finfo;    const char *fname;    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    fname = ap_server_root_relative(cmd->pool, arg);    if (!fname) {        return apr_pstrcat(cmd->pool, "Invalid CoreDumpDirectory path ",                            arg, NULL);    }    if ((rv = apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool)) != APR_SUCCESS) {        return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname,                           " does not exist", NULL);    }    if (finfo.filetype != APR_DIR) {        return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname,                           " is not a directory", NULL);    }    apr_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir));    ap_coredumpdir_configured = 1;    return NULL;}#endif#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECHapr_lockmech_e ap_accept_lock_mech = APR_LOCK_DEFAULT;const char ap_valid_accept_mutex_string[] =    "Valid accept mutexes for this platform and MPM are: default"#if APR_HAS_FLOCK_SERIALIZE    ", flock"#endif#if APR_HAS_FCNTL_SERIALIZE    ", fcntl"#endif#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)    ", sysvsem"#endif#if APR_HAS_POSIXSEM_SERIALIZE    ", posixsem"#endif#if APR_HAS_PROC_PTHREAD_SERIALIZE    ", pthread"#endif    ".";AP_DECLARE(const char *) ap_mpm_set_accept_lock_mech(cmd_parms *cmd,                                                     void *dummy,                                                     const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    if (!strcasecmp(arg, "default")) {        ap_accept_lock_mech = APR_LOCK_DEFAULT;    }#if APR_HAS_FLOCK_SERIALIZE    else if (!strcasecmp(arg, "flock")) {        ap_accept_lock_mech = APR_LOCK_FLOCK;    }#endif#if APR_HAS_FCNTL_SERIALIZE    else if (!strcasecmp(arg, "fcntl")) {        ap_accept_lock_mech = APR_LOCK_FCNTL;    }#endif    /* perchild can't use SysV sems because the permissions on the accept     * mutex can't be set to allow all processes to use the mutex and     * at the same time keep all users from being able to dink with the     * mutex     */#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)    else if (!strcasecmp(arg, "sysvsem")) {        ap_accept_lock_mech = APR_LOCK_SYSVSEM;    }#endif#if APR_HAS_POSIXSEM_SERIALIZE    else if (!strcasecmp(arg, "posixsem")) {        ap_accept_lock_mech = APR_LOCK_POSIXSEM;    }#endif#if APR_HAS_PROC_PTHREAD_SERIALIZE    else if (!strcasecmp(arg, "pthread")) {        ap_accept_lock_mech = APR_LOCK_PROC_PTHREAD;    }#endif    else {        return apr_pstrcat(cmd->pool, arg, " is an invalid mutex mechanism; ",                           ap_valid_accept_mutex_string, NULL);    }    return NULL;}#endif#ifdef AP_MPM_WANT_SIGNAL_SERVERstatic const char *dash_k_arg;static int send_signal(pid_t pid, int sig){    if (kill(pid, sig) < 0) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, errno, NULL,                     "sending signal to server");        return 1;    }    return 0;}int ap_signal_server(int *exit_status, apr_pool_t *pconf){    apr_status_t rv;    pid_t otherpid;    int running = 0;    int have_pid_file = 0;    const char *status;        *exit_status = 0;    rv = ap_read_pid(pconf, ap_pid_fname, &otherpid);    if (rv != APR_SUCCESS) {        if (rv != APR_ENOENT) {            ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, NULL,                         "Error retrieving pid file %s", ap_pid_fname);            *exit_status = 1;            return 1;        }        status = "httpd (no pid file) not running";    }    else {        have_pid_file = 1;        if (kill(otherpid, 0) == 0) {            running = 1;            status = apr_psprintf(pconf,                                   "httpd (pid %" APR_PID_T_FMT ") already "                                  "running", otherpid);        }        else {            status = apr_psprintf(pconf,                                  "httpd (pid %" APR_PID_T_FMT "?) not running",                                  otherpid);        }    }    if (!strcmp(dash_k_arg, "start")) {        if (running) {            printf("%s\n", status);            return 1;        }    }    if (!strcmp(dash_k_arg, "stop")) {        if (!running) {            printf("%s\n", status);        }        else {            send_signal(otherpid, SIGTERM);        }        return 1;    }    if (!strcmp(dash_k_arg, "restart")) {        if (!running) {            printf("httpd not running, trying to start\n");        }        else {            *exit_status = send_signal(otherpid, SIGHUP);            return 1;        }    }    if (!strcmp(dash_k_arg, "graceful")) {        if (!running) {            printf("httpd not running, trying to start\n");        }        else {            *exit_status = send_signal(otherpid, SIGUSR1);            return 1;        }    }    return 0;}void ap_mpm_rewrite_args(process_rec *process){    apr_array_header_t *mpm_new_argv;    apr_status_t rv;    apr_getopt_t *opt;    char optbuf[3];    const char *optarg;    int fixed_args;    mpm_new_argv = apr_array_make(process->pool, process->argc,                                  sizeof(const char **));    *(const char **)apr_array_push(mpm_new_argv) = process->argv[0];    fixed_args = mpm_new_argv->nelts;    apr_getopt_init(&opt, process->pool, process->argc, process->argv);    opt->errfn = NULL;    optbuf[0] = '-';    /* option char returned by apr_getopt() will be stored in optbuf[1] */    optbuf[2] = '\0';    while ((rv = apr_getopt(opt, "k:" AP_SERVER_BASEARGS,                            optbuf + 1, &optarg)) == APR_SUCCESS) {        switch(optbuf[1]) {        case 'k':            if (!dash_k_arg) {                if (!strcmp(optarg, "start") || !strcmp(optarg, "stop") ||                    !strcmp(optarg, "restart") || !strcmp(optarg, "graceful")) {                    dash_k_arg = optarg;                    break;                }            }        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;            }        }    }    /* 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++]);    }    process->argc = mpm_new_argv->nelts;    process->argv = (const char * const *)mpm_new_argv->elts;    if (dash_k_arg) {        APR_REGISTER_OPTIONAL_FN(ap_signal_server);    }}#endif /* AP_MPM_WANT_SIGNAL_SERVER */#ifdef AP_MPM_WANT_SET_MAX_MEM_FREEapr_uint32_t ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy,	                            const char *arg){    long value;    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }        value = strtol(arg, NULL, 0);    if (value < 0 || errno == ERANGE)        return apr_pstrcat(cmd->pool, "Invalid MaxMemFree value: ",                            arg, NULL);    ap_max_mem_free = (apr_uint32_t)value * 1024;    return NULL;}#endif /* AP_MPM_WANT_SET_MAX_MEM_FREE */#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLERstatic pid_t parent_pid, my_pid;apr_pool_t *pconf;#if AP_ENABLE_EXCEPTION_HOOKstatic int exception_hook_enabled;const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy,                                      const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    if (cmd->server->is_virtual) {	return "EnableExceptionHook directive not allowed in <VirtualHost>";    }    if (strcasecmp(arg, "on") == 0) {        exception_hook_enabled = 1;    }    else if (strcasecmp(arg, "off") == 0) {        exception_hook_enabled = 0;    }    else {        return "parameter must be 'on' or 'off'";    }    return NULL;}APR_HOOK_STRUCT(    APR_HOOK_LINK(fatal_exception))AP_IMPLEMENT_HOOK_RUN_ALL(int, fatal_exception,                          (ap_exception_info_t *ei), (ei), OK, DECLINED)static void run_fatal_exception_hook(int sig){    ap_exception_info_t ei = {0};    if (exception_hook_enabled &&        geteuid() != 0 &&         my_pid != parent_pid) {        ei.sig = sig;        ei.pid = my_pid;        ap_run_fatal_exception(&ei);    }}#endif /* AP_ENABLE_EXCEPTION_HOOK *//* handle all varieties of core dumping signals */static void sig_coredump(int sig){    apr_filepath_set(ap_coredump_dir, pconf);    apr_signal(sig, SIG_DFL);#if AP_ENABLE_EXCEPTION_HOOK    run_fatal_exception_hook(sig);#endif    /* linuxthreads issue calling getpid() here:     *   This comparison won't match if the crashing thread is     *   some module's thread that runs in the parent process.     *   The fallout, which is limited to linuxthreads:     *   The special log message won't be written when such a     *   thread in the parent causes the parent to crash.     */    if (getpid() == parent_pid) {        ap_log_error(APLOG_MARK, APLOG_NOTICE,                     0, ap_server_conf,                     "seg fault or similar nasty error detected "                     "in the parent process");        /* XXX we can probably add some rudimentary cleanup code here,         * like getting rid of the pid file.  If any additional bad stuff         * happens, we are protected from recursive errors taking down the         * system since this function is no longer the signal handler   GLA         */    }    kill(getpid(), sig);    /* At this point we've got sig blocked, because we're still inside     * the signal handler.  When we leave the signal handler it will     * be unblocked, and we'll take the signal... and coredump or whatever     * is appropriate for this particular Unix.  In addition the parent     * will see the real signal we received -- whereas if we called     * abort() here, the parent would only see SIGABRT.     */}apr_status_t ap_fatal_signal_child_setup(server_rec *s){    my_pid = getpid();    return APR_SUCCESS;}apr_status_t ap_fatal_signal_setup(server_rec *s, apr_pool_t *in_pconf){#ifndef NO_USE_SIGACTION    struct sigaction sa;    sigemptyset(&sa.sa_mask);    #if defined(SA_ONESHOT)    sa.sa_flags = SA_ONESHOT;#elif defined(SA_RESETHAND)    sa.sa_flags = SA_RESETHAND;#else    sa.sa_flags = 0;#endif    sa.sa_handler = sig_coredump;    if (sigaction(SIGSEGV, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGSEGV)");#ifdef SIGBUS    if (sigaction(SIGBUS, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGBUS)");#endif#ifdef SIGABORT    if (sigaction(SIGABORT, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABORT)");#endif#ifdef SIGABRT    if (sigaction(SIGABRT, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABRT)");#endif#ifdef SIGILL    if (sigaction(SIGILL, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGILL)");#endif#else /* NO_USE_SIGACTION */        apr_signal(SIGSEGV, sig_coredump);#ifdef SIGBUS    apr_signal(SIGBUS, sig_coredump);#endif /* SIGBUS */#ifdef SIGABORT    apr_signal(SIGABORT, sig_coredump);#endif /* SIGABORT */#ifdef SIGABRT    apr_signal(SIGABRT, sig_coredump);#endif /* SIGABRT */#ifdef SIGILL    apr_signal(SIGILL, sig_coredump);#endif /* SIGILL */#endif /* NO_USE_SIGACTION */    pconf = in_pconf;    parent_pid = my_pid = getpid();    return APR_SUCCESS;}#endif /* AP_MPM_WANT_FATAL_SIGNAL_HANDLER */

⌨️ 快捷键说明

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