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

📄 proc.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 3 页
字号:
APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,                                                       apr_child_errfn_t *errfn){    attr->errfn = errfn;    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,                                                       apr_int32_t chk){    attr->errchk = chk;    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_procattr_addrspace_set(apr_procattr_t *attr,                                                       apr_int32_t addrspace){    /* won't ever be used on this platform, so don't save the flag */    return APR_SUCCESS;}#if APR_HAS_UNICODE_FS && !defined(_WIN32_WCE)/* Used only for the NT code path, a critical section is the fastest * implementation available. */static CRITICAL_SECTION proc_lock;static apr_status_t threadproc_global_cleanup(void *ignored){    DeleteCriticalSection(&proc_lock);    return APR_SUCCESS;}/* Called from apr_initialize, we need a critical section to handle * the pipe inheritance on win32.  This will mutex any process create * so as we change our inherited pipes, we prevent another process from * also inheriting those alternate handles, and prevent the other process * from failing to inherit our standard handles. */apr_status_t apr_threadproc_init(apr_pool_t *pool){    IF_WIN_OS_IS_UNICODE    {        InitializeCriticalSection(&proc_lock);        /* register the cleanup */        apr_pool_cleanup_register(pool, &proc_lock,                                  threadproc_global_cleanup,                                  apr_pool_cleanup_null);    }    return APR_SUCCESS;}#else /* !APR_HAS_UNICODE_FS || defined(_WIN32_WCE) */apr_status_t apr_threadproc_init(apr_pool_t *pool){    return APR_SUCCESS;}#endifAPR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,                                          const char *progname,                                          const char * const *args,                                          const char * const *env,                                          apr_procattr_t *attr,                                          apr_pool_t *pool){    apr_status_t rv;    apr_size_t i;    const char *argv0;    char *cmdline;    char *pEnvBlock;    PROCESS_INFORMATION pi;    DWORD dwCreationFlags = 0;    new->in = attr->parent_in;    new->out = attr->parent_out;    new->err = attr->parent_err;    if (attr->detached) {        /* If we are creating ourselves detached, Then we should hide the         * window we are starting in.  And we had better redfine our         * handles for STDIN, STDOUT, and STDERR. Do not set the         * detached attribute for Win9x. We have found that Win9x does         * not manage the stdio handles properly when running old 16         * bit executables if the detached attribute is set.         */        if (apr_os_level >= APR_WIN_NT) {            /*              * XXX DETACHED_PROCESS won't on Win9x at all; on NT/W2K              * 16 bit executables fail (MS KB: Q150956)             */            dwCreationFlags |= DETACHED_PROCESS;        }    }    /* progname must be unquoted, in native format, as there are all sorts      * of bugs in the NT library loader code that fault when parsing '/'.     * XXX progname must be NULL if this is a 16 bit app running in WOW     */    if (progname[0] == '\"') {        progname = apr_pstrndup(pool, progname + 1, strlen(progname) - 2);    }    if (attr->cmdtype == APR_PROGRAM || attr->cmdtype == APR_PROGRAM_ENV) {        char *fullpath = NULL;        if ((rv = apr_filepath_merge(&fullpath, attr->currdir, progname,                                      APR_FILEPATH_NATIVE, pool)) != APR_SUCCESS) {            if (attr->errfn) {                attr->errfn(pool, rv,                             apr_pstrcat(pool, "filepath_merge failed.",                                         " currdir: ", attr->currdir,                                         " progname: ", progname, NULL));            }            return rv;        }        progname = fullpath;    }     else {        /* Do not fail if the path isn't parseable for APR_PROGRAM_PATH         * or APR_SHELLCMD.  We only invoke apr_filepath_merge (with no         * left hand side expression) in order to correct the path slash         * delimiters.  But the filename doesn't need to be in the CWD,         * nor does it need to be a filename at all (it could be a         * built-in shell command.)         */        char *fullpath = NULL;        if ((rv = apr_filepath_merge(&fullpath, "", progname,                                      APR_FILEPATH_NATIVE, pool)) == APR_SUCCESS) {            progname = fullpath;        }            }    if (has_space(progname)) {        argv0 = apr_pstrcat(pool, "\"", progname, "\"", NULL);    }    else {        argv0 = progname;    }    /* Handle the args, seperate from argv0 */    cmdline = "";    for (i = 1; args && args[i]; ++i) {        if (has_space(args[i]) || !args[i][0]) {            cmdline = apr_pstrcat(pool, cmdline, " \"", args[i], "\"", NULL);        }        else {            cmdline = apr_pstrcat(pool, cmdline, " ", args[i], NULL);        }    }#ifndef _WIN32_WCE    if (attr->cmdtype == APR_SHELLCMD || attr->cmdtype == APR_SHELLCMD_ENV) {        char *shellcmd = getenv("COMSPEC");        if (!shellcmd) {            if (attr->errfn) {                attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");            }            return APR_EINVAL;        }        if (shellcmd[0] == '"') {            progname = apr_pstrndup(pool, shellcmd + 1, strlen(shellcmd) - 2);        }        else {            progname = shellcmd;            if (has_space(shellcmd)) {                shellcmd = apr_pstrcat(pool, "\"", shellcmd, "\"", NULL);            }        }        /* Command.com does not support a quoted command, while cmd.exe demands one.         */        i = strlen(progname);        if (i >= 11 && strcasecmp(progname + i - 11, "command.com") == 0) {            cmdline = apr_pstrcat(pool, shellcmd, " /C ", argv0, cmdline, NULL);        }        else {            cmdline = apr_pstrcat(pool, shellcmd, " /C \"", argv0, cmdline, "\"", NULL);        }    }     else #endif    {#if defined(_WIN32_WCE)        {#else        /* Win32 is _different_ than unix.  While unix will find the given         * program since it's already chdir'ed, Win32 cannot since the parent         * attempts to open the program with it's own path.         * ###: This solution isn't much better - it may defeat path searching         * when the path search was desired.  Open to further discussion.         */        i = strlen(progname);        if (i >= 4 && (strcasecmp(progname + i - 4, ".bat") == 0                    || strcasecmp(progname + i - 4, ".cmd") == 0))        {            char *shellcmd = getenv("COMSPEC");            if (!shellcmd) {                if (attr->errfn) {                    attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");                }                return APR_EINVAL;            }            if (shellcmd[0] == '"') {                progname = apr_pstrndup(pool, shellcmd + 1, strlen(shellcmd) - 2);            }            else {                progname = shellcmd;                if (has_space(shellcmd)) {                    shellcmd = apr_pstrcat(pool, "\"", shellcmd, "\"", NULL);                }            }            i = strlen(progname);            if (i >= 11 && strcasecmp(progname + i - 11, "command.com") == 0) {                /* XXX: Still insecure - need doubled-quotes on each individual                 * arg of cmdline.  Suspect we need to postpone cmdline parsing                 * until this moment in all four code paths, with some flags                 * to toggle 'which flavor' is needed.                 */                cmdline = apr_pstrcat(pool, shellcmd, " /C ", argv0, cmdline, NULL);            }            else {                /* We must protect the cmdline args from any interpolation - this                 * is not a shellcmd, and the source of argv[] is untrusted.                 * Notice we escape ALL the cmdline args, including the quotes                 * around the individual args themselves.  No sense in allowing                 * the shift-state to be toggled, and the application will                  * not see the caret escapes.                 */                cmdline = apr_caret_escape_args(pool, cmdline);                /*                 * Our app name must always be quoted so the quotes surrounding                 * the entire /c "command args" are unambigious.                 */                if (*argv0 != '"') {                    cmdline = apr_pstrcat(pool, shellcmd, " /C \"\"", argv0, "\"", cmdline, "\"", NULL);                }                else {                    cmdline = apr_pstrcat(pool, shellcmd, " /C \"", argv0, cmdline, "\"", NULL);                }            }        }        else {#endif            /* A simple command we are directly invoking.  Do not pass             * the first arg to CreateProc() for APR_PROGRAM_PATH             * invocation, since it would need to be a literal and             * complete file path.  That is; "c:\bin\aprtest.exe"             * would succeed, but "c:\bin\aprtest" or "aprtest.exe"             * can fail.             */            cmdline = apr_pstrcat(pool, argv0, cmdline, NULL);            if (attr->cmdtype == APR_PROGRAM_PATH) {                progname = NULL;            }        }    }    if (!env || attr->cmdtype == APR_PROGRAM_ENV ||        attr->cmdtype == APR_SHELLCMD_ENV) {        pEnvBlock = NULL;    }    else {        apr_size_t iEnvBlockLen;        /*         * Win32's CreateProcess call requires that the environment         * be passed in an environment block, a null terminated block of         * null terminated strings.         */          i = 0;        iEnvBlockLen = 1;        while (env[i]) {            iEnvBlockLen += strlen(env[i]) + 1;            i++;        }        if (!i)             ++iEnvBlockLen;#if APR_HAS_UNICODE_FS        IF_WIN_OS_IS_UNICODE        {            apr_wchar_t *pNext;            pEnvBlock = (char *)apr_palloc(pool, iEnvBlockLen * 2);            dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;            i = 0;            pNext = (apr_wchar_t*)pEnvBlock;            while (env[i]) {                apr_size_t in = strlen(env[i]) + 1;                if ((rv = apr_conv_utf8_to_ucs2(env[i], &in,                                                 pNext, &iEnvBlockLen))                         != APR_SUCCESS) {                    if (attr->errfn) {                        attr->errfn(pool, rv,                                     apr_pstrcat(pool,                                                 "utf8 to ucs2 conversion failed"                                                 " on this string: ", env[i], NULL));                    }                    return rv;                }                pNext = wcschr(pNext, L'\0') + 1;                i++;            }	    if (!i)                *(pNext++) = L'\0';	    *pNext = L'\0';        }#endif /* APR_HAS_UNICODE_FS */#if APR_HAS_ANSI_FS        ELSE_WIN_OS_IS_ANSI        {            char *pNext;            pEnvBlock = (char *)apr_palloc(pool, iEnvBlockLen);                i = 0;            pNext = pEnvBlock;            while (env[i]) {                strcpy(pNext, env[i]);                pNext = strchr(pNext, '\0') + 1;                i++;            }	    if (!i)                *(pNext++) = '\0';	    *pNext = '\0';        }#endif /* APR_HAS_ANSI_FS */    }     new->invoked = cmdline;#if APR_HAS_UNICODE_FS    IF_WIN_OS_IS_UNICODE    {        STARTUPINFOW si;        DWORD stdin_reset = 0;        DWORD stdout_reset = 0;        DWORD stderr_reset = 0;        apr_wchar_t *wprg = NULL;        apr_wchar_t *wcmd = NULL;        apr_wchar_t *wcwd = NULL;        if (progname) {            apr_size_t nprg = strlen(progname) + 1;            apr_size_t nwprg = nprg + 6;            wprg = apr_palloc(pool, nwprg * sizeof(wprg[0]));            if ((rv = apr_conv_utf8_to_ucs2(progname, &nprg, wprg, &nwprg))                   != APR_SUCCESS) {                if (attr->errfn) {                    attr->errfn(pool, rv,                                 apr_pstrcat(pool,                                             "utf8 to ucs2 conversion failed"                                             " on progname: ", progname, NULL));                }                return rv;            }        }        if (cmdline) {            apr_size_t ncmd = strlen(cmdline) + 1;            apr_size_t nwcmd = ncmd;            wcmd = apr_palloc(pool, nwcmd * sizeof(wcmd[0]));            if ((rv = apr_conv_utf8_to_ucs2(cmdline, &ncmd, wcmd, &nwcmd))                    != APR_SUCCESS) {                if (attr->errfn) {                    attr->errfn(pool, rv,                                 apr_pstrcat(pool,                                             "utf8 to ucs2 conversion failed"                                             " on cmdline: ", cmdline, NULL));                }                return rv;            }        }        if (attr->currdir)        {            apr_size_t ncwd = strlen(attr->currdir) + 1;            apr_size_t nwcwd = ncwd;            wcwd = apr_palloc(pool, ncwd * sizeof(wcwd[0]));            if ((rv = apr_conv_utf8_to_ucs2(attr->currdir, &ncwd,                                             wcwd, &nwcwd))                    != APR_SUCCESS) {

⌨️ 快捷键说明

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