1 /*=========================================================================
3 Program: KWSys - Kitware System Library
4 Module: $RCSfile: ProcessUNIX.c,v $
6 Date: $Date: 2003-12-03 14:20:05 $
7 Version: $Revision: 1.15 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #define KWSYS_IN_PROCESS_C
18 #include "kwsysPrivate.h"
19 #include KWSYS_HEADER(Process.h)
23 Implementation for UNIX
25 On UNIX, a child process is forked to exec the program. Three
26 output pipes from the child are read by the parent process using a
27 select call to block until data are ready. Two of the pipes are
28 stdout and stderr for the child. The third is a special error pipe
29 that has two purposes. First, if the child cannot exec the program,
30 the error is reported through the error pipe. Second, the error
31 pipe is left open until the child exits. This is used in
32 conjunction with the timeout on the select call to implement a
33 timeout for program even when it closes stdout and stderr.
40 We cannot create the pipeline of processes in suspended states. How
41 do we cleanup processes already started when one fails to load? Right
42 now we are just killing them, which is probably not the right thing to
47 #include <stdio.h> /* snprintf */
48 #include <stdlib.h> /* malloc, free */
49 #include <string.h> /* strdup, strerror, memset */
50 #include <sys/time.h> /* struct timeval */
51 #include <sys/types.h> /* pid_t, fd_set */
52 #include <sys/wait.h> /* waitpid */
53 #include <unistd.h> /* pipe, close, fork, execvp, select, _exit */
54 #include <fcntl.h> /* fcntl */
55 #include <errno.h> /* errno */
56 #include <time.h> /* gettimeofday */
57 #include <signal.h> /* sigaction */
59 /* The number of pipes for the child's output. The standard stdout
60 and stderr pipes are the first two. One more pipe is used to
61 detect when the child process has terminated. The third pipe is
62 not given to the child process, so it cannot close it until it
64 #define KWSYSPE_PIPE_COUNT 3
65 #define KWSYSPE_PIPE_STDOUT 0
66 #define KWSYSPE_PIPE_STDERR 1
67 #define KWSYSPE_PIPE_TERM 2
69 /* The maximum amount to read from a pipe at a time. */
70 #define KWSYSPE_PIPE_BUFFER_SIZE 1024
72 typedef struct timeval kwsysProcessTime
;
74 typedef struct kwsysProcessCreateInformation_s
81 } kwsysProcessCreateInformation
;
83 /*--------------------------------------------------------------------------*/
84 static int kwsysProcessInitialize(kwsysProcess
* cp
);
85 static void kwsysProcessCleanup(kwsysProcess
* cp
, int error
);
86 static void kwsysProcessCleanupDescriptor(int* pfd
);
87 static int kwsysProcessCreate(kwsysProcess
* cp
, int index
,
88 kwsysProcessCreateInformation
* si
, int* readEnd
);
89 static int kwsysProcessGetTimeoutTime(kwsysProcess
* cp
, double* userTimeout
,
90 kwsysProcessTime
* timeoutTime
);
91 static int kwsysProcessGetTimeoutLeft(kwsysProcessTime
* timeoutTime
,
92 kwsysProcessTime
* timeoutLength
);
93 static kwsysProcessTime
kwsysProcessTimeGetCurrent();
94 static double kwsysProcessTimeToDouble(kwsysProcessTime t
);
95 static kwsysProcessTime
kwsysProcessTimeFromDouble(double d
);
96 static int kwsysProcessTimeLess(kwsysProcessTime in1
, kwsysProcessTime in2
);
97 static kwsysProcessTime
kwsysProcessTimeAdd(kwsysProcessTime in1
, kwsysProcessTime in2
);
98 static kwsysProcessTime
kwsysProcessTimeSubtract(kwsysProcessTime in1
, kwsysProcessTime in2
);
99 static void kwsysProcessChildErrorExit(int errorPipe
);
100 static void kwsysProcessRestoreDefaultSignalHandlers();
102 /*--------------------------------------------------------------------------*/
103 /* Structure containing data used to implement the child's execution. */
104 struct kwsysProcess_s
106 /* The command lines to execute. */
108 int NumberOfCommands
;
110 /* Descriptors for the read ends of the child's output pipes. */
111 int PipeReadEnds
[KWSYSPE_PIPE_COUNT
];
113 /* Buffer for pipe data. */
114 char PipeBuffer
[KWSYSPE_PIPE_BUFFER_SIZE
];
116 /* Process IDs returned by the calls to fork. */
119 /* Flag for whether the children were terminated by a faild select. */
122 /* The timeout length. */
125 /* The working directory for the process. */
126 char* WorkingDirectory
;
128 /* Time at which the child started. Negative for no timeout. */
129 kwsysProcessTime StartTime
;
131 /* Time at which the child will timeout. Negative for no timeout. */
132 kwsysProcessTime TimeoutTime
;
134 /* Flag for whether the timeout expired. */
137 /* The old SIGCHLD handler. */
138 struct sigaction OldSigChldAction
;
140 /* The number of pipes left open during execution. */
143 /* File descriptor set for call to select. */
146 /* The current status of the child process. */
149 /* The exceptional behavior that terminated the child process, if
153 /* The exit code of the child process. */
156 /* The exit value of the child process, if any. */
159 /* Whether the process was killed. */
162 /* Buffer for error message in case of failure. */
163 char ErrorMessage
[KWSYSPE_PIPE_BUFFER_SIZE
+1];
165 /* The exit codes of each child process in the pipeline. */
166 int* CommandExitCodes
;
169 /*--------------------------------------------------------------------------*/
170 kwsysProcess
* kwsysProcess_New()
172 /* Allocate a process control structure. */
173 kwsysProcess
* cp
= (kwsysProcess
*)malloc(sizeof(kwsysProcess
));
178 memset(cp
, 0, sizeof(kwsysProcess
));
179 cp
->State
= kwsysProcess_State_Starting
;
183 /*--------------------------------------------------------------------------*/
184 void kwsysProcess_Delete(kwsysProcess
* cp
)
186 /* If the process is executing, wait for it to finish. */
187 if(cp
->State
== kwsysProcess_State_Executing
)
189 kwsysProcess_WaitForExit(cp
, 0);
193 kwsysProcess_SetCommand(cp
, 0);
194 kwsysProcess_SetWorkingDirectory(cp
, 0);
195 if(cp
->CommandExitCodes
)
197 free(cp
->CommandExitCodes
);
202 /*--------------------------------------------------------------------------*/
203 int kwsysProcess_SetCommand(kwsysProcess
* cp
, char const* const* command
)
206 for(i
=0; i
< cp
->NumberOfCommands
; ++i
)
208 char** c
= cp
->Commands
[i
];
213 free(cp
->Commands
[i
]);
215 cp
->NumberOfCommands
= 0;
223 return kwsysProcess_AddCommand(cp
, command
);
228 /*--------------------------------------------------------------------------*/
229 int kwsysProcess_AddCommand(kwsysProcess
* cp
, char const* const* command
)
231 int newNumberOfCommands
;
234 /* Make sure we have a command to add. */
240 /* Allocate a new array for command pointers. */
241 newNumberOfCommands
= cp
->NumberOfCommands
+ 1;
242 if(!(newCommands
= (char***)malloc(sizeof(char**) * newNumberOfCommands
)))
248 /* Copy any existing commands into the new array. */
251 for(i
=0; i
< cp
->NumberOfCommands
; ++i
)
253 newCommands
[i
] = cp
->Commands
[i
];
257 /* Add the new command. */
259 char const* const* c
= command
;
264 newCommands
[cp
->NumberOfCommands
] = (char**)malloc((n
+1)*sizeof(char*));
265 if(!newCommands
[cp
->NumberOfCommands
])
273 newCommands
[cp
->NumberOfCommands
][i
] = strdup(command
[i
]);
274 if(!newCommands
[cp
->NumberOfCommands
][i
])
284 free(newCommands
[cp
->NumberOfCommands
][i
-1]);
289 newCommands
[cp
->NumberOfCommands
][n
] = 0;
292 /* Successfully allocated new command array. Free the old array. */
294 cp
->Commands
= newCommands
;
295 cp
->NumberOfCommands
= newNumberOfCommands
;
300 /*--------------------------------------------------------------------------*/
301 void kwsysProcess_SetTimeout(kwsysProcess
* cp
, double timeout
)
303 cp
->Timeout
= timeout
;
310 /*--------------------------------------------------------------------------*/
311 void kwsysProcess_SetWorkingDirectory(kwsysProcess
* cp
, const char* dir
)
313 if(cp
->WorkingDirectory
== dir
)
317 if(cp
->WorkingDirectory
&& dir
&& strcmp(cp
->WorkingDirectory
, dir
) == 0)
321 if(cp
->WorkingDirectory
)
323 free(cp
->WorkingDirectory
);
324 cp
->WorkingDirectory
= 0;
328 cp
->WorkingDirectory
= (char*)malloc(strlen(dir
) + 1);
329 strcpy(cp
->WorkingDirectory
, dir
);
333 /*--------------------------------------------------------------------------*/
334 int kwsysProcess_GetOption(kwsysProcess
* cp
, int optionId
)
341 /*--------------------------------------------------------------------------*/
342 void kwsysProcess_SetOption(kwsysProcess
* cp
, int optionId
, int value
)
349 /*--------------------------------------------------------------------------*/
350 int kwsysProcess_GetState(kwsysProcess
* cp
)
355 /*--------------------------------------------------------------------------*/
356 int kwsysProcess_GetExitException(kwsysProcess
* cp
)
358 return cp
->ExitException
;
361 /*--------------------------------------------------------------------------*/
362 int kwsysProcess_GetExitCode(kwsysProcess
* cp
)
367 /*--------------------------------------------------------------------------*/
368 int kwsysProcess_GetExitValue(kwsysProcess
* cp
)
370 return cp
->ExitValue
;
373 /*--------------------------------------------------------------------------*/
374 const char* kwsysProcess_GetErrorString(kwsysProcess
* cp
)
376 if(cp
->State
== kwsysProcess_State_Error
)
378 return cp
->ErrorMessage
;
383 /*--------------------------------------------------------------------------*/
384 void kwsysProcess_Execute(kwsysProcess
* cp
)
387 struct sigaction newSigChldAction
;
388 kwsysProcessCreateInformation si
= {-1, -1, -1, -1, {-1, -1}};
390 /* Do not execute a second copy simultaneously. */
391 if(cp
->State
== kwsysProcess_State_Executing
)
396 /* Initialize the control structure for a new process. */
397 if(!kwsysProcessInitialize(cp
))
399 strcpy(cp
->ErrorMessage
, "Out of memory");
400 cp
->State
= kwsysProcess_State_Error
;
404 /* We want no special handling of SIGCHLD. Repeat call until it is
406 memset(&newSigChldAction
, 0, sizeof(struct sigaction
));
407 newSigChldAction
.sa_handler
= SIG_DFL
;
408 while((sigaction(SIGCHLD
, &newSigChldAction
, &cp
->OldSigChldAction
) < 0) &&
411 /* Setup the stderr and termination pipes to be shared by all processes. */
412 for(i
=KWSYSPE_PIPE_STDERR
; i
< KWSYSPE_PIPE_COUNT
; ++i
)
414 /* Create the pipe. */
418 kwsysProcessCleanup(cp
, 1);
422 /* Store the pipe. */
423 cp
->PipeReadEnds
[i
] = p
[0];
424 if(i
== KWSYSPE_PIPE_STDERR
)
433 /* Set close-on-exec flag on the pipe's ends. */
434 if((fcntl(p
[0], F_SETFD
, FD_CLOEXEC
) < 0) ||
435 (fcntl(p
[1], F_SETFD
, FD_CLOEXEC
) < 0))
437 kwsysProcessCleanup(cp
, 1);
438 kwsysProcessCleanupDescriptor(&si
.stderr
);
439 kwsysProcessCleanupDescriptor(&si
.term
);
444 /* The timeout period starts now. */
445 cp
->StartTime
= kwsysProcessTimeGetCurrent();
446 cp
->TimeoutTime
.tv_sec
= -1;
447 cp
->TimeoutTime
.tv_usec
= -1;
449 /* Create the pipeline of processes. */
452 for(i
=0; i
< cp
->NumberOfCommands
; ++i
)
454 if(!kwsysProcessCreate(cp
, i
, &si
, &readEnd
))
456 kwsysProcessCleanup(cp
, 1);
458 /* Release resources that may have been allocated for this
459 process before an error occurred. */
460 kwsysProcessCleanupDescriptor(&readEnd
);
463 kwsysProcessCleanupDescriptor(&si
.stdin
);
465 kwsysProcessCleanupDescriptor(&si
.stdout
);
466 kwsysProcessCleanupDescriptor(&si
.stderr
);
467 kwsysProcessCleanupDescriptor(&si
.term
);
468 kwsysProcessCleanupDescriptor(&si
.error
[0]);
469 kwsysProcessCleanupDescriptor(&si
.error
[1]);
473 /* Save a handle to the output pipe for the last process. */
474 cp
->PipeReadEnds
[KWSYSPE_PIPE_STDOUT
] = readEnd
;
477 /* The parent process does not need the output pipe write ends. */
478 kwsysProcessCleanupDescriptor(&si
.stderr
);
479 kwsysProcessCleanupDescriptor(&si
.term
);
481 /* All the pipes are now open. */
482 cp
->PipesLeft
= KWSYSPE_PIPE_COUNT
;
484 /* The process has now started. */
485 cp
->State
= kwsysProcess_State_Executing
;
488 /*--------------------------------------------------------------------------*/
489 int kwsysProcess_WaitForData(kwsysProcess
* cp
, int pipes
, char** data
,
490 int* length
, double* userTimeout
)
494 kwsysProcessTime
* timeout
= 0;
495 kwsysProcessTime timeoutLength
;
496 kwsysProcessTime timeoutTime
;
497 kwsysProcessTime userStartTime
;
503 /* Record the time at which user timeout period starts. */
506 userStartTime
= kwsysProcessTimeGetCurrent();
509 /* Calculate the time at which a timeout will expire, and whether it
510 is the user or process timeout. */
511 user
= kwsysProcessGetTimeoutTime(cp
, userTimeout
, &timeoutTime
);
513 /* Data can only be available when pipes are open. If the process
514 is not running, cp->PipesLeft will be 0. */
515 while(cp
->PipesLeft
> 0)
517 /* Check for any open pipes with data reported ready by the last
519 for(i
=0; i
< KWSYSPE_PIPE_COUNT
; ++i
)
521 if(cp
->PipeReadEnds
[i
] >= 0 &&
522 FD_ISSET(cp
->PipeReadEnds
[i
], &cp
->PipeSet
))
526 /* We are handling this pipe now. Remove it from the set. */
527 FD_CLR(cp
->PipeReadEnds
[i
], &cp
->PipeSet
);
529 /* The pipe is ready to read without blocking. Keep trying to
530 read until the operation is not interrupted. */
531 while(((n
= read(cp
->PipeReadEnds
[i
], cp
->PipeBuffer
,
532 KWSYSPE_PIPE_BUFFER_SIZE
)) < 0) && (errno
== EINTR
));
535 /* We have data on this pipe. */
536 if(i
== KWSYSPE_PIPE_TERM
)
538 /* This is data on the special termination pipe. Ignore it. */
540 else if(pipes
& (1 << i
))
542 /* Caller wants this data. Report it. */
543 *data
= cp
->PipeBuffer
;
551 /* We are done reading from this pipe. */
552 kwsysProcessCleanupDescriptor(&cp
->PipeReadEnds
[i
]);
558 /* If we have data, break early. */
564 /* Make sure the set is empty (it should always be empty here
566 FD_ZERO(&cp
->PipeSet
);
568 /* Add the pipe reading ends that are still open. */
570 for(i
=0; i
< KWSYSPE_PIPE_COUNT
; ++i
)
572 if(cp
->PipeReadEnds
[i
] >= 0)
574 FD_SET(cp
->PipeReadEnds
[i
], &cp
->PipeSet
);
575 if(cp
->PipeReadEnds
[i
] > max
)
577 max
= cp
->PipeReadEnds
[i
];
582 /* Make sure we have a non-empty set. */
585 /* All pipes have closed. Child has terminated. */
589 /* Setup a timeout if required. */
590 if(timeoutTime
.tv_sec
< 0)
596 timeout
= &timeoutLength
;
598 if(kwsysProcessGetTimeoutLeft(&timeoutTime
, &timeoutLength
))
600 /* Timeout has already expired. */
605 /* Run select to block until data are available. Repeat call
606 until it is not interrupted. */
607 while(((numReady
= select(max
+1, &cp
->PipeSet
, 0, 0, timeout
)) < 0) &&
610 /* Check result of select. */
613 /* Select's timeout expired. */
617 else if(numReady
< 0)
619 /* Select returned an error. Leave the error description in the
621 strncpy(cp
->ErrorMessage
, strerror(errno
), KWSYSPE_PIPE_BUFFER_SIZE
);
623 /* Kill the children now. */
624 kwsysProcess_Kill(cp
);
631 /* Update the user timeout. */
634 kwsysProcessTime userEndTime
= kwsysProcessTimeGetCurrent();
635 kwsysProcessTime difference
= kwsysProcessTimeSubtract(userEndTime
,
637 double d
= kwsysProcessTimeToDouble(difference
);
645 /* Check what happened. */
648 /* Data are ready on a pipe. */
653 /* A timeout has expired. */
656 /* The user timeout has expired. It has no time left. */
657 return kwsysProcess_Pipe_Timeout
;
661 /* The process timeout has expired. Kill the children now. */
662 kwsysProcess_Kill(cp
);
664 cp
->TimeoutExpired
= 1;
671 /* No pipes are left open. */
676 /*--------------------------------------------------------------------------*/
677 int kwsysProcess_WaitForExit(kwsysProcess
* cp
, double* userTimeout
)
683 /* Make sure we are executing a process. */
684 if(cp
->State
!= kwsysProcess_State_Executing
)
689 /* Wait for all the pipes to close. Ignore all data. */
690 while((pipe
= kwsysProcess_WaitForData(cp
, 0, 0, 0, userTimeout
)) > 0)
692 if(pipe
== kwsysProcess_Pipe_Timeout
)
698 /* Wait for each child to terminate. The process should have
699 already exited because KWSYSPE_PIPE_TERM has been closed by this
700 point. Repeat the call until it is not interrupted. */
703 for(i
=0; i
< cp
->NumberOfCommands
; ++i
)
705 while(((result
= waitpid(cp
->ForkPIDs
[i
],
706 &cp
->CommandExitCodes
[i
], 0)) < 0) &&
708 if(result
<= 0 && cp
->State
!= kwsysProcess_State_Error
)
710 /* Unexpected error. Report the first time this happens. */
711 strncpy(cp
->ErrorMessage
, strerror(errno
), KWSYSPE_PIPE_BUFFER_SIZE
);
712 cp
->State
= kwsysProcess_State_Error
;
717 /* Check if there was an error in one of the waitpid calls. */
718 if(cp
->State
== kwsysProcess_State_Error
)
720 /* The error message is already in its buffer. Tell
721 kwsysProcessCleanup to not create it. */
722 kwsysProcessCleanup(cp
, 0);
726 /* Check whether the child reported an error invoking the process. */
729 /* The error message is already in its buffer. Tell
730 kwsysProcessCleanup to not create it. */
731 kwsysProcessCleanup(cp
, 0);
732 cp
->State
= kwsysProcess_State_Error
;
736 /* Use the status of the last process in the pipeline. */
737 status
= cp
->CommandExitCodes
[cp
->NumberOfCommands
-1];
739 /* Determine the outcome. */
742 /* We killed the child. */
743 cp
->State
= kwsysProcess_State_Killed
;
745 else if(cp
->TimeoutExpired
)
747 /* The timeout expired. */
748 cp
->State
= kwsysProcess_State_Expired
;
750 else if(WIFEXITED(status
))
752 /* The child exited normally. */
753 cp
->State
= kwsysProcess_State_Exited
;
754 cp
->ExitException
= kwsysProcess_Exception_None
;
755 cp
->ExitCode
= status
;
756 cp
->ExitValue
= (int)WEXITSTATUS(status
);
758 else if(WIFSIGNALED(status
))
760 /* The child received an unhandled signal. */
761 cp
->State
= kwsysProcess_State_Exception
;
762 switch ((int)WTERMSIG(status
))
765 case SIGSEGV
: cp
->ExitException
= kwsysProcess_Exception_Fault
; break;
768 case SIGBUS
: cp
->ExitException
= kwsysProcess_Exception_Fault
; break;
771 case SIGFPE
: cp
->ExitException
= kwsysProcess_Exception_Numerical
; break;
774 case SIGILL
: cp
->ExitException
= kwsysProcess_Exception_Illegal
; break;
777 case SIGINT
: cp
->ExitException
= kwsysProcess_Exception_Interrupt
; break;
779 default: cp
->ExitException
= kwsysProcess_Exception_Other
; break;
781 cp
->ExitCode
= status
;
785 /* Error getting the child return code. */
786 strcpy(cp
->ErrorMessage
, "Error getting child return code.");
787 cp
->State
= kwsysProcess_State_Error
;
790 /* Normal cleanup. */
791 kwsysProcessCleanup(cp
, 0);
795 /*--------------------------------------------------------------------------*/
796 void kwsysProcess_Kill(kwsysProcess
* cp
)
800 /* Make sure we are executing a process. */
801 if(cp
->State
!= kwsysProcess_State_Executing
)
806 /* Kill the children. */
808 for(i
=0; i
< cp
->NumberOfCommands
; ++i
)
812 kill(cp
->ForkPIDs
[i
], SIGKILL
);
817 /*--------------------------------------------------------------------------*/
818 /* Initialize a process control structure for kwsysProcess_Execute. */
819 static int kwsysProcessInitialize(kwsysProcess
* cp
)
822 for(i
=0; i
< KWSYSPE_PIPE_COUNT
; ++i
)
824 cp
->PipeReadEnds
[i
] = -1;
827 cp
->StartTime
.tv_sec
= -1;
828 cp
->StartTime
.tv_usec
= -1;
829 cp
->TimeoutTime
.tv_sec
= -1;
830 cp
->TimeoutTime
.tv_usec
= -1;
831 cp
->TimeoutExpired
= 0;
833 FD_ZERO(&cp
->PipeSet
);
834 cp
->State
= kwsysProcess_State_Starting
;
836 cp
->ExitException
= kwsysProcess_Exception_None
;
839 cp
->ErrorMessage
[0] = 0;
845 cp
->ForkPIDs
= (pid_t
*)malloc(sizeof(pid_t
)*cp
->NumberOfCommands
);
850 memset(cp
->ForkPIDs
, 0, sizeof(pid_t
)*cp
->NumberOfCommands
);
852 if(cp
->CommandExitCodes
)
854 free(cp
->CommandExitCodes
);
856 cp
->CommandExitCodes
= (int*)malloc(sizeof(int)*cp
->NumberOfCommands
);
857 if(!cp
->CommandExitCodes
)
861 memset(cp
->CommandExitCodes
, 0, sizeof(int)*cp
->NumberOfCommands
);
866 /*--------------------------------------------------------------------------*/
867 /* Free all resources used by the given kwsysProcess instance that were
868 allocated by kwsysProcess_Execute. */
869 static void kwsysProcessCleanup(kwsysProcess
* cp
, int error
)
875 /* We are cleaning up due to an error. Report the error message
876 if one has not been provided already. */
877 if(cp
->ErrorMessage
[0] == 0)
879 strncpy(cp
->ErrorMessage
, strerror(errno
), KWSYSPE_PIPE_BUFFER_SIZE
);
882 /* Set the error state. */
883 cp
->State
= kwsysProcess_State_Error
;
885 /* Kill any children already started. */
888 for(i
=0; i
< cp
->NumberOfCommands
; ++i
)
892 kill(cp
->ForkPIDs
[i
], SIGKILL
);
898 /* Restore the SIGCHLD handler. */
899 while((sigaction(SIGCHLD
, &cp
->OldSigChldAction
, 0) < 0) &&
909 /* Close pipe handles. */
910 for(i
=0; i
< KWSYSPE_PIPE_COUNT
; ++i
)
912 kwsysProcessCleanupDescriptor(&cp
->PipeReadEnds
[i
]);
916 /*--------------------------------------------------------------------------*/
917 /* Close the given file descriptor if it is open. Reset its value to -1. */
918 static void kwsysProcessCleanupDescriptor(int* pfd
)
922 /* Keep trying to close until it is not interrupted by a
924 while((close(*pfd
) < 0) && (errno
== EINTR
));
929 /*--------------------------------------------------------------------------*/
930 int kwsysProcessCreate(kwsysProcess
* cp
, int index
,
931 kwsysProcessCreateInformation
* si
, int* readEnd
)
933 /* Setup the process's stdin. */
936 si
->stdin
= *readEnd
;
944 /* Setup the process's stdout. */
946 /* Create the pipe. */
955 /* Set close-on-exec flag on the pipe's ends. */
956 if((fcntl(p
[0], F_SETFD
, FD_CLOEXEC
) < 0) ||
957 (fcntl(p
[1], F_SETFD
, FD_CLOEXEC
) < 0))
963 /* Create the error reporting pipe. */
964 if(pipe(si
->error
) < 0)
969 /* Set close-on-exec flag on the error pipe's write end. */
970 if(fcntl(si
->error
[1], F_SETFD
, FD_CLOEXEC
) < 0)
975 /* Fork off a child process. */
976 cp
->ForkPIDs
[index
] = fork();
977 if(cp
->ForkPIDs
[index
] < 0)
982 if(cp
->ForkPIDs
[index
] == 0)
984 /* Close the read end of the error reporting pipe. */
987 /* Setup the stdin, stdout, and stderr pipes. */
995 /* Clear the close-on-exec flag for stdin, stdout, and stderr.
996 Also clear it for the termination pipe. All other pipe handles
997 will be closed when exec succeeds. */
998 fcntl(0, F_SETFD
, 0);
999 fcntl(1, F_SETFD
, 0);
1000 fcntl(2, F_SETFD
, 0);
1001 fcntl(si
->term
, F_SETFD
, 0);
1003 /* Restore all default signal handlers. */
1004 kwsysProcessRestoreDefaultSignalHandlers();
1006 /* Change to the working directory specified, if any. */
1007 if(cp
->WorkingDirectory
)
1009 /* Some platforms specify that the chdir call may be
1010 interrupted. Repeat the call until it finishes. */
1012 while(((r
= chdir(cp
->WorkingDirectory
)) < 0) && (errno
== EINTR
));
1015 /* Failure. Report error to parent and terminate. */
1016 kwsysProcessChildErrorExit(si
->error
[1]);
1020 /* Execute the real process. If successful, this does not return. */
1021 execvp(cp
->Commands
[index
][0], cp
->Commands
[index
]);
1023 /* Failure. Report error to parent and terminate. */
1024 kwsysProcessChildErrorExit(si
->error
[1]);
1027 /* We are done with the error reporting pipe write end. */
1028 kwsysProcessCleanupDescriptor(&si
->error
[1]);
1030 /* Block until the child's exec call succeeds and closes the error
1031 pipe or writes data to the pipe to report an error. */
1035 /* Read the entire error message up to the length of our buffer. */
1036 while(total
< KWSYSPE_PIPE_BUFFER_SIZE
&& n
> 0)
1038 /* Keep trying to read until the operation is not interrupted. */
1039 while(((n
= read(si
->error
[0], cp
->ErrorMessage
+total
,
1040 KWSYSPE_PIPE_BUFFER_SIZE
-total
)) < 0) &&
1048 /* We are done with the error reporting pipe read end. */
1049 kwsysProcessCleanupDescriptor(&si
->error
[0]);
1053 /* The child failed to execute the process. */
1058 /* Successfully created this child process. */
1061 /* The parent process does not need the input pipe read end. */
1062 kwsysProcessCleanupDescriptor(&si
->stdin
);
1065 /* The parent process does not need the output pipe write ends. */
1066 kwsysProcessCleanupDescriptor(&si
->stdout
);
1071 /*--------------------------------------------------------------------------*/
1072 /* Get the time at which either the process or user timeout will
1073 expire. Returns 1 if the user timeout is first, and 0 otherwise. */
1074 static int kwsysProcessGetTimeoutTime(kwsysProcess
* cp
, double* userTimeout
,
1075 kwsysProcessTime
* timeoutTime
)
1077 /* The first time this is called, we need to calculate the time at
1078 which the child will timeout. */
1079 if(cp
->Timeout
&& cp
->TimeoutTime
.tv_sec
< 0)
1081 kwsysProcessTime length
= kwsysProcessTimeFromDouble(cp
->Timeout
);
1082 cp
->TimeoutTime
= kwsysProcessTimeAdd(cp
->StartTime
, length
);
1085 /* Start with process timeout. */
1086 *timeoutTime
= cp
->TimeoutTime
;
1088 /* Check if the user timeout is earlier. */
1091 kwsysProcessTime currentTime
= kwsysProcessTimeGetCurrent();
1092 kwsysProcessTime userTimeoutLength
= kwsysProcessTimeFromDouble(*userTimeout
);
1093 kwsysProcessTime userTimeoutTime
= kwsysProcessTimeAdd(currentTime
,
1095 if(kwsysProcessTimeLess(userTimeoutTime
, *timeoutTime
))
1097 *timeoutTime
= userTimeoutTime
;
1104 /*--------------------------------------------------------------------------*/
1105 /* Get the length of time before the given timeout time arrives.
1106 Returns 1 if the time has already arrived, and 0 otherwise. */
1107 static int kwsysProcessGetTimeoutLeft(kwsysProcessTime
* timeoutTime
,
1108 kwsysProcessTime
* timeoutLength
)
1110 if(timeoutTime
->tv_sec
< 0)
1112 /* No timeout time has been requested. */
1117 /* Calculate the remaining time. */
1118 kwsysProcessTime currentTime
= kwsysProcessTimeGetCurrent();
1119 *timeoutLength
= kwsysProcessTimeSubtract(*timeoutTime
, currentTime
);
1120 if(timeoutLength
->tv_sec
< 0)
1122 /* Timeout has already expired. */
1127 /* There is some time left. */
1133 /*--------------------------------------------------------------------------*/
1134 static kwsysProcessTime
kwsysProcessTimeGetCurrent()
1136 kwsysProcessTime current
;
1137 gettimeofday(¤t
, 0);
1141 /*--------------------------------------------------------------------------*/
1142 static double kwsysProcessTimeToDouble(kwsysProcessTime t
)
1144 return (double)t
.tv_sec
+ t
.tv_usec
*0.000001;
1147 /*--------------------------------------------------------------------------*/
1148 static kwsysProcessTime
kwsysProcessTimeFromDouble(double d
)
1152 t
.tv_usec
= (long)((d
-t
.tv_sec
)*1000000);
1156 /*--------------------------------------------------------------------------*/
1157 static int kwsysProcessTimeLess(kwsysProcessTime in1
, kwsysProcessTime in2
)
1159 return ((in1
.tv_sec
< in2
.tv_sec
) ||
1160 ((in1
.tv_sec
== in2
.tv_sec
) && (in1
.tv_usec
< in2
.tv_usec
)));
1163 /*--------------------------------------------------------------------------*/
1164 static kwsysProcessTime
kwsysProcessTimeAdd(kwsysProcessTime in1
, kwsysProcessTime in2
)
1166 kwsysProcessTime out
;
1167 out
.tv_sec
= in1
.tv_sec
+ in2
.tv_sec
;
1168 out
.tv_usec
= in1
.tv_usec
+ in2
.tv_usec
;
1169 if(out
.tv_usec
> 1000000)
1171 out
.tv_usec
-= 1000000;
1177 /*--------------------------------------------------------------------------*/
1178 static kwsysProcessTime
kwsysProcessTimeSubtract(kwsysProcessTime in1
, kwsysProcessTime in2
)
1180 kwsysProcessTime out
;
1181 out
.tv_sec
= in1
.tv_sec
- in2
.tv_sec
;
1182 out
.tv_usec
= in1
.tv_usec
- in2
.tv_usec
;
1185 out
.tv_usec
+= 1000000;
1191 /*--------------------------------------------------------------------------*/
1192 /* When the child process encounters an error before its program is
1193 invoked, this is called to report the error to the parent and
1195 static void kwsysProcessChildErrorExit(int errorPipe
)
1197 /* Construct the error message. */
1198 char buffer
[KWSYSPE_PIPE_BUFFER_SIZE
];
1199 strncpy(buffer
, strerror(errno
), KWSYSPE_PIPE_BUFFER_SIZE
);
1201 /* Report the error to the parent through the special pipe. */
1202 write(errorPipe
, buffer
, strlen(buffer
));
1204 /* Terminate without cleanup. */
1208 /*--------------------------------------------------------------------------*/
1209 /* Restores all signal handlers to their default values. */
1210 static void kwsysProcessRestoreDefaultSignalHandlers()
1212 struct sigaction act
;
1213 memset(&act
, 0, sizeof(struct sigaction
));
1214 act
.sa_handler
= SIG_DFL
;
1216 sigaction(SIGHUP
, &act
, 0);
1219 sigaction(SIGINT
, &act
, 0);
1222 sigaction(SIGQUIT
, &act
, 0);
1225 sigaction(SIGILL
, &act
, 0);
1228 sigaction(SIGTRAP
, &act
, 0);
1231 sigaction(SIGABRT
, &act
, 0);
1234 sigaction(SIGIOT
, &act
, 0);
1237 sigaction(SIGBUS
, &act
, 0);
1240 sigaction(SIGFPE
, &act
, 0);
1243 sigaction(SIGUSR1
, &act
, 0);
1246 sigaction(SIGSEGV
, &act
, 0);
1249 sigaction(SIGUSR2
, &act
, 0);
1252 sigaction(SIGPIPE
, &act
, 0);
1255 sigaction(SIGALRM
, &act
, 0);
1258 sigaction(SIGTERM
, &act
, 0);
1261 sigaction(SIGSTKFLT
, &act
, 0);
1264 sigaction(SIGCLD
, &act
, 0);
1267 sigaction(SIGCHLD
, &act
, 0);
1270 sigaction(SIGCONT
, &act
, 0);
1273 sigaction(SIGTSTP
, &act
, 0);
1276 sigaction(SIGTTIN
, &act
, 0);
1279 sigaction(SIGTTOU
, &act
, 0);
1282 sigaction(SIGURG
, &act
, 0);
1285 sigaction(SIGXCPU
, &act
, 0);
1288 sigaction(SIGXFSZ
, &act
, 0);
1291 sigaction(SIGVTALRM
, &act
, 0);
1294 sigaction(SIGPROF
, &act
, 0);
1297 sigaction(SIGWINCH
, &act
, 0);
1300 sigaction(SIGPOLL
, &act
, 0);
1303 sigaction(SIGIO
, &act
, 0);
1306 sigaction(SIGPWR
, &act
, 0);
1309 sigaction(SIGSYS
, &act
, 0);
1312 sigaction(SIGUNUSED
, &act
, 0);