STYLE: Removed trailing whitespace.

This commit is contained in:
Brad King 2003-12-05 11:37:28 -05:00
parent 9ce4e23715
commit 97b469537b
3 changed files with 144 additions and 144 deletions

View File

@ -9,8 +9,8 @@
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See http://www.cmake.org/HTML/Copyright.html for details. See http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/

View File

@ -9,8 +9,8 @@ Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See http://www.cmake.org/HTML/Copyright.html for details. See http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/
@ -34,10 +34,10 @@ int main()
/* Process startup information for the real child. */ /* Process startup information for the real child. */
STARTUPINFO si; STARTUPINFO si;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
/* The result of waiting for the child to exit. */ /* The result of waiting for the child to exit. */
DWORD waitResult; DWORD waitResult;
/* The child's process return code. */ /* The child's process return code. */
DWORD retVal; DWORD retVal;
@ -47,7 +47,7 @@ int main()
/* Pointer that will be advanced to the beginning of the command /* Pointer that will be advanced to the beginning of the command
line of the real child process. */ line of the real child process. */
LPSTR cmdLine = commandLine; LPSTR cmdLine = commandLine;
/* Handle to the error reporting pipe provided by the parent. This /* Handle to the error reporting pipe provided by the parent. This
is parsed off the command line. */ is parsed off the command line. */
HANDLE errorPipe = 0; HANDLE errorPipe = 0;
@ -60,14 +60,14 @@ int main()
/* Handle to the event the parent uses to tell us to kill the child. /* Handle to the event the parent uses to tell us to kill the child.
This is parsed off the command line. */ This is parsed off the command line. */
HANDLE killEvent = 0; HANDLE killEvent = 0;
/* Flag for whether to hide window of child process. */ /* Flag for whether to hide window of child process. */
int hideWindow = 0; int hideWindow = 0;
/* An array of the handles on which we wait when the child is /* An array of the handles on which we wait when the child is
running. */ running. */
HANDLE waitHandles[2] = {0, 0}; HANDLE waitHandles[2] = {0, 0};
/* Move the pointer past the name of this executable. */ /* Move the pointer past the name of this executable. */
if(*cmdLine == '"') if(*cmdLine == '"')
{ {
@ -93,12 +93,12 @@ int main()
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
sscanf(cmdLine, "%p", &killEvent); sscanf(cmdLine, "%p", &killEvent);
/* Parse the hide window flag. */ /* Parse the hide window flag. */
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
sscanf(cmdLine, "%d", &hideWindow); sscanf(cmdLine, "%d", &hideWindow);
/* Skip to the beginning of the command line of the real child. */ /* Skip to the beginning of the command line of the real child. */
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
@ -154,7 +154,7 @@ int main()
TerminateProcess(pi.hProcess, 255); TerminateProcess(pi.hProcess, 255);
WaitForSingleObject(pi.hProcess, INFINITE); WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
return 1; return 1;
} }
else else
@ -191,16 +191,16 @@ void ReportLastError(HANDLE errorPipe)
{ {
LPVOID lpMsgBuf; LPVOID lpMsgBuf;
DWORD n; DWORD n;
FormatMessage( FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, NULL,
GetLastError(), GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, (LPTSTR) &lpMsgBuf,
0, 0,
NULL NULL
); );
WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0); WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0);
LocalFree( lpMsgBuf ); LocalFree( lpMsgBuf );

View File

