📄 proc.c
字号:
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 (attr->child_in && attr->child_in->filehand) { if (GetHandleInformation(si.hStdInput, &stdin_reset) && (stdin_reset &= HANDLE_FLAG_INHERIT)) SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, 0); if ( (si.hStdInput = attr->child_in->filehand) != INVALID_HANDLE_VALUE ) SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); } si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); if (attr->child_out && attr->child_out->filehand) { if (GetHandleInformation(si.hStdOutput, &stdout_reset) && (stdout_reset &= HANDLE_FLAG_INHERIT)) SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, 0); if ( (si.hStdOutput = attr->child_out->filehand) != INVALID_HANDLE_VALUE ) SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); } si.hStdError = GetStdHandle(STD_ERROR_HANDLE); if (attr->child_err && attr->child_err->filehand) { if (GetHandleInformation(si.hStdError, &stderr_reset) && (stderr_reset &= HANDLE_FLAG_INHERIT)) SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, 0); if ( (si.hStdError = attr->child_err->filehand) != INVALID_HANDLE_VALUE ) SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); } } if (attr->user_token) { /* XXX: for terminal services, handles can't be cannot be * inherited across sessions. This process must be created * in our existing session. lpDesktop assignment appears * to be wrong according to these rules. */ si.lpDesktop = L"Winsta0\\Default"; if (!ImpersonateLoggedOnUser(attr->user_token)) { /* failed to impersonate the logged user */ rv = apr_get_os_error(); CloseHandle(attr->user_token); attr->user_token = NULL; return rv; } rv = CreateProcessAsUserW(attr->user_token, wprg, wcmd, attr->sa, NULL, TRUE, dwCreationFlags, pEnvBlock, wcwd, &si, &pi); RevertToSelf(); } else { 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) && (attr->child_in != &no_file)) { apr_file_close(attr->child_in); } if ((attr->child_out) && (attr->child_out != &no_file)) { apr_file_close(attr->child_out); } if ((attr->child_err) && (attr->child_err != &no_file)) { apr_file_close(attr->child_err); } CloseHandle(pi.hThread); return APR_SUCCESS;}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_all_procs(apr_proc_t *proc, int *exitcode, apr_exit_why_e *exitwhy, apr_wait_how_e waithow, apr_pool_t *p){#if APR_HAS_UNICODE_FS#ifndef _WIN32_WCE IF_WIN_OS_IS_UNICODE { DWORD dwId = GetCurrentProcessId(); DWORD i; DWORD nChilds = 0; DWORD nActive = 0; HANDLE ps32; PROCESSENTRY32W pe32; BOOL bHasMore = FALSE; DWORD dwFlags = PROCESS_QUERY_INFORMATION; apr_status_t rv = APR_EGENERAL; if (waithow == APR_WAIT) dwFlags |= SYNCHRONIZE; if (!(ps32 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0))) { return apr_get_os_error(); } pe32.dwSize = sizeof(PROCESSENTRY32W); if (!Process32FirstW(ps32, &pe32)) { if (GetLastError() == ERROR_NO_MORE_FILES) return APR_EOF; else return apr_get_os_error(); } do { DWORD dwRetval = 0; DWORD nHandles = 0; HANDLE hProcess = NULL; HANDLE pHandles[MAXIMUM_WAIT_OBJECTS]; do { if (pe32.th32ParentProcessID == dwId) { nChilds++; if ((hProcess = OpenProcess(dwFlags, FALSE, pe32.th32ProcessID)) != NULL) { if (GetExitCodeProcess(hProcess, &dwRetval)) { if (dwRetval == STILL_ACTIVE) { nActive++; if (waithow == APR_WAIT) pHandles[nHandles++] = hProcess; else CloseHandle(hProcess); } else { /* Process has exited. * No need to wait for its termination. */ CloseHandle(hProcess); if (exitcode) *exitcode = dwRetval; if (exitwhy) *exitwhy = why_from_exit_code(dwRetval); proc->pid = pe32.th32ProcessID; } } else { /* Unexpected error code. * Cleanup and return; */ rv = apr_get_os_error(); CloseHandle(hProcess); for (i = 0; i < nHandles; i++) CloseHandle(pHandles[i]); return rv; } } else { /* This is our child, so it shouldn't happen * that we cannot open our child's process handle. * However if the child process increased the * security token it might fail. */ } } } while ((bHasMore = Process32NextW(ps32, &pe32)) && nHandles < MAXIMUM_WAIT_OBJECTS); if (nHandles) { /* Wait for all collected processes to finish */ DWORD waitStatus = WaitForMultipleObjects(nHandles, pHandles, TRUE, INFINITE); for (i = 0; i < nHandles; i++) CloseHandle(pHandles[i]); if (waitStatus == WAIT_OBJECT_0) { /* Decrease active count by the number of awaited * processes. */ nActive -= nHandles; } else { /* Broken from the infinite loop */ break; } } } while (bHasMore); CloseHandle(ps32); if (waithow != APR_WAIT) { if (nChilds && nChilds == nActive) { /* All child processes are running */ rv = APR_CHILD_NOTDONE; proc->pid = -1; } else { /* proc->pid contains the pid of the * exited processes */ rv = APR_CHILD_DONE; } } if (nActive == 0) { rv = APR_CHILD_DONE; proc->pid = -1; } return rv; }#endif /* _WIN32_WCE */#endif /* APR_HAS_UNICODE_FS */ return APR_ENOTIMPL;}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();}APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize){ return APR_ENOTIMPL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -