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

📄 proc.c

📁 Apache 2.0.63 is the current stable version of the 2.0 series, and is recommended over any previous
💻 C
📖 第 1 页 / 共 3 页
字号:
    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) {
                if (attr->errfn) {
                    attr->errfn(pool, rv, 
                                apr_pstrcat(pool, 
                                            "utf8 to ucs2 conversion failed" 
                                            " on currdir: ", attr->currdir, NULL));
                }
                return rv;
            }
        }

        memset(&si, 0, sizeof(si));
        si.cb = sizeof(si);

        if (attr->detached) {
            si.dwFlags |= STARTF_USESHOWWINDOW;
            si.wShowWindow = SW_HIDE;
        }

#ifndef _WIN32_WCE
        /* LOCK CRITICAL SECTION 
         * before we begin to manipulate the inherited handles
         */
        EnterCriticalSection(&proc_lock);

        if ((attr->child_in && attr->child_in->filehand)
            || (attr->child_out && attr->child_out->filehand)
            || (attr->child_err && attr->child_err->filehand))
        {
            si.dwFlags |= STARTF_USESTDHANDLES;

            si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
            if (GetHandleInformation(si.hStdInput, &stdin_reset)
                    && (stdin_reset &= HANDLE_FLAG_INHERIT))
                SetHandleInformation(si.hStdInput,
                                     HANDLE_FLAG_INHERIT, 0);

            if (attr->child_in && attr->child_in->filehand)
            {
                si.hStdInput = attr->child_in->filehand;
                SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT,
                                                   HANDLE_FLAG_INHERIT);
            }
            else
                si.hStdInput = INVALID_HANDLE_VALUE;
            
            si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
            if (GetHandleInformation(si.hStdOutput, &stdout_reset)
                    && (stdout_reset &= HANDLE_FLAG_INHERIT))
                SetHandleInformation(si.hStdOutput,
                                     HANDLE_FLAG_INHERIT, 0);

            if (attr->child_out && attr->child_out->filehand)
            {
                si.hStdOutput = attr->child_out->filehand;
                SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT,
                                                    HANDLE_FLAG_INHERIT);
            }
            else
                si.hStdOutput = INVALID_HANDLE_VALUE;

            si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
            if (GetHandleInformation(si.hStdError, &stderr_reset)
                    && (stderr_reset &= HANDLE_FLAG_INHERIT))
                SetHandleInformation(si.hStdError,
                                     HANDLE_FLAG_INHERIT, 0);

            if (attr->child_err && attr->child_err->filehand)
            {
                si.hStdError = attr->child_err->filehand;
                SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT,
                                                   HANDLE_FLAG_INHERIT);
            }
            else
                si.hStdError = INVALID_HANDLE_VALUE;
        }
        rv = CreateProcessW(wprg, wcmd,        /* Executable & Command line */
                            NULL, NULL,        /* Proc & thread security attributes */
                            TRUE,              /* Inherit handles */
                            dwCreationFlags,   /* Creation flags */
                            pEnvBlock,         /* Environment block */
                            wcwd,              /* Current directory name */
                            &si, &pi);

        if ((attr->child_in && attr->child_in->filehand)
            || (attr->child_out && attr->child_out->filehand)
            || (attr->child_err && attr->child_err->filehand))
        {
            if (stdin_reset)
                SetHandleInformation(GetStdHandle(STD_INPUT_HANDLE),
                                     stdin_reset, stdin_reset);

            if (stdout_reset)
                SetHandleInformation(GetStdHandle(STD_OUTPUT_HANDLE),
                                     stdout_reset, stdout_reset);

            if (stderr_reset)
                SetHandleInformation(GetStdHandle(STD_ERROR_HANDLE),
                                     stderr_reset, stderr_reset);
        }
        /* RELEASE CRITICAL SECTION 
         * The state of the inherited handles has been restored.
         */
        LeaveCriticalSection(&proc_lock);

