diff options
Diffstat (limited to 'Source/kwsys/ProcessFwd9x.c')
-rw-r--r-- | Source/kwsys/ProcessFwd9x.c | 109 |
1 files changed, 80 insertions, 29 deletions
diff --git a/Source/kwsys/ProcessFwd9x.c b/Source/kwsys/ProcessFwd9x.c index 7c03a68..689fbb0 100644 --- a/Source/kwsys/ProcessFwd9x.c +++ b/Source/kwsys/ProcessFwd9x.c @@ -27,6 +27,8 @@ PURPOSE. See the above copyright notices for more information. #include <windows.h> #include <stdio.h> +void ReportLastError(HANDLE errorPipe); + int main() { /* Process startup information for the real child. */ @@ -49,6 +51,11 @@ int main() /* Handle to the error reporting pipe provided by the parent. This is parsed off the command line. */ HANDLE errorPipe = 0; + HANDLE errorPipeOrig = 0; + + /* Handle to the event the parent uses to tell us to resume the child. + This is parsed off the command line. */ + HANDLE resumeEvent = 0; /* Handle to the event the parent uses to tell us to kill the child. This is parsed off the command line. */ @@ -75,7 +82,12 @@ int main() /* Parse the error pipe handle. */ while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } - sscanf(cmdLine, "%p", &errorPipe); + sscanf(cmdLine, "%p", &errorPipeOrig); + + /* Parse the resume event handle. */ + while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } + while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } + sscanf(cmdLine, "%p", &resumeEvent); /* Parse the kill event handle. */ while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } @@ -91,6 +103,22 @@ int main() while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } + /* Create a non-inherited copy of the error pipe. We do not want + the child to get it. */ + if(DuplicateHandle(GetCurrentProcess(), errorPipeOrig, + GetCurrentProcess(), &errorPipe, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + /* Have a non-inherited duplicate. Close the inherited one. */ + CloseHandle(errorPipeOrig); + } + else + { + /* Could not duplicate handle. Report the error. */ + ReportLastError(errorPipeOrig); + return 1; + } + /* Create the subprocess. */ ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi)); @@ -100,32 +128,23 @@ int main() si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); si.hStdError = GetStdHandle(STD_ERROR_HANDLE); - if(!CreateProcess(0, cmdLine, 0, 0, TRUE, 0, 0, 0, &si, &pi)) + if(CreateProcess(0, cmdLine, 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si, &pi)) + { + /* Process created successfully. Close the error reporting pipe + to notify the parent of success. */ + CloseHandle(errorPipe); + } + else { /* Error creating the process. Report the error to the parent process through the special error reporting pipe. */ - LPVOID lpMsgBuf; - DWORD n; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0); - LocalFree( lpMsgBuf ); + ReportLastError(errorPipe); return 1; } - CloseHandle(pi.hThread); - /* Wait for subprocess to exit or for kill event from parent. */ + /* Wait for resume or kill event from parent. */ waitHandles[0] = killEvent; - waitHandles[1] = pi.hProcess; + waitHandles[1] = resumeEvent; waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE); /* Check what happened. */ @@ -135,22 +154,54 @@ int main() TerminateProcess(pi.hProcess, 255); WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); return 1; } - else if(GetExitCodeProcess(pi.hProcess, &retVal)) + else + { + /* We were asked to resume the child. */ + ResumeThread(pi.hThread); + CloseHandle(pi.hThread); + } + + /* Wait for subprocess to exit or for kill event from parent. */ + waitHandles[0] = killEvent; + waitHandles[1] = pi.hProcess; + waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE); + + /* Check what happened. */ + if(waitResult == WAIT_OBJECT_0) { - /* The child exited and we could get the return code. */ + /* We were asked to kill the child. */ + TerminateProcess(pi.hProcess, 255); + WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); - return retVal; + return 1; } else { - /* The child exited and we could not get the return code. Report - the problem to the parent process. */ - DWORD n; - const char* msg = "Failed to get process return code."; - WriteFile(errorPipe, msg, strlen(msg)+1, &n, 0); + /* The child exited. Get the return code. */ + GetExitCodeProcess(pi.hProcess, &retVal); CloseHandle(pi.hProcess); - return -1; + return retVal; } } + +void ReportLastError(HANDLE errorPipe) +{ + LPVOID lpMsgBuf; + DWORD n; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0); + LocalFree( lpMsgBuf ); +} |