diff --git a/ProcessUNIX.c b/ProcessUNIX.c index 9c5915fc254fc7f7e06e3a2c2faa31115a6753bd..d32326ce4eae39ce863c2c3145897778fb1724a9 100644 --- a/ProcessUNIX.c +++ b/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; } @@ -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) { diff --git a/kwsysDateStamp.cmake b/kwsysDateStamp.cmake index 14183e6f17a4a40c5ef16a0bdcea8a54adb1d2b9..dc575c862abe61dd53d26c022441bc27a73bd425 100644 --- a/kwsysDateStamp.cmake +++ b/kwsysDateStamp.cmake @@ -7,4 +7,4 @@ SET(KWSYS_DATE_STAMP_YEAR 2008) SET(KWSYS_DATE_STAMP_MONTH 01) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 08) +SET(KWSYS_DATE_STAMP_DAY 10)