|
|
@@ -141,6 +141,7 @@ typedef struct kwsysProcessCreateInformation_s
|
|
|
static int kwsysProcessInitialize(kwsysProcess* cp);
|
|
|
static void kwsysProcessCleanup(kwsysProcess* cp, int error);
|
|
|
static void kwsysProcessCleanupDescriptor(int* pfd);
|
|
|
+static void kwsysProcessClosePipes(kwsysProcess* cp);
|
|
|
static int kwsysProcessSetNonBlocking(int fd);
|
|
|
static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
|
|
kwsysProcessCreateInformation* si, int* readEnd);
|
|
|
@@ -893,8 +894,6 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp)
|
|
|
{
|
|
|
- int i;
|
|
|
-
|
|
|
/* Make sure a detached child process is running. */
|
|
|
if(!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
|
|
|
cp->TimeoutExpired || cp->Killed)
|
|
|
@@ -902,33 +901,8 @@ kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* Close any pipes that are still open. */
|
|
|
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
|
|
- {
|
|
|
- if(cp->PipeReadEnds[i] >= 0)
|
|
|
- {
|
|
|
-#if KWSYSPE_USE_SELECT
|
|
|
- /* If the pipe was reported by the last call to select, we must
|
|
|
- read from it. This is needed to satisfy the suggestions from
|
|
|
- "man select_tut" and is not needed for the polling
|
|
|
- implementation. Ignore the data. */
|
|
|
- if(FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
|
|
|
- {
|
|
|
- /* We are handling this pipe now. Remove it from the set. */
|
|
|
- FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
|
|
|
-
|
|
|
- /* The pipe is ready to read without blocking. Keep trying to
|
|
|
- read until the operation is not interrupted. */
|
|
|
- while((read(cp->PipeReadEnds[i], cp->PipeBuffer,
|
|
|
- KWSYSPE_PIPE_BUFFER_SIZE) < 0) && (errno == EINTR));
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
- /* We are done reading from this pipe. */
|
|
|
- kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
|
|
- --cp->PipesLeft;
|
|
|
- }
|
|
|
- }
|
|
|
+ /* Close all the pipes safely. */
|
|
|
+ kwsysProcessClosePipes(cp);
|
|
|
|
|
|
/* We will not wait for exit, so cleanup now. */
|
|
|
kwsysProcessCleanup(cp, 0);
|
|
|
@@ -1346,18 +1320,17 @@ void kwsysProcess_Kill(kwsysProcess* cp)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ /* First close the child exit report pipe write end to avoid causing a
|
|
|
+ SIGPIPE when the child terminates and our signal handler tries to
|
|
|
+ report it after we have already closed the read end. */
|
|
|
+ kwsysProcessCleanupDescriptor(&cp->SignalPipe);
|
|
|
+
|
|
|
+#if !defined(__APPLE__)
|
|
|
/* Close all the pipe read ends. Do this before killing the
|
|
|
children because Cygwin has problems killing processes that are
|
|
|
- blocking to wait for writing to their output pipes. First close
|
|
|
- the child exit report pipe write end to avoid causing a SIGPIPE
|
|
|
- when the child terminates and our signal handler tries to report
|
|
|
- it. */
|
|
|
- kwsysProcessCleanupDescriptor(&cp->SignalPipe);
|
|
|
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
|
|
- {
|
|
|
- kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
|
|
- }
|
|
|
- cp->PipesLeft = 0;
|
|
|
+ blocking to wait for writing to their output pipes. */
|
|
|
+ kwsysProcessClosePipes(cp);
|
|
|
+#endif
|
|
|
|
|
|
/* Kill the children. */
|
|
|
cp->Killed = 1;
|
|
|
@@ -1374,6 +1347,14 @@ void kwsysProcess_Kill(kwsysProcess* cp)
|
|
|
while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR));
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+#if defined(__APPLE__)
|
|
|
+ /* Close all the pipe read ends. Do this after killing the
|
|
|
+ children because OS X has problems closing pipe read ends whose
|
|
|
+ pipes are full and still have an open write end. */
|
|
|
+ kwsysProcessClosePipes(cp);
|
|
|
+#endif
|
|
|
+
|
|
|
cp->CommandsLeft = 0;
|
|
|
}
|
|
|
|
|
|
@@ -1533,6 +1514,40 @@ static void kwsysProcessCleanupDescriptor(int* pfd)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*--------------------------------------------------------------------------*/
|
|
|
+static void kwsysProcessClosePipes(kwsysProcess* cp)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* Close any pipes that are still open. */
|
|
|
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
|
|
+ {
|
|
|
+ if(cp->PipeReadEnds[i] >= 0)
|
|
|
+ {
|
|
|
+#if KWSYSPE_USE_SELECT
|
|
|
+ /* If the pipe was reported by the last call to select, we must
|
|
|
+ read from it. This is needed to satisfy the suggestions from
|
|
|
+ "man select_tut" and is not needed for the polling
|
|
|
+ implementation. Ignore the data. */
|
|
|
+ if(FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
|
|
|
+ {
|
|
|
+ /* We are handling this pipe now. Remove it from the set. */
|
|
|
+ FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
|
|
|
+
|
|
|
+ /* The pipe is ready to read without blocking. Keep trying to
|
|
|
+ read until the operation is not interrupted. */
|
|
|
+ while((read(cp->PipeReadEnds[i], cp->PipeBuffer,
|
|
|
+ KWSYSPE_PIPE_BUFFER_SIZE) < 0) && (errno == EINTR));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ /* We are done reading from this pipe. */
|
|
|
+ kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
|
|
+ --cp->PipesLeft;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
static int kwsysProcessSetNonBlocking(int fd)
|
|
|
{
|