#else /* defined(_WIN32_WCE) */
        rv = CreateProcessW(wprg, wcmd,        /* Executable & Command line */
                            NULL, NULL,        /* Proc & thread security attributes */
                            FALSE,             /* must be 0 */
                            dwCreationFlags,   /* Creation flags */
                            NULL,              /* Environment block must be NULL */
                            NULL,              /* Current directory name must be NULL*/
                            NULL,              /* STARTUPINFO not supported */
                            &pi);
#endif
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        STARTUPINFOA si;
        memset(&si, 0, sizeof(si));
        si.cb = sizeof(si);

        if (attr->detached) {
            si.dwFlags |= STARTF_USESHOWWINDOW;
            si.wShowWindow = SW_HIDE;
        }

        if ((attr->child_in && attr->child_in->filehand)
            || (attr->child_out && attr->child_out->filehand)
            || (attr->child_err && attr->child_err->filehand))
        {
            si.dwFlags |= STARTF_USESTDHANDLES;

            si.hStdInput = (attr->child_in) 
                              ? attr->child_in->filehand
                              : GetStdHandle(STD_INPUT_HANDLE);

            si.hStdOutput = (attr->child_out)
                              ? attr->child_out->filehand
                              : GetStdHandle(STD_OUTPUT_HANDLE);

            si.hStdError = (attr->child_err)
                              ? attr->child_err->filehand
                              : GetStdHandle(STD_ERROR_HANDLE);
        }

        rv = CreateProcessA(progname, cmdline, /* Command line */
                            NULL, NULL,        /* Proc & thread security attributes */
                            TRUE,              /* Inherit handles */
                            dwCreationFlags,   /* Creation flags */
                            pEnvBlock,         /* Environment block */
                            attr->currdir,     /* Current directory name */
                            &si, &pi);
    }
#endif /* APR_HAS_ANSI_FS */

    /* Check CreateProcess result 
     */
    if (!rv)
        return apr_get_os_error();

    /* XXX Orphaned handle warning - no fix due to broken apr_proc_t api.
     */
    new->hproc = pi.hProcess;
    new->pid = pi.dwProcessId;

    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);
    }
    CloseHandle(pi.hThread);

    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)
{
    /* Unix does apr_proc_wait(proc(-1), exitcode, exitwhy, waithow)
     * but Win32's apr_proc_wait won't work that way.  We can either
     * register all APR created processes in some sort of AsyncWait
     * thread, or simply walk from the global process pool for all 
     * apr_pool_note_subprocess()es registered with APR.
     */
    return APR_ENOTIMPL;
}

static apr_exit_why_e why_from_exit_code(DWORD exit) {
    /* See WinNT.h STATUS_ACCESS_VIOLATION and family for how
     * this class of failures was determined
     */
    if (((exit & 0xC0000000) == 0xC0000000) 
                    && !(exit & 0x3FFF0000))
        return APR_PROC_SIGNAL;
    else
        return APR_PROC_EXIT;

    /* ### No way to tell if Dr Watson grabbed a core, AFAICT. */
}

APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
                                        int *exitcode, apr_exit_why_e *exitwhy,
                                        apr_wait_how_e waithow)
{
    DWORD stat;
    DWORD time;

    if (waithow == APR_WAIT)
        time = INFINITE;
    else
        time = 0;

    if ((stat = WaitForSingleObject(proc->hproc, time)) == WAIT_OBJECT_0) {
        if (GetExitCodeProcess(proc->hproc, &stat)) {
            if (exitcode)
                *exitcode = stat;
            if (exitwhy)
                *exitwhy = why_from_exit_code(stat);
            CloseHandle(proc->hproc);
            proc->hproc = NULL;
            return APR_CHILD_DONE;
        }
    }
    else if (stat == WAIT_TIMEOUT) {
        return APR_CHILD_NOTDONE;
    }
    return apr_get_os_error();
}

⌨️ 快捷键说明

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