diff options
author | Brad King <brad.king@kitware.com> | 2015-05-05 13:13:24 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-05-05 13:13:24 (GMT) |
commit | a874700fc2da9331140e93df4088c6a1021d3cc3 (patch) | |
tree | be90d318df3d296a0b047716c5bf14083cd4031a /Source/kwsys/ProcessWin32.c | |
parent | f6749f727451ef3e35c20e80e712f0bda38348f9 (diff) | |
parent | 71f38d060bb729e1ac6cfe8db412c0ef96b68cc7 (diff) | |
download | CMake-a874700fc2da9331140e93df4088c6a1021d3cc3.zip CMake-a874700fc2da9331140e93df4088c6a1021d3cc3.tar.gz CMake-a874700fc2da9331140e93df4088c6a1021d3cc3.tar.bz2 |
Merge branch 'upstream-kwsys' into update-kwsys
Diffstat (limited to 'Source/kwsys/ProcessWin32.c')
-rw-r--r-- | Source/kwsys/ProcessWin32.c | 559 |
1 files changed, 253 insertions, 306 deletions
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index c2965ea..da1bc15 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -94,6 +94,11 @@ typedef struct kwsysProcessCreateInformation_s { /* Windows child startup control data. */ STARTUPINFOW StartupInfo; + + /* Original handles before making inherited duplicates. */ + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; } kwsysProcessCreateInformation; @@ -107,15 +112,12 @@ static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td); static int kwsysProcessInitialize(kwsysProcess* cp); static int kwsysProcessCreate(kwsysProcess* cp, int index, - kwsysProcessCreateInformation* si, - PHANDLE readEnd); + kwsysProcessCreateInformation* si); static void kwsysProcessDestroy(kwsysProcess* cp, int event); static int kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name); -static int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle); -static int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], - int isWrite); +static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle); +static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle); static void kwsysProcessCleanupHandle(PHANDLE h); -static void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle); static void kwsysProcessCleanup(kwsysProcess* cp, int error); static void kwsysProcessCleanErrorMessage(kwsysProcess* cp); static int kwsysProcessComputeCommandLength(kwsysProcess* cp, @@ -306,6 +308,10 @@ struct kwsysProcess_s /* Real working directory of our own process. */ DWORD RealWorkingDirectoryLength; wchar_t* RealWorkingDirectory; + + /* Own handles for the child's ends of the pipes in the parent process. + Used temporarily during process creation. */ + HANDLE PipeChildStd[3]; }; /*--------------------------------------------------------------------------*/ @@ -446,6 +452,10 @@ kwsysProcess* kwsysProcess_New(void) return 0; } } + for(i=0; i < 3; ++i) + { + cp->PipeChildStd[i] = INVALID_HANDLE_VALUE; + } return cp; } @@ -875,9 +885,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) { int i; - /* Child startup control data. */ - kwsysProcessCreateInformation si; - /* Do not execute a second time. */ if(!cp || cp->State == kwsysProcess_State_Executing) { @@ -914,117 +921,211 @@ void kwsysProcess_Execute(kwsysProcess* cp) SetCurrentDirectoryW(cp->WorkingDirectory); } - /* Initialize startup info data. */ - ZeroMemory(&si, sizeof(si)); - si.StartupInfo.cb = sizeof(si.StartupInfo); - - /* Decide whether a child window should be shown. */ - si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW; - si.StartupInfo.wShowWindow = - (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT); - - /* Connect the child's output pipes to the threads. */ - si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; - /* Create stderr pipe to be shared by all processes in the pipeline. - Neither end is directly inherited. */ - if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read, - &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0)) + /* Setup the stdin pipe for the first process. */ + if(cp->PipeFileSTDIN) { - kwsysProcessCleanup(cp, 1); - return; + /* Create a handle to read a file for stdin. */ + wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN); + cp->PipeChildStd[0] = + CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + 0, OPEN_EXISTING, 0, 0); + free(wstdin); + if(cp->PipeChildStd[0] == INVALID_HANDLE_VALUE) + { + kwsysProcessCleanup(cp, 1); + return; + } + } + else if(cp->PipeSharedSTDIN) + { + /* Share this process's stdin with the child. */ + kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE, &cp->PipeChildStd[0]); + } + else if(cp->PipeNativeSTDIN[0]) + { + /* Use the provided native pipe. */ + kwsysProcessSetupPipeNative(cp->PipeNativeSTDIN[0], &cp->PipeChildStd[0]); + } + else + { + /* Explicitly give the child no stdin. */ + cp->PipeChildStd[0] = INVALID_HANDLE_VALUE; } - /* Create an inherited duplicate of the write end, but do not - close the non-inherited version. We need to keep it open - to use in waking up the pipe threads. */ - if(!DuplicateHandle(GetCurrentProcess(), cp->Pipe[KWSYSPE_PIPE_STDERR].Write, - GetCurrentProcess(), &si.StartupInfo.hStdError, - 0, TRUE, DUPLICATE_SAME_ACCESS)) + /* Create the output pipe for the last process. + We always create this so the pipe thread can run even if we + do not end up giving the write end to the child below. */ + if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read, + &cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0)) { kwsysProcessCleanup(cp, 1); - kwsysProcessCleanupHandle(&si.StartupInfo.hStdError); return; } - /* Replace the stderr pipe with a file if requested. In this case - the pipe thread will still run but never report data. */ - if(cp->PipeFileSTDERR) + if(cp->PipeFileSTDOUT) { - if(!kwsysProcessSetupOutputPipeFile(&si.StartupInfo.hStdError, - cp->PipeFileSTDERR)) + /* Use a file for stdout. */ + if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1], + cp->PipeFileSTDOUT)) { kwsysProcessCleanup(cp, 1); - kwsysProcessCleanupHandle(&si.StartupInfo.hStdError); return; } } - - /* Replace the stderr pipe with the parent process's if requested. - In this case the pipe thread will still run but never report - data. */ - if(cp->PipeSharedSTDERR) + else if(cp->PipeSharedSTDOUT) + { + /* Use the parent stdout. */ + kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE, &cp->PipeChildStd[1]); + } + else if(cp->PipeNativeSTDOUT[1]) + { + /* Use the given handle for stdout. */ + kwsysProcessSetupPipeNative(cp->PipeNativeSTDOUT[1], &cp->PipeChildStd[1]); + } + else { - if(!kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE, - &si.StartupInfo.hStdError)) + /* Use our pipe for stdout. Duplicate the handle since our waker + thread will use the original. Do not make it inherited yet. */ + if(!DuplicateHandle(GetCurrentProcess(), + cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, + GetCurrentProcess(), &cp->PipeChildStd[1], + 0, FALSE, DUPLICATE_SAME_ACCESS)) { kwsysProcessCleanup(cp, 1); - kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, - STD_ERROR_HANDLE); return; } } - /* Replace the stderr pipe with the native pipe provided if any. In - this case the pipe thread will still run but never report - data. */ - if(cp->PipeNativeSTDERR[1]) + /* Create stderr pipe to be shared by all processes in the pipeline. + We always create this so the pipe thread can run even if we do not + end up giving the write end to the child below. */ + if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read, + &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0)) + { + kwsysProcessCleanup(cp, 1); + return; + } + + if(cp->PipeFileSTDERR) + { + /* Use a file for stderr. */ + if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2], + cp->PipeFileSTDERR)) + { + kwsysProcessCleanup(cp, 1); + return; + } + } + else if(cp->PipeSharedSTDERR) + { + /* Use the parent stderr. */ + kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE, &cp->PipeChildStd[2]); + } + else if(cp->PipeNativeSTDERR[1]) + { + /* Use the given handle for stderr. */ + kwsysProcessSetupPipeNative(cp->PipeNativeSTDERR[1], &cp->PipeChildStd[2]); + } + else { - if(!kwsysProcessSetupPipeNative(&si.StartupInfo.hStdError, - cp->PipeNativeSTDERR, 1)) + /* Use our pipe for stderr. Duplicate the handle since our waker + thread will use the original. Do not make it inherited yet. */ + if(!DuplicateHandle(GetCurrentProcess(), + cp->Pipe[KWSYSPE_PIPE_STDERR].Write, + GetCurrentProcess(), &cp->PipeChildStd[2], + 0, FALSE, DUPLICATE_SAME_ACCESS)) { kwsysProcessCleanup(cp, 1); - kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, - STD_ERROR_HANDLE); return; } } /* Create the pipeline of processes. */ { - HANDLE readEnd = 0; + /* Child startup control data. */ + kwsysProcessCreateInformation si; + HANDLE nextStdInput = cp->PipeChildStd[0]; + + /* Initialize startup info data. */ + ZeroMemory(&si, sizeof(si)); + si.StartupInfo.cb = sizeof(si.StartupInfo); + + /* Decide whether a child window should be shown. */ + si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW; + si.StartupInfo.wShowWindow = + (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT); + + /* Connect the child's output pipes to the threads. */ + si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; + for(i=0; i < cp->NumberOfCommands; ++i) { - if(kwsysProcessCreate(cp, i, &si, &readEnd)) + /* Setup the process's pipes. */ + si.hStdInput = nextStdInput; + if (i == cp->NumberOfCommands-1) + { + /* The last child gets the overall stdout. */ + nextStdInput = INVALID_HANDLE_VALUE; + si.hStdOutput = cp->PipeChildStd[1]; + } + else + { + /* Create a pipe to sit between the children. */ + HANDLE p[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; + if (!CreatePipe(&p[0], &p[1], 0, 0)) + { + if (nextStdInput != cp->PipeChildStd[0]) + { + kwsysProcessCleanupHandle(&nextStdInput); + } + kwsysProcessCleanup(cp, 1); + return; + } + nextStdInput = p[0]; + si.hStdOutput = p[1]; + } + si.hStdError = cp->PipeChildStd[2]; + + { + int res = kwsysProcessCreate(cp, i, &si); + + /* Close our copies of pipes used between children. */ + if (si.hStdInput != cp->PipeChildStd[0]) + { + kwsysProcessCleanupHandle(&si.hStdInput); + } + if (si.hStdOutput != cp->PipeChildStd[1]) + { + kwsysProcessCleanupHandle(&si.hStdOutput); + } + if (si.hStdError != cp->PipeChildStd[2]) + { + kwsysProcessCleanupHandle(&si.hStdError); + } + if (res) { cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess; } else { + if (nextStdInput != cp->PipeChildStd[0]) + { + kwsysProcessCleanupHandle(&nextStdInput); + } kwsysProcessCleanup(cp, 1); - - /* Release resources that may have been allocated for this - process before an error occurred. */ - kwsysProcessCleanupHandle(&readEnd); - kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdInput, - STD_INPUT_HANDLE); - kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdOutput, - STD_OUTPUT_HANDLE); - kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, - STD_ERROR_HANDLE); return; } } - - /* Save a handle to the output pipe for the last process. */ - cp->Pipe[KWSYSPE_PIPE_STDOUT].Read = readEnd; + } } - /* Close the inherited handles to the stderr pipe shared by all - processes in the pipeline. The stdout and stdin pipes are not - shared among all children and are therefore closed by - kwsysProcessCreate after each child is created. */ - kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, STD_ERROR_HANDLE); + /* The parent process does not need the child's pipe ends. */ + for (i=0; i < 3; ++i) + { + kwsysProcessCleanupHandle(&cp->PipeChildStd[i]); + } /* Restore the working directory. */ if(cp->RealWorkingDirectory) @@ -1543,162 +1644,90 @@ int kwsysProcessInitialize(kwsysProcess* cp) } } } + { + int i; + for (i=0; i < 3; ++i) + { + cp->PipeChildStd[i] = INVALID_HANDLE_VALUE; + } + } return 1; } /*--------------------------------------------------------------------------*/ -int kwsysProcessCreate(kwsysProcess* cp, int index, - kwsysProcessCreateInformation* si, - PHANDLE readEnd) +static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn) { - /* Setup the process's stdin. */ - if(*readEnd) - { - /* Create an inherited duplicate of the read end from the output - pipe of the previous process. This also closes the - non-inherited version. */ - if(!DuplicateHandle(GetCurrentProcess(), *readEnd, - GetCurrentProcess(), readEnd, - 0, TRUE, (DUPLICATE_CLOSE_SOURCE | - DUPLICATE_SAME_ACCESS))) - { - return 0; - } - si->StartupInfo.hStdInput = *readEnd; + DWORD flags; - /* This function is done with this handle. */ - *readEnd = 0; - } - else if(cp->PipeFileSTDIN) - { - /* Create a handle to read a file for stdin. */ - wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN); - HANDLE fin = CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - 0, OPEN_EXISTING, 0, 0); - free(wstdin); - if(fin == INVALID_HANDLE_VALUE) - { - return 0; - } - /* Create an inherited duplicate of the handle. This also closes - the non-inherited version. */ - if(!DuplicateHandle(GetCurrentProcess(), fin, - GetCurrentProcess(), &fin, - 0, TRUE, (DUPLICATE_CLOSE_SOURCE | - DUPLICATE_SAME_ACCESS))) - { - return 0; - } - si->StartupInfo.hStdInput = fin; - } - else if(cp->PipeSharedSTDIN) - { - /* Share this process's stdin with the child. */ - if(!kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE, - &si->StartupInfo.hStdInput)) - { - return 0; - } - } - else if(cp->PipeNativeSTDIN[0]) + /* Check whether the handle is valid for this process. */ + if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags)) { - /* Use the provided native pipe. */ - if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdInput, - cp->PipeNativeSTDIN, 0)) + /* Use the handle as-is if it is already inherited. */ + if (flags & HANDLE_FLAG_INHERIT) { - return 0; + *out = in; + return 1; } + + /* Create an inherited copy of this handle. */ + return DuplicateHandle(GetCurrentProcess(), in, + GetCurrentProcess(), out, + 0, TRUE, DUPLICATE_SAME_ACCESS); } else { - /* Explicitly give the child no stdin. */ - si->StartupInfo.hStdInput = INVALID_HANDLE_VALUE; + /* The given handle is not valid for this process. Some child + processes may break if they do not have a valid standard handle, + so open NUL to give to the child. */ + SECURITY_ATTRIBUTES sa; + ZeroMemory(&sa, sizeof(sa)); + sa.nLength = (DWORD)sizeof(sa); + sa.bInheritHandle = 1; + *out = CreateFileW(L"NUL", + (isStdIn ? GENERIC_READ : + (GENERIC_WRITE | FILE_READ_ATTRIBUTES)), + FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, OPEN_EXISTING, 0, 0); + return *out != INVALID_HANDLE_VALUE; } - /* Setup the process's stdout. */ - { - DWORD maybeClose = DUPLICATE_CLOSE_SOURCE; - HANDLE writeEnd; +} - /* Create the output pipe for this process. Neither end is directly - inherited. */ - if(!CreatePipe(readEnd, &writeEnd, 0, 0)) - { - return 0; - } +/*--------------------------------------------------------------------------*/ +int kwsysProcessCreate(kwsysProcess* cp, int index, + kwsysProcessCreateInformation* si) +{ + int res = - /* Create an inherited duplicate of the write end. Close the - non-inherited version unless this is the last process. Save the - non-inherited write end of the last process. */ - if(index == cp->NumberOfCommands-1) - { - cp->Pipe[KWSYSPE_PIPE_STDOUT].Write = writeEnd; - maybeClose = 0; - } - if(!DuplicateHandle(GetCurrentProcess(), writeEnd, - GetCurrentProcess(), &writeEnd, - 0, TRUE, (maybeClose | DUPLICATE_SAME_ACCESS))) - { - return 0; - } - si->StartupInfo.hStdOutput = writeEnd; - } + /* Create inherited copies the handles. */ + kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput, + si->hStdInput, 1) && + kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput, + si->hStdOutput, 0) && + kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError, + si->hStdError, 0) && - /* Replace the stdout pipe with a file if requested. In this case - the pipe thread will still run but never report data. */ - if(index == cp->NumberOfCommands-1 && cp->PipeFileSTDOUT) - { - if(!kwsysProcessSetupOutputPipeFile(&si->StartupInfo.hStdOutput, - cp->PipeFileSTDOUT)) - { - return 0; - } - } + /* Create the child in a suspended state so we can wait until all + children have been created before running any one. */ + CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0, + 0, &si->StartupInfo, &cp->ProcessInformation[index]); - /* Replace the stdout pipe of the last child with the parent - process's if requested. In this case the pipe thread will still - run but never report data. */ - if(index == cp->NumberOfCommands-1 && cp->PipeSharedSTDOUT) + /* Close the inherited copies of the handles. */ + if (si->StartupInfo.hStdInput != si->hStdInput) { - if(!kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE, - &si->StartupInfo.hStdOutput)) - { - return 0; - } + kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput); } - - /* Replace the stdout pipe with the native pipe provided if any. In - this case the pipe thread will still run but never report - data. */ - if(index == cp->NumberOfCommands-1 && cp->PipeNativeSTDOUT[1]) + if (si->StartupInfo.hStdOutput != si->hStdOutput) { - if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdOutput, - cp->PipeNativeSTDOUT, 1)) - { - return 0; - } + kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput); } - - /* Create the child in a suspended state so we can wait until all - children have been created before running any one. */ - if(!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0, - 0, &si->StartupInfo, &cp->ProcessInformation[index])) + if (si->StartupInfo.hStdError != si->hStdError) { - return 0; + kwsysProcessCleanupHandle(&si->StartupInfo.hStdError); } - /* Successfully created this child process. Close the current - process's copies of the inherited stdout and stdin handles. The - stderr handle is shared among all children and is closed by - kwsysProcess_Execute after all children have been created. */ - kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdInput, - STD_INPUT_HANDLE); - kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdOutput, - STD_OUTPUT_HANDLE); - - return 1; + return res; } /*--------------------------------------------------------------------------*/ @@ -1763,7 +1792,7 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) return 1; } - /* Close the existing inherited handle. */ + /* Close the existing handle. */ kwsysProcessCleanupHandle(phandle); /* Create a handle to write a file for the pipe. */ @@ -1776,103 +1805,27 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) return 0; } - /* Create an inherited duplicate of the handle. This also closes - the non-inherited version. */ - if(!DuplicateHandle(GetCurrentProcess(), fout, - GetCurrentProcess(), &fout, - 0, TRUE, (DUPLICATE_CLOSE_SOURCE | - DUPLICATE_SAME_ACCESS))) - { - return 0; - } - /* Assign the replacement handle. */ *phandle = fout; return 1; } /*--------------------------------------------------------------------------*/ -int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle) +void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle) { - /* Check whether the handle to be shared is already inherited. */ - DWORD flags; - int inherited = 0; - if(GetHandleInformation(GetStdHandle(nStdHandle), &flags) && - (flags & HANDLE_FLAG_INHERIT)) - { - inherited = 1; - } - - /* Cleanup the previous handle. */ + /* Close the existing handle. */ kwsysProcessCleanupHandle(handle); - - /* If the standard handle is not inherited then duplicate it to - create an inherited copy. Do not close the original handle when - duplicating! */ - if(inherited) - { - *handle = GetStdHandle(nStdHandle); - return 1; - } - else if(DuplicateHandle(GetCurrentProcess(), GetStdHandle(nStdHandle), - GetCurrentProcess(), handle, - 0, TRUE, DUPLICATE_SAME_ACCESS)) - { - return 1; - } - else - { - /* The given standard handle is not valid for this process. Some - child processes may break if they do not have a valid standard - pipe, so give the child an empty pipe. For the stdin pipe we - want to close the write end and give the read end to the child. - For stdout and stderr we want to close the read end and give - the write end to the child. */ - int child_end = (nStdHandle == STD_INPUT_HANDLE)? 0:1; - int parent_end = (nStdHandle == STD_INPUT_HANDLE)? 1:0; - HANDLE emptyPipe[2]; - if(!CreatePipe(&emptyPipe[0], &emptyPipe[1], 0, 0)) - { - return 0; - } - - /* Close the non-inherited end so the pipe will be broken - immediately. */ - CloseHandle(emptyPipe[parent_end]); - - /* Create an inherited duplicate of the handle. This also - closes the non-inherited version. */ - if(!DuplicateHandle(GetCurrentProcess(), emptyPipe[child_end], - GetCurrentProcess(), &emptyPipe[child_end], - 0, TRUE, (DUPLICATE_CLOSE_SOURCE | - DUPLICATE_SAME_ACCESS))) - { - return 0; - } - - /* Give the inherited handle to the child. */ - *handle = emptyPipe[child_end]; - return 1; - } + /* Store the new standard handle. */ + *handle = GetStdHandle(nStdHandle); } /*--------------------------------------------------------------------------*/ -int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite) +void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle) { - /* Close the existing inherited handle. */ + /* Close the existing handle. */ kwsysProcessCleanupHandle(handle); - - /* Create an inherited duplicate of the handle. This also closes - the non-inherited version. */ - if(!DuplicateHandle(GetCurrentProcess(), p[isWrite? 1:0], - GetCurrentProcess(), handle, - 0, TRUE, (DUPLICATE_CLOSE_SOURCE | - DUPLICATE_SAME_ACCESS))) - { - return 0; - } - - return 1; + /* Store the new given handle. */ + *handle = native; } /*--------------------------------------------------------------------------*/ @@ -1880,23 +1833,13 @@ int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite) /* Close the given handle if it is open. Reset its value to 0. */ void kwsysProcessCleanupHandle(PHANDLE h) { - if(h && *h) + if(h && *h && *h != INVALID_HANDLE_VALUE && + *h != GetStdHandle(STD_INPUT_HANDLE) && + *h != GetStdHandle(STD_OUTPUT_HANDLE) && + *h != GetStdHandle(STD_ERROR_HANDLE)) { CloseHandle(*h); - *h = 0; - } -} - -/*--------------------------------------------------------------------------*/ - -/* Close the given handle if it is open and not a standard handle. - Reset its value to 0. */ -void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle) -{ - if(h && *h && (*h != GetStdHandle(nStdHandle))) - { - CloseHandle(*h); - *h = 0; + *h = INVALID_HANDLE_VALUE; } } @@ -1986,6 +1929,10 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error) kwsysProcessCleanupHandle(&cp->Pipe[i].Read); cp->Pipe[i].Closed = 0; } + for(i=0; i < 3; ++i) + { + kwsysProcessCleanupHandle(&cp->PipeChildStd[i]); + } } /*--------------------------------------------------------------------------*/ |