summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/ProcessUNIX.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/ProcessUNIX.c')
-rw-r--r--Source/kwsys/ProcessUNIX.c93
1 files changed, 54 insertions, 39 deletions
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 6f3d3df..d6d7fcb 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -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;
}
@@ -1534,6 +1515,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)
{
int flags = fcntl(fd, F_GETFL);