@ -9,8 +9,8 @@ Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See http://www.cmake.org/HTML/Copyright.html for details. See http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/
@ -21,16 +21,16 @@ PURPOSE. See the above copyright notices for more information.
/* /*
Implementation for Windows Implementation for Windows
On windows, a thread is created to wait for data on each pipe. The On windows, a thread is created to wait for data on each pipe. The
threads are synchronized with the main thread to simulate the use of threads are synchronized with the main thread to simulate the use of
a UNIX-style select system call. a UNIX-style select system call.
On Windows9x platforms, a small WIN32 console application is spawned On Windows9x platforms, a small WIN32 console application is spawned
in-between the calling process and the actual child to be executed. in-between the calling process and the actual child to be executed.
This is to work-around a problem with connecting pipes from WIN16 This is to work-around a problem with connecting pipes from WIN16
console applications to WIN32 applications. console applications to WIN32 applications.
For more information, please check Microsoft Knowledge Base Articles For more information, please check Microsoft Knowledge Base Articles
Q190351 and Q150956. Q190351 and Q150956.
@ -101,125 +101,125 @@ extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
struct kwsysProcessPipeData_s struct kwsysProcessPipeData_s
{ {
/* ------------- Data managed per instance of kwsysProcess ------------- */ /* ------------- Data managed per instance of kwsysProcess ------------- */
/* Handle for the thread for this pipe. */ /* Handle for the thread for this pipe. */
HANDLE Thread; HANDLE Thread;
/* Semaphore indicating a process and pipe are available. */ /* Semaphore indicating a process and pipe are available. */
HANDLE Ready; HANDLE Ready;
/* Semaphore indicating when this thread's buffer is empty. */ /* Semaphore indicating when this thread's buffer is empty. */
HANDLE Empty; HANDLE Empty;
/* Semaphore indicating a pipe thread has reset for another process. */ /* Semaphore indicating a pipe thread has reset for another process. */
HANDLE Reset; HANDLE Reset;
/* Index of this pipe. */ /* Index of this pipe. */
int Index; int Index;
/* The kwsysProcess instance owning this pipe. */ /* The kwsysProcess instance owning this pipe. */
kwsysProcess* Process; kwsysProcess* Process;
/* ------------- Data managed per call to Execute ------------- */ /* ------------- Data managed per call to Execute ------------- */
/* Buffer for data read in this pipe's thread. */ /* Buffer for data read in this pipe's thread. */
char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE]; char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
/* The length of the data stored in the buffer. */ /* The length of the data stored in the buffer. */
DWORD DataLength; DWORD DataLength;
/* Whether the pipe has been closed. */ /* Whether the pipe has been closed. */
int Closed; int Closed;
/* Handle for the read end of this pipe. */ /* Handle for the read end of this pipe. */
HANDLE Read; HANDLE Read;
/* Handle for the write end of this pipe. */ /* Handle for the write end of this pipe. */
HANDLE Write; HANDLE Write;
}; };
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
/* Structure containing data used to implement the child's execution. */ /* Structure containing data used to implement the child's execution. */
struct kwsysProcess_s struct kwsysProcess_s
{ {
/* ------------- Data managed per instance of kwsysProcess ------------- */ /* ------------- Data managed per instance of kwsysProcess ------------- */
/* The status of the process structure. */ /* The status of the process structure. */
int State; int State;
/* The command lines to execute. */ /* The command lines to execute. */
char** Commands; char** Commands;
int NumberOfCommands; int NumberOfCommands;
/* The exit code of each command. */ /* The exit code of each command. */
DWORD* CommandExitCodes; DWORD* CommandExitCodes;
/* The working directory for the child process. */ /* The working directory for the child process. */
char* WorkingDirectory; char* WorkingDirectory;
/* Whether to hide the child process's window. */ /* Whether to hide the child process's window. */
int HideWindow; int HideWindow;
/* On Win9x platforms, the path to the forwarding executable. */ /* On Win9x platforms, the path to the forwarding executable. */
char* Win9x; char* Win9x;
/* On Win9x platforms, the resume event for the forwarding executable. */ /* On Win9x platforms, the resume event for the forwarding executable. */
HANDLE Win9xResumeEvent; HANDLE Win9xResumeEvent;
/* On Win9x platforms, the kill event for the forwarding executable. */ /* On Win9x platforms, the kill event for the forwarding executable. */
HANDLE Win9xKillEvent; HANDLE Win9xKillEvent;
/* Mutex to protect the shared index used by threads to report data. */ /* Mutex to protect the shared index used by threads to report data. */
HANDLE SharedIndexMutex; HANDLE SharedIndexMutex;
/* Semaphore used by threads to signal data ready. */ /* Semaphore used by threads to signal data ready. */
HANDLE Full; HANDLE Full;
/* Whether we are currently deleting this kwsysProcess instance. */ /* Whether we are currently deleting this kwsysProcess instance. */
int Deleting; int Deleting;
/* Data specific to each pipe and its thread. */ /* Data specific to each pipe and its thread. */
kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT]; kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT];
/* ------------- Data managed per call to Execute ------------- */ /* ------------- Data managed per call to Execute ------------- */
/* The exceptional behavior that terminated the process, if any. */ /* The exceptional behavior that terminated the process, if any. */
int ExitException; int ExitException;
/* The process exit code. */ /* The process exit code. */
DWORD ExitCode; DWORD ExitCode;
/* The process return code, if any. */ /* The process return code, if any. */
int ExitValue; int ExitValue;
/* Index of last pipe to report data, if any. */ /* Index of last pipe to report data, if any. */
int CurrentIndex; int CurrentIndex;
/* Index shared by threads to report data. */ /* Index shared by threads to report data. */
int SharedIndex; int SharedIndex;
/* The timeout length. */ /* The timeout length. */
double Timeout; double Timeout;
/* Time at which the child started. */ /* Time at which the child started. */
kwsysProcessTime StartTime; kwsysProcessTime StartTime;
/* Time at which the child will timeout. Negative for no timeout. */ /* Time at which the child will timeout. Negative for no timeout. */
kwsysProcessTime TimeoutTime; kwsysProcessTime TimeoutTime;
/* Flag for whether the process was killed. */ /* Flag for whether the process was killed. */
int Killed; int Killed;
/* Flag for whether the timeout expired. */ /* Flag for whether the timeout expired. */
int TimeoutExpired; int TimeoutExpired;
/* Flag for whether the process has terminated. */ /* Flag for whether the process has terminated. */
int Terminated; int Terminated;
/* The number of pipes still open during execution and while waiting /* The number of pipes still open during execution and while waiting
for pipes to close after process termination. */ for pipes to close after process termination. */
int PipesLeft; int PipesLeft;
/* Buffer for error messages (possibly from Win9x child). */ /* Buffer for error messages (possibly from Win9x child). */
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1]; char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
@ -244,7 +244,7 @@ kwsysProcess* kwsysProcess_New()
/* Windows version number data. */ /* Windows version number data. */
OSVERSIONINFO osv; OSVERSIONINFO osv;
/* Allocate a process control structure. */ /* Allocate a process control structure. */
cp = (kwsysProcess*)malloc(sizeof(kwsysProcess)); cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
if(!cp) if(!cp)
@ -253,10 +253,10 @@ kwsysProcess* kwsysProcess_New()
return 0; return 0;
} }
ZeroMemory(cp, sizeof(*cp)); ZeroMemory(cp, sizeof(*cp));
/* Set initial status. */ /* Set initial status. */
cp->State = kwsysProcess_State_Starting; cp->State = kwsysProcess_State_Starting;
/* Choose a method of running the child based on version of /* Choose a method of running the child based on version of
windows. */ windows. */
ZeroMemory(&osv, sizeof(osv)); ZeroMemory(&osv, sizeof(osv));
@ -268,16 +268,16 @@ kwsysProcess* kwsysProcess_New()
work-around a Windows 9x bug. */ work-around a Windows 9x bug. */
char fwdName[_MAX_FNAME+1] = ""; char fwdName[_MAX_FNAME+1] = "";
char tempDir[_MAX_PATH+1] = ""; char tempDir[_MAX_PATH+1] = "";
/* We will try putting the executable in the system temp /* We will try putting the executable in the system temp
directory. Note that the returned path already has a trailing directory. Note that the returned path already has a trailing
slash. */ slash. */
DWORD length = GetTempPath(_MAX_PATH+1, tempDir); DWORD length = GetTempPath(_MAX_PATH+1, tempDir);
/* Construct the executable name from the process id and kwsysProcess /* Construct the executable name from the process id and kwsysProcess
instance. This should be unique. */ instance. This should be unique. */
sprintf(fwdName, "cmw9xfwd_%u_%p.exe", GetCurrentProcessId(), cp); sprintf(fwdName, "cmw9xfwd_%u_%p.exe", GetCurrentProcessId(), cp);
/* If we have a temp directory, use it. */ /* If we have a temp directory, use it. */
if(length > 0 && length <= _MAX_PATH) if(length > 0 && length <= _MAX_PATH)
{ {
@ -289,11 +289,11 @@ kwsysProcess* kwsysProcess_New()
kwsysProcess_Delete(cp); kwsysProcess_Delete(cp);
return 0; return 0;
} }
/* Construct the full path to the forwarding executable. */ /* Construct the full path to the forwarding executable. */
sprintf(win9x, "%s%s", tempDir, fwdName); sprintf(win9x, "%s%s", tempDir, fwdName);
} }
/* If we found a place to put the forwarding executable, try to /* If we found a place to put the forwarding executable, try to
write it. */ write it. */
if(win9x) if(win9x)
@ -313,17 +313,17 @@ kwsysProcess* kwsysProcess_New()
return 0; return 0;
} }
} }
/* Save the path to the forwarding executable. */ /* Save the path to the forwarding executable. */
cp->Win9x = win9x; cp->Win9x = win9x;
/* Initially no thread owns the mutex. Initialize semaphore to 1. */ /* Initially no thread owns the mutex. Initialize semaphore to 1. */
if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0))) if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
{ {
kwsysProcess_Delete(cp); kwsysProcess_Delete(cp);
return 0; return 0;
} }
/* Initially no data are available. Initialize semaphore to 0. */ /* Initially no data are available. Initialize semaphore to 0. */
if(!(cp->Full = CreateSemaphore(0, 0, 1, 0))) if(!(cp->Full = CreateSemaphore(0, 0, 1, 0)))
{ {
@ -354,39 +354,39 @@ kwsysProcess* kwsysProcess_New()
return 0; return 0;
} }
} }
/* Create the thread to read each pipe. */ /* Create the thread to read each pipe. */
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
{ {
DWORD dummy=0; DWORD dummy=0;
/* Assign the thread its index. */ /* Assign the thread its index. */
cp->Pipe[i].Index = i; cp->Pipe[i].Index = i;
/* Give the thread a pointer back to the kwsysProcess instance. */ /* Give the thread a pointer back to the kwsysProcess instance. */
cp->Pipe[i].Process = cp; cp->Pipe[i].Process = cp;
/* The pipe is not yet ready to read. Initialize semaphore to 0. */ /* The pipe is not yet ready to read. Initialize semaphore to 0. */
if(!(cp->Pipe[i].Ready = CreateSemaphore(0, 0, 1, 0))) if(!(cp->Pipe[i].Ready = CreateSemaphore(0, 0, 1, 0)))
{ {
kwsysProcess_Delete(cp); kwsysProcess_Delete(cp);
return 0; return 0;
} }
/* The pipe is not yet reset. Initialize semaphore to 0. */ /* The pipe is not yet reset. Initialize semaphore to 0. */
if(!(cp->Pipe[i].Reset = CreateSemaphore(0, 0, 1, 0))) if(!(cp->Pipe[i].Reset = CreateSemaphore(0, 0, 1, 0)))
{ {
kwsysProcess_Delete(cp); kwsysProcess_Delete(cp);
return 0; return 0;
} }
/* The thread's buffer is initially empty. Initialize semaphore to 1. */ /* The thread's buffer is initially empty. Initialize semaphore to 1. */
if(!(cp->Pipe[i].Empty = CreateSemaphore(0, 1, 1, 0))) if(!(cp->Pipe[i].Empty = CreateSemaphore(0, 1, 1, 0)))
{ {
kwsysProcess_Delete(cp); kwsysProcess_Delete(cp);
return 0; return 0;
} }
/* Create the thread. It will block immediately. The thread will /* Create the thread. It will block immediately. The thread will
not make deeply nested calls, so we need only a small not make deeply nested calls, so we need only a small
stack. */ stack. */
@ -397,7 +397,7 @@ kwsysProcess* kwsysProcess_New()
return 0; return 0;
} }
} }
return cp; return cp;
} }
@ -411,10 +411,10 @@ void kwsysProcess_Delete(kwsysProcess* cp)
{ {
kwsysProcess_WaitForExit(cp, 0); kwsysProcess_WaitForExit(cp, 0);
} }
/* We are deleting the kwsysProcess instance. */ /* We are deleting the kwsysProcess instance. */
cp->Deleting = 1; cp->Deleting = 1;
/* Terminate each of the threads. */ /* Terminate each of the threads. */
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
{ {
@ -423,30 +423,30 @@ void kwsysProcess_Delete(kwsysProcess* cp)
/* Signal the thread we are ready for it. It will terminate /* Signal the thread we are ready for it. It will terminate
immediately since Deleting is set. */ immediately since Deleting is set. */
ReleaseSemaphore(cp->Pipe[i].Ready, 1, 0); ReleaseSemaphore(cp->Pipe[i].Ready, 1, 0);
/* Wait for the thread to exit. */ /* Wait for the thread to exit. */
WaitForSingleObject(cp->Pipe[i].Thread, INFINITE); WaitForSingleObject(cp->Pipe[i].Thread, INFINITE);
/* Close the handle to the thread. */ /* Close the handle to the thread. */
kwsysProcessCleanupHandle(&cp->Pipe[i].Thread); kwsysProcessCleanupHandle(&cp->Pipe[i].Thread);
} }
/* Cleanup the pipe's semaphores. */ /* Cleanup the pipe's semaphores. */
kwsysProcessCleanupHandle(&cp->Pipe[i].Ready); kwsysProcessCleanupHandle(&cp->Pipe[i].Ready);
kwsysProcessCleanupHandle(&cp->Pipe[i].Empty); kwsysProcessCleanupHandle(&cp->Pipe[i].Empty);
} }
/* Close the shared semaphores. */ /* Close the shared semaphores. */
kwsysProcessCleanupHandle(&cp->SharedIndexMutex); kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
kwsysProcessCleanupHandle(&cp->Full); kwsysProcessCleanupHandle(&cp->Full);
/* Close the Win9x resume and kill event handles. */ /* Close the Win9x resume and kill event handles. */
if(cp->Win9x) if(cp->Win9x)
{ {
kwsysProcessCleanupHandle(&cp->Win9xResumeEvent); kwsysProcessCleanupHandle(&cp->Win9xResumeEvent);
kwsysProcessCleanupHandle(&cp->Win9xKillEvent); kwsysProcessCleanupHandle(&cp->Win9xKillEvent);
} }
/* Free memory. */ /* Free memory. */
kwsysProcess_SetCommand(cp, 0); kwsysProcess_SetCommand(cp, 0);
kwsysProcess_SetWorkingDirectory(cp, 0); kwsysProcess_SetWorkingDirectory(cp, 0);
@ -542,11 +542,11 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
break; break;
} }
} }
/* Add the length of the argument, plus 1 for the space /* Add the length of the argument, plus 1 for the space
separating the arguments. */ separating the arguments. */
length += (int)strlen(*arg) + 1; length += (int)strlen(*arg) + 1;
if(spaces) if(spaces)
{ {
/* Add 2 for double quotes since spaces are present. */ /* Add 2 for double quotes since spaces are present. */
@ -575,12 +575,12 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
backslashes = 0; backslashes = 0;
} }
} }
/* We need to escape all ending backslashes. */ /* We need to escape all ending backslashes. */
length += backslashes; length += backslashes;
} }
} }
/* Allocate enough space for the command. We do not need an extra /* Allocate enough space for the command. We do not need an extra
byte for the terminating null because we allocated a space for byte for the terminating null because we allocated a space for
the first argument that we will not use. */ the first argument that we will not use. */
@ -591,7 +591,7 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
free(newCommands); free(newCommands);
return 0; return 0;
} }
/* Construct the command line in the allocated buffer. */ /* Construct the command line in the allocated buffer. */
cmd = newCommands[cp->NumberOfCommands]; cmd = newCommands[cp->NumberOfCommands];
for(arg = command; *arg; ++arg) for(arg = command; *arg; ++arg)
@ -611,19 +611,19 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
spaces = 1; spaces = 1;
break; break;
} }
} }
/* Add the separating space if this is not the first argument. */ /* Add the separating space if this is not the first argument. */
if(arg != command) if(arg != command)
{ {
*cmd++ = ' '; *cmd++ = ' ';
} }
if(spaces) if(spaces)
{ {
/* Add the opening double-quote for this argument. */ /* Add the opening double-quote for this argument. */
*cmd++ = '"'; *cmd++ = '"';
/* Add the characters of the argument, possibly escaping them. */ /* Add the characters of the argument, possibly escaping them. */
for(c=*arg; *c; ++c) for(c=*arg; *c; ++c)
{ {
@ -642,10 +642,10 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
--backslashes; --backslashes;
*cmd++ = '\\'; *cmd++ = '\\';
} }
/* Add the backslash to escape the double-quote. */ /* Add the backslash to escape the double-quote. */
*cmd++ = '\\'; *cmd++ = '\\';
/* Add the double-quote itself. */ /* Add the double-quote itself. */
*cmd++ = '"'; *cmd++ = '"';
} }
@ -658,7 +658,7 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
*cmd++ = *c; *cmd++ = *c;
} }
} }
/* Add enough backslashes to escape any trailing ones. */ /* Add enough backslashes to escape any trailing ones. */
while(backslashes > 0) while(backslashes > 0)
{ {
@ -781,7 +781,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Child startup control data. */ /* Child startup control data. */
kwsysProcessCreateInformation si; kwsysProcessCreateInformation si;
/* Do not execute a second time. */ /* Do not execute a second time. */
if(cp->State == kwsysProcess_State_Executing) if(cp->State == kwsysProcess_State_Executing)
{ {
@ -795,7 +795,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
cp->State = kwsysProcess_State_Error; cp->State = kwsysProcess_State_Error;
return; return;
} }
/* Reset the Win9x resume and kill events. */ /* Reset the Win9x resume and kill events. */
if(cp->Win9x) if(cp->Win9x)
{ {
@ -814,12 +814,12 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Initialize startup info data. */ /* Initialize startup info data. */
ZeroMemory(&si, sizeof(si)); ZeroMemory(&si, sizeof(si));
si.StartupInfo.cb = sizeof(si.StartupInfo); si.StartupInfo.cb = sizeof(si.StartupInfo);
/* Decide whether a child window should be shown. */ /* Decide whether a child window should be shown. */
si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW; si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
si.StartupInfo.wShowWindow = si.StartupInfo.wShowWindow =
(unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT); (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
/* Connect the child's output pipes to the threads. */ /* Connect the child's output pipes to the threads. */
si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
@ -831,7 +831,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
kwsysProcessCleanup(cp, 1); kwsysProcessCleanup(cp, 1);
return; return;
} }
/* Create an inherited duplicate of the write end, but do not /* Create an inherited duplicate of the write end, but do not
close the non-inherited version. We need to keep it open close the non-inherited version. We need to keep it open
to use in waking up the pipe threads. */ to use in waking up the pipe threads. */
@ -883,7 +883,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* The timeout period starts now. */ /* The timeout period starts now. */
cp->StartTime = kwsysProcessTimeGetCurrent(); cp->StartTime = kwsysProcessTimeGetCurrent();
cp->TimeoutTime = kwsysProcessTimeFromDouble(-1); cp->TimeoutTime = kwsysProcessTimeFromDouble(-1);
/* All processes in the pipeline have been started in suspended /* All processes in the pipeline have been started in suspended
mode. Resume them all now. */ mode. Resume them all now. */
if(cp->Win9x) if(cp->Win9x)
@ -898,7 +898,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
} }
} }
/* ---- It is no longer safe to call kwsysProcessCleanup. ----- */ /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
/* Tell the pipe threads that a process has started. */ /* Tell the pipe threads that a process has started. */
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
{ {
@ -910,11 +910,11 @@ void kwsysProcess_Execute(kwsysProcess* cp)
{ {
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread); kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
} }
/* No pipe has reported data. */ /* No pipe has reported data. */
cp->CurrentIndex = KWSYSPE_PIPE_COUNT; cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
cp->PipesLeft = KWSYSPE_PIPE_COUNT; cp->PipesLeft = KWSYSPE_PIPE_COUNT;
/* The process has now started. */ /* The process has now started. */
cp->State = kwsysProcess_State_Executing; cp->State = kwsysProcess_State_Executing;
} }
@ -940,14 +940,14 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* leng
{ {
return 0; return 0;
} }
/* Record the time at which user timeout period starts. */ /* Record the time at which user timeout period starts. */
userStartTime = kwsysProcessTimeGetCurrent(); userStartTime = kwsysProcessTimeGetCurrent();
/* Calculate the time at which a timeout will expire, and whether it /* Calculate the time at which a timeout will expire, and whether it
is the user or process timeout. */ is the user or process timeout. */
user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime); user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime);
/* Loop until we have a reason to return. */ /* Loop until we have a reason to return. */
while(!done && cp->PipesLeft > 0) while(!done && cp->PipesLeft > 0)
{ {
@ -958,7 +958,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* leng
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0); ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0);
cp->CurrentIndex = KWSYSPE_PIPE_COUNT; cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
} }
/* Setup a timeout if required. */ /* Setup a timeout if required. */
if(kwsysProcessGetTimeoutLeft(&timeoutTime, &timeoutLength)) if(kwsysProcessGetTimeoutLeft(&timeoutTime, &timeoutLength))
{ {
@ -974,7 +974,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* leng
{ {
timeout = kwsysProcessTimeToDWORD(timeoutLength); timeout = kwsysProcessTimeToDWORD(timeoutLength);
} }
/* Wait for a pipe's thread to signal or a process to terminate. */ /* Wait for a pipe's thread to signal or a process to terminate. */
w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents, w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents,
0, timeout); 0, timeout);
@ -990,7 +990,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* leng
The thread will block until we signal its Empty mutex. */ The thread will block until we signal its Empty mutex. */
cp->CurrentIndex = cp->SharedIndex; cp->CurrentIndex = cp->SharedIndex;
ReleaseSemaphore(cp->SharedIndexMutex, 1, 0); ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
/* Data are available or a pipe closed. */ /* Data are available or a pipe closed. */
if(cp->Pipe[cp->CurrentIndex].Closed) if(cp->Pipe[cp->CurrentIndex].Closed)
{ {
@ -1016,7 +1016,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* leng
kwsysProcessDestroy(cp, w-WAIT_OBJECT_0); kwsysProcessDestroy(cp, w-WAIT_OBJECT_0);
} }
} }
/* Update the user timeout. */ /* Update the user timeout. */
if(userTimeout) if(userTimeout)
{ {
@ -1030,7 +1030,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* leng
*userTimeout = 0; *userTimeout = 0;
} }
} }
/* Check what happened. */ /* Check what happened. */
if(pipeId) if(pipeId)
{ {
@ -1066,13 +1066,13 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
{ {
int i; int i;
int pipe; int pipe;
/* Make sure we are executing a process. */ /* Make sure we are executing a process. */
if(cp->State != kwsysProcess_State_Executing) if(cp->State != kwsysProcess_State_Executing)
{ {
return 1; return 1;
} }
/* Wait for the process to terminate. Ignore all data. */ /* Wait for the process to terminate. Ignore all data. */
while((pipe = kwsysProcess_WaitForData(cp, 0, 0, 0, userTimeout)) > 0) while((pipe = kwsysProcess_WaitForData(cp, 0, 0, 0, userTimeout)) > 0)
{ {
@ -1096,11 +1096,11 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
{ {
WaitForSingleObject(cp->Pipe[i].Reset, INFINITE); WaitForSingleObject(cp->Pipe[i].Reset, INFINITE);
} }
/* ---- It is now safe again to call kwsysProcessCleanup. ----- */ /* ---- It is now safe again to call kwsysProcessCleanup. ----- */
/* Close all the pipes. */ /* Close all the pipes. */
kwsysProcessCleanup(cp, 0); kwsysProcessCleanup(cp, 0);
/* Determine the outcome. */ /* Determine the outcome. */
if(cp->Killed) if(cp->Killed)
{ {
@ -1122,7 +1122,7 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
cp->State = kwsysProcess_State_Exception; cp->State = kwsysProcess_State_Exception;
switch (cp->ExitCode) switch (cp->ExitCode)
{ {
case CONTROL_C_EXIT: case CONTROL_C_EXIT:
cp->ExitException = kwsysProcess_Exception_Interrupt; break; cp->ExitException = kwsysProcess_Exception_Interrupt; break;
case EXCEPTION_FLT_DENORMAL_OPERAND: case EXCEPTION_FLT_DENORMAL_OPERAND:
@ -1170,14 +1170,14 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
void kwsysProcess_Kill(kwsysProcess* cp) void kwsysProcess_Kill(kwsysProcess* cp)
{ {
int i; int i;
/* Make sure we are executing a process. */ /* Make sure we are executing a process. */
if(cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired || if(cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
cp->Killed || cp->Terminated) cp->Killed || cp->Terminated)
{ {
return; return;
} }
/* If we are killing a process that just reported data, release /* If we are killing a process that just reported data, release
the pipe's thread. */ the pipe's thread. */
if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT) if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
@ -1185,14 +1185,14 @@ void kwsysProcess_Kill(kwsysProcess* cp)
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0); ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0);
cp->CurrentIndex = KWSYSPE_PIPE_COUNT; cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
} }
/* Wake up all the pipe threads with dummy data. */ /* Wake up all the pipe threads with dummy data. */
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
{ {
DWORD dummy; DWORD dummy;
WriteFile(cp->Pipe[i].Write, "", 1, &dummy, 0); WriteFile(cp->Pipe[i].Write, "", 1, &dummy, 0);
} }
/* Tell pipe threads to reset until we run another process. */ /* Tell pipe threads to reset until we run another process. */
while(cp->PipesLeft > 0) while(cp->PipesLeft > 0)
{ {
@ -1203,7 +1203,7 @@ void kwsysProcess_Kill(kwsysProcess* cp)
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0); ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0);
--cp->PipesLeft; --cp->PipesLeft;
} }
/* Kill the children. */ /* Kill the children. */
cp->Killed = 1; cp->Killed = 1;
if(cp->Win9x) if(cp->Win9x)
@ -1237,17 +1237,17 @@ DWORD WINAPI kwsysProcessPipeThread(LPVOID ptd)
{ {
kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd; kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
kwsysProcess* cp = td->Process; kwsysProcess* cp = td->Process;
/* Wait for a process to be ready. */ /* Wait for a process to be ready. */
while((WaitForSingleObject(td->Ready, INFINITE), !cp->Deleting)) while((WaitForSingleObject(td->Ready, INFINITE), !cp->Deleting))
{ {
/* Read output from the process for this thread's pipe. */ /* Read output from the process for this thread's pipe. */
kwsysProcessPipeThreadReadPipe(cp, td); kwsysProcessPipeThreadReadPipe(cp, td);
/* We were signalled to exit with our buffer empty. Reset the /* We were signalled to exit with our buffer empty. Reset the
mutex for a new process. */ mutex for a new process. */
ReleaseSemaphore(td->Empty, 1, 0); ReleaseSemaphore(td->Empty, 1, 0);
/* Signal the main thread we have reset for a new process. */ /* Signal the main thread we have reset for a new process. */
ReleaseSemaphore(td->Reset, 1, 0); ReleaseSemaphore(td->Reset, 1, 0);
} }
@ -1273,14 +1273,14 @@ void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
{ {
/* UNEXPECTED failure to read the pipe. */ /* UNEXPECTED failure to read the pipe. */
} }
/* The pipe closed. There are no more data to read. */ /* The pipe closed. There are no more data to read. */
td->Closed = 1; td->Closed = 1;
} }
/* Wait for our turn to be handled by the main thread. */ /* Wait for our turn to be handled by the main thread. */
WaitForSingleObject(cp->SharedIndexMutex, INFINITE); WaitForSingleObject(cp->SharedIndexMutex, INFINITE);
/* Tell the main thread we have something to report. */ /* Tell the main thread we have something to report. */
cp->SharedIndex = td->Index; cp->SharedIndex = td->Index;
ReleaseSemaphore(cp->Full, 1, 0); ReleaseSemaphore(cp->Full, 1, 0);
@ -1298,10 +1298,10 @@ int kwsysProcessInitialize(kwsysProcess* cp)
cp->ExitException = kwsysProcess_Exception_None; cp->ExitException = kwsysProcess_Exception_None;
cp->ExitCode = 1; cp->ExitCode = 1;
cp->ExitValue = 1; cp->ExitValue = 1;
/* Reset error data. */ /* Reset error data. */
cp->ErrorMessage[0] = 0; cp->ErrorMessage[0] = 0;
/* Allocate process information for each process. */ /* Allocate process information for each process. */
cp->ProcessInformation = cp->ProcessInformation =
(PROCESS_INFORMATION*)malloc(sizeof(PROCESS_INFORMATION) * (PROCESS_INFORMATION*)malloc(sizeof(PROCESS_INFORMATION) *
@ -1405,7 +1405,7 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
{ {
return 0; return 0;
} }
/* Create an inherited duplicate of the write end. This also closes /* Create an inherited duplicate of the write end. This also closes
the non-inherited version. */ the non-inherited version. */
if(!DuplicateHandle(GetCurrentProcess(), si->ErrorPipeWrite, if(!DuplicateHandle(GetCurrentProcess(), si->ErrorPipeWrite,
@ -1561,7 +1561,7 @@ void kwsysProcessCleanupHandle(PHANDLE h)
void kwsysProcessCleanup(kwsysProcess* cp, int error) void kwsysProcessCleanup(kwsysProcess* cp, int error)
{ {
int i; int i;
/* If this is an error case, report the error. */ /* If this is an error case, report the error. */
if(error) if(error)
{ {
@ -1585,7 +1585,7 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
} }
/* Remove trailing period and newline, if any. */ /* Remove trailing period and newline, if any. */
kwsysProcessCleanErrorMessage(cp); kwsysProcessCleanErrorMessage(cp);
/* Set the error state. */ /* Set the error state. */
cp->State = kwsysProcess_State_Error; cp->State = kwsysProcess_State_Error;
@ -1607,7 +1607,7 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE); WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
} }
} }
} }
for(i=0; i < cp->NumberOfCommands; ++i) for(i=0; i < cp->NumberOfCommands; ++i)
{ {
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread); kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
@ -1633,7 +1633,7 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
{ {
kwsysProcessCleanupHandle(&cp->Pipe[i].Write); kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
kwsysProcessCleanupHandle(&cp->Pipe[i].Read); kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
} }
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -1669,11 +1669,11 @@ int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
{ {
kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout); kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length); cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
} }
/* Start with process timeout. */ /* Start with process timeout. */
*timeoutTime = cp->TimeoutTime; *timeoutTime = cp->TimeoutTime;
/* Check if the user timeout is earlier. */ /* Check if the user timeout is earlier. */
if(userTimeout) if(userTimeout)
{ {