summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/ProcessFwd9x.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/ProcessFwd9x.c')
-rw-r--r--Source/kwsys/ProcessFwd9x.c109
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 );
+}