📄 proc.c
字号:
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 + -