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

📄 proc.c

📁 apr-1.2.7.tar.gz源码 支持svn的需求
💻 C
📖 第 1 页 / 共 2 页
字号:
    new->out = attr->parent_out;    if (attr->errchk) {        if (attr->currdir) {            if (access(attr->currdir, X_OK) == -1) {                /* chdir() in child wouldn't have worked */                return errno;            }        }        if (attr->cmdtype == APR_PROGRAM ||            attr->cmdtype == APR_PROGRAM_ENV ||            *progname == '/') {            /* for both of these values of cmdtype, caller must pass             * full path, so it is easy to check;             * caller can choose to pass full path for other             * values of cmdtype             */            if (access(progname, R_OK|X_OK) == -1) {                /* exec*() in child wouldn't have worked */                return errno;            }        }        else {            /* todo: search PATH for progname then try to access it */        }    }    if ((new->pid = fork()) < 0) {        return errno;    }    else if (new->pid == 0) {        int status;        /* child process */        /*         * If we do exec cleanup before the dup2() calls to set up pipes         * on 0-2, we accidentally close the pipes used by programs like         * mod_cgid.         *         * If we do exec cleanup after the dup2() calls, cleanup can accidentally         * close our pipes which replaced any files which previously had         * descriptors 0-2.         *         * The solution is to kill the cleanup for the pipes, then do         * exec cleanup, then do the dup2() calls.         */        if (attr->child_in) {            apr_pool_cleanup_kill(apr_file_pool_get(attr->child_in),                                  attr->child_in, apr_unix_file_cleanup);        }        if (attr->child_out) {            apr_pool_cleanup_kill(apr_file_pool_get(attr->child_out),                                  attr->child_out, apr_unix_file_cleanup);        }        if (attr->child_err) {            apr_pool_cleanup_kill(apr_file_pool_get(attr->child_err),                                  attr->child_err, apr_unix_file_cleanup);        }        apr_pool_cleanup_for_exec();        if (attr->child_in) {            apr_file_close(attr->parent_in);            dup2(attr->child_in->filedes, STDIN_FILENO);            apr_file_close(attr->child_in);        }        if (attr->child_out) {            apr_file_close(attr->parent_out);            dup2(attr->child_out->filedes, STDOUT_FILENO);            apr_file_close(attr->child_out);        }        if (attr->child_err) {            apr_file_close(attr->parent_err);            dup2(attr->child_err->filedes, STDERR_FILENO);            apr_file_close(attr->child_err);        }        apr_signal(SIGCHLD, SIG_DFL); /* not sure if this is needed or not */        if (attr->currdir != NULL) {            if (chdir(attr->currdir) == -1) {                if (attr->errfn) {                    attr->errfn(pool, errno, "change of working directory failed");                }                exit(-1);   /* We have big problems, the child should exit. */            }        }        /* Only try to switch if we are running as root */        if (attr->gid != -1 && !geteuid()) {            if ((status = setgid(attr->gid))) {                if (attr->errfn) {                    attr->errfn(pool, errno, "setting of group failed");                }                exit(-1);   /* We have big problems, the child should exit. */            }        }        if (attr->uid != -1 && !geteuid()) {            if ((status = setuid(attr->uid))) {                if (attr->errfn) {                    attr->errfn(pool, errno, "setting of user failed");                }                exit(-1);   /* We have big problems, the child should exit. */            }        }        if ((status = limit_proc(attr)) != APR_SUCCESS) {            if (attr->errfn) {                attr->errfn(pool, errno, "setting of resource limits failed");            }            exit(-1);   /* We have big problems, the child should exit. */        }        if (attr->cmdtype == APR_SHELLCMD ||            attr->cmdtype == APR_SHELLCMD_ENV) {            int onearg_len = 0;            const char *newargs[4];            newargs[0] = SHELL_PATH;            newargs[1] = "-c";            i = 0;            while (args[i]) {                onearg_len += strlen(args[i]);                onearg_len++; /* for space delimiter */                i++;            }            switch(i) {            case 0:                /* bad parameters; we're doomed */                break;            case 1:                /* no args, or caller already built a single string from                 * progname and args                 */                newargs[2] = args[0];                break;            default:            {                char *ch, *onearg;                                ch = onearg = apr_palloc(pool, onearg_len);                i = 0;                while (args[i]) {                    size_t len = strlen(args[i]);                    memcpy(ch, args[i], len);                    ch += len;                    *ch = ' ';                    ++ch;                    ++i;                }                --ch; /* back up to trailing blank */                *ch = '\0';                newargs[2] = onearg;            }            }            newargs[3] = NULL;            if (attr->detached) {                apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);            }            if (attr->cmdtype == APR_SHELLCMD) {                execve(SHELL_PATH, (char * const *) newargs, (char * const *)env);            }            else {                execv(SHELL_PATH, (char * const *)newargs);            }        }        else if (attr->cmdtype == APR_PROGRAM) {            if (attr->detached) {                apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);            }            execve(progname, (char * const *)args, (char * const *)env);        }        else if (attr->cmdtype == APR_PROGRAM_ENV) {            if (attr->detached) {                apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);            }            execv(progname, (char * const *)args);        }        else {            /* APR_PROGRAM_PATH */            if (attr->detached) {                apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);            }            execvp(progname, (char * const *)args);        }        if (attr->errfn) {            char *desc;            desc = apr_psprintf(pool, "exec of '%s' failed",                                progname);            attr->errfn(pool, errno, desc);        }        exit(-1);  /* if we get here, there is a problem, so exit with an                    * error code. */    }    /* Parent process */    if (attr->child_in) {        apr_file_close(attr->child_in);    }    if (attr->child_out) {        apr_file_close(attr->child_out);    }    if (attr->child_err) {        apr_file_close(attr->child_err);    }    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,                                                  int *exitcode,                                                  apr_exit_why_e *exitwhy,                                                  apr_wait_how_e waithow,                                                  apr_pool_t *p){    proc->pid = -1;    return apr_proc_wait(proc, exitcode, exitwhy, waithow);}APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,                                        int *exitcode, apr_exit_why_e *exitwhy,                                        apr_wait_how_e waithow){    pid_t pstatus;    int waitpid_options = WUNTRACED;    int exit_int;    int ignore;    apr_exit_why_e ignorewhy;    if (exitcode == NULL) {        exitcode = &ignore;    }    if (exitwhy == NULL) {        exitwhy = &ignorewhy;    }    if (waithow != APR_WAIT) {        waitpid_options |= WNOHANG;    }    do {        pstatus = waitpid(proc->pid, &exit_int, waitpid_options);    } while (pstatus < 0 && errno == EINTR);    if (pstatus > 0) {        proc->pid = pstatus;        if (WIFEXITED(exit_int)) {            *exitwhy = APR_PROC_EXIT;            *exitcode = WEXITSTATUS(exit_int);        }        else if (WIFSIGNALED(exit_int)) {            *exitwhy = APR_PROC_SIGNAL;#ifdef WCOREDUMP            if (WCOREDUMP(exit_int)) {                *exitwhy |= APR_PROC_SIGNAL_CORE;            }#endif            *exitcode = WTERMSIG(exit_int);        }        else {            /* unexpected condition */            return APR_EGENERAL;        }        return APR_CHILD_DONE;    }    else if (pstatus == 0) {        return APR_CHILD_NOTDONE;    }    return errno;}APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr,                                                 apr_int32_t what,                                                 struct rlimit *limit){    switch(what) {        case APR_LIMIT_CPU:#ifdef RLIMIT_CPU            attr->limit_cpu = limit;            break;#else            return APR_ENOTIMPL;#endif        case APR_LIMIT_MEM:#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)            attr->limit_mem = limit;            break;#else            return APR_ENOTIMPL;#endif        case APR_LIMIT_NPROC:#ifdef RLIMIT_NPROC            attr->limit_nproc = limit;            break;#else            return APR_ENOTIMPL;#endif        case APR_LIMIT_NOFILE:#ifdef RLIMIT_NOFILE            attr->limit_nofile = limit;            break;#else            return APR_ENOTIMPL;#endif    }    return APR_SUCCESS;}

⌨️ 快捷键说明

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