11#include "cache.h"
22#include "run-command.h"
33#include "exec_cmd.h"
4+ #include "sigchain.h"
45#include "argv-array.h"
56
7+ struct child_to_clean {
8+ pid_t pid ;
9+ struct child_to_clean * next ;
10+ };
11+ static struct child_to_clean * children_to_clean ;
12+ static int installed_child_cleanup_handler ;
13+
14+ static void cleanup_children (int sig )
15+ {
16+ while (children_to_clean ) {
17+ struct child_to_clean * p = children_to_clean ;
18+ children_to_clean = p -> next ;
19+ kill (p -> pid , sig );
20+ free (p );
21+ }
22+ }
23+
24+ static void cleanup_children_on_signal (int sig )
25+ {
26+ cleanup_children (sig );
27+ sigchain_pop (sig );
28+ raise (sig );
29+ }
30+
31+ static void cleanup_children_on_exit (void )
32+ {
33+ cleanup_children (SIGTERM );
34+ }
35+
36+ static void mark_child_for_cleanup (pid_t pid )
37+ {
38+ struct child_to_clean * p = xmalloc (sizeof (* p ));
39+ p -> pid = pid ;
40+ p -> next = children_to_clean ;
41+ children_to_clean = p ;
42+
43+ if (!installed_child_cleanup_handler ) {
44+ atexit (cleanup_children_on_exit );
45+ sigchain_push_common (cleanup_children_on_signal );
46+ installed_child_cleanup_handler = 1 ;
47+ }
48+ }
49+
50+ static void clear_child_for_cleanup (pid_t pid )
51+ {
52+ struct child_to_clean * * last , * p ;
53+
54+ last = & children_to_clean ;
55+ for (p = children_to_clean ; p ; p = p -> next ) {
56+ if (p -> pid == pid ) {
57+ * last = p -> next ;
58+ free (p );
59+ return ;
60+ }
61+ }
62+ }
63+
664static inline void close_pair (int fd [2 ])
765{
866 close (fd [0 ]);
@@ -130,6 +188,9 @@ static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure)
130188 } else {
131189 error ("waitpid is confused (%s)" , argv0 );
132190 }
191+
192+ clear_child_for_cleanup (pid );
193+
133194 errno = failed_errno ;
134195 return code ;
135196}
@@ -292,6 +353,8 @@ int start_command(struct child_process *cmd)
292353 if (cmd -> pid < 0 )
293354 error ("cannot fork() for %s: %s" , cmd -> argv [0 ],
294355 strerror (failed_errno = errno ));
356+ else if (cmd -> clean_on_exit )
357+ mark_child_for_cleanup (cmd -> pid );
295358
296359 /*
297360 * Wait for child's execvp. If the execvp succeeds (or if fork()
@@ -312,6 +375,7 @@ int start_command(struct child_process *cmd)
312375 cmd -> pid = -1 ;
313376 }
314377 close (notify_pipe [0 ]);
378+
315379}
316380#else
317381{
@@ -356,6 +420,8 @@ int start_command(struct child_process *cmd)
356420 failed_errno = errno ;
357421 if (cmd -> pid < 0 && (!cmd -> silent_exec_failure || errno != ENOENT ))
358422 error ("cannot spawn %s: %s" , cmd -> argv [0 ], strerror (errno ));
423+ if (cmd -> clean_on_exit && cmd -> pid >= 0 )
424+ mark_child_for_cleanup (cmd -> pid );
359425
360426 if (cmd -> env )
361427 free_environ (env );
@@ -431,6 +497,7 @@ static void prepare_run_command_v_opt(struct child_process *cmd,
431497 cmd -> stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0 ;
432498 cmd -> silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0 ;
433499 cmd -> use_shell = opt & RUN_USING_SHELL ? 1 : 0 ;
500+ cmd -> clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0 ;
434501}
435502
436503int run_command_v_opt (const char * * argv , int opt )
@@ -540,6 +607,8 @@ int start_async(struct async *async)
540607 exit (!!async -> proc (proc_in , proc_out , async -> data ));
541608 }
542609
610+ mark_child_for_cleanup (async -> pid );
611+
543612 if (need_in )
544613 close (fdin [0 ]);
545614 else if (async -> in )
0 commit comments