1 /* Waiting for a subprocess to finish. 2 Copyright (C) 2001-2003, 2005-2012 Free Software Foundation, Inc. 3 Written by Bruno Haible <haible (at) clisp.cons.org>, 2001. 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 19 #include <config.h> 20 21 /* Specification. */ 22 #include "wait-process.h" 23 24 #include <errno.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <signal.h> 28 29 #include <sys/types.h> 30 #include <sys/wait.h> 31 32 #include "error.h" 33 #include "fatal-signal.h" 34 #include "xalloc.h" 35 #include "gettext.h" 36 37 #define _(str) gettext (str) 38 39 #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) 40 41 42 #if defined _MSC_VER || defined __MINGW32__ 43 44 #define WIN32_LEAN_AND_MEAN 45 #include <windows.h> 46 47 /* The return value of spawnvp() is really a process handle as returned 48 by CreateProcess(). Therefore we can kill it using TerminateProcess. */ 49 #define kill(pid,sig) TerminateProcess ((HANDLE) (pid), sig) 50 51 #endif 52 53 54 /* Type of an entry in the slaves array. 55 The 'used' bit determines whether this entry is currently in use. 56 (If pid_t was an atomic type like sig_atomic_t, we could just set the 57 'child' field to 0 when unregistering a slave process, and wouldn't need 58 the 'used' field.) 59 The 'used' and 'child' fields are accessed from within the cleanup_slaves() 60 action, therefore we mark them as 'volatile'. */ 61 typedef struct 62 { 63 volatile sig_atomic_t used; 64 volatile pid_t child; 65 } 66 slaves_entry_t; 67 68 /* The registered slave subprocesses. */ 69 static slaves_entry_t static_slaves[32]; 70 static slaves_entry_t * volatile slaves = static_slaves; 71 static sig_atomic_t volatile slaves_count = 0; 72 static size_t slaves_allocated = SIZEOF (static_slaves); 73 74 /* The termination signal for slave subprocesses. 75 2003-10-07: Terminator becomes Governator. */ 76 #ifdef SIGHUP 77 # define TERMINATOR SIGHUP 78 #else 79 # define TERMINATOR SIGTERM 80 #endif 81 82 /* The cleanup action. It gets called asynchronously. */ 83 static void 84 cleanup_slaves (void) 85 { 86 for (;;) 87 { 88 /* Get the last registered slave. */ 89 size_t n = slaves_count; 90 if (n == 0) 91 break; 92 n--; 93 slaves_count = n; 94 /* Skip unused entries in the slaves array. */ 95 if (slaves[n].used) 96 { 97 pid_t slave = slaves[n].child; 98 99 /* Kill the slave. */ 100 kill (slave, TERMINATOR); 101 } 102 } 103 } 104 105 /* Register a subprocess as being a slave process. This means that the 106 subprocess will be terminated when its creator receives a catchable fatal 107 signal or exits normally. Registration ends when wait_subprocess() 108 notices that the subprocess has exited. */ 109 void 110 register_slave_subprocess (pid_t child) 111 { 112 static bool cleanup_slaves_registered = false; 113 if (!cleanup_slaves_registered) 114 { 115 atexit (cleanup_slaves); 116 at_fatal_signal (cleanup_slaves); 117 cleanup_slaves_registered = true; 118 } 119 120 /* Try to store the new slave in an unused entry of the slaves array. */ 121 { 122 slaves_entry_t *s = slaves; 123 slaves_entry_t *s_end = s + slaves_count; 124 125 for (; s < s_end; s++) 126 if (!s->used) 127 { 128 /* The two uses of 'volatile' in the slaves_entry_t type above 129 (and ISO C 99 section 5.1.2.3.(5)) ensure that we mark the 130 entry as used only after the child pid has been written to the 131 memory location s->child. */ 132 s->child = child; 133 s->used = 1; 134 return; 135 } 136 } 137 138 if (slaves_count == slaves_allocated) 139 { 140 /* Extend the slaves array. Note that we cannot use xrealloc(), 141 because then the cleanup_slaves() function could access an already 142 deallocated array. */ 143 slaves_entry_t *old_slaves = slaves; 144 size_t new_slaves_allocated = 2 * slaves_allocated; 145 slaves_entry_t *new_slaves = 146 (slaves_entry_t *) 147 malloc (new_slaves_allocated * sizeof (slaves_entry_t)); 148 if (new_slaves == NULL) 149 { 150 /* xalloc_die() will call exit() which will invoke cleanup_slaves(). 151 Additionally we need to kill child, because it's not yet among 152 the slaves list. */ 153 kill (child, TERMINATOR); 154 xalloc_die (); 155 } 156 memcpy (new_slaves, old_slaves, 157 slaves_allocated * sizeof (slaves_entry_t)); 158 slaves = new_slaves; 159 slaves_allocated = new_slaves_allocated; 160 /* Now we can free the old slaves array. */ 161 if (old_slaves != static_slaves) 162 free (old_slaves); 163 } 164 /* The three uses of 'volatile' in the types above (and ISO C 99 section 165 5.1.2.3.(5)) ensure that we increment the slaves_count only after the 166 new slave and its 'used' bit have been written to the memory locations 167 that make up slaves[slaves_count]. */ 168 slaves[slaves_count].child = child; 169 slaves[slaves_count].used = 1; 170 slaves_count++; 171 } 172 173 /* Unregister a child from the list of slave subprocesses. */ 174 static void 175 unregister_slave_subprocess (pid_t child) 176 { 177 /* The easiest way to remove an entry from a list that can be used by 178 an asynchronous signal handler is just to mark it as unused. For this, 179 we rely on sig_atomic_t. */ 180 slaves_entry_t *s = slaves; 181 slaves_entry_t *s_end = s + slaves_count; 182 183 for (; s < s_end; s++) 184 if (s->used && s->child == child) 185 s->used = 0; 186 } 187 188 189 /* Wait for a subprocess to finish. Return its exit code. 190 If it didn't terminate correctly, exit if exit_on_error is true, otherwise 191 return 127. */ 192 int 193 wait_subprocess (pid_t child, const char *progname, 194 bool ignore_sigpipe, bool null_stderr, 195 bool slave_process, bool exit_on_error, 196 int *termsigp) 197 { 198 #if HAVE_WAITID && defined WNOWAIT && 0 199 /* Commented out because waitid() without WEXITED and with WNOWAIT doesn't 200 work: On Solaris 7 and OSF/1 4.0, it returns -1 and sets errno = ECHILD, 201 and on HP-UX 10.20 it just hangs. */ 202 /* Use of waitid() with WNOWAIT avoids a race condition: If slave_process is 203 true, and this process sleeps a very long time between the return from 204 waitpid() and the execution of unregister_slave_subprocess(), and 205 meanwhile another process acquires the same PID as child, and then - still 206 before unregister_slave_subprocess() - this process gets a fatal signal, 207 it would kill the other totally unrelated process. */ 208 siginfo_t info; 209 210 if (termsigp != NULL) 211 *termsigp = 0; 212 for (;;) 213 { 214 if (waitid (P_PID, child, &info, WEXITED | (slave_process ? WNOWAIT : 0)) 215 < 0) 216 { 217 # ifdef EINTR 218 if (errno == EINTR) 219 continue; 220 # endif 221 if (exit_on_error || !null_stderr) 222 error (exit_on_error ? EXIT_FAILURE : 0, errno, 223 _("%s subprocess"), progname); 224 return 127; 225 } 226 227 /* info.si_code is set to one of CLD_EXITED, CLD_KILLED, CLD_DUMPED, 228 CLD_TRAPPED, CLD_STOPPED, CLD_CONTINUED. Loop until the program 229 terminates. */ 230 if (info.si_code == CLD_EXITED 231 || info.si_code == CLD_KILLED || info.si_code == CLD_DUMPED) 232 break; 233 } 234 235 /* The child process has exited or was signalled. */ 236 237 if (slave_process) 238 { 239 /* Unregister the child from the list of slave subprocesses, so that 240 later, when we exit, we don't kill a totally unrelated process which 241 may have acquired the same pid. */ 242 unregister_slave_subprocess (child); 243 244 /* Now remove the zombie from the process list. */ 245 for (;;) 246 { 247 if (waitid (P_PID, child, &info, WEXITED) < 0) 248 { 249 # ifdef EINTR 250 if (errno == EINTR) 251 continue; 252 # endif 253 if (exit_on_error || !null_stderr) 254 error (exit_on_error ? EXIT_FAILURE : 0, errno, 255 _("%s subprocess"), progname); 256 return 127; 257 } 258 break; 259 } 260 } 261 262 switch (info.si_code) 263 { 264 case CLD_KILLED: 265 case CLD_DUMPED: 266 if (termsigp != NULL) 267 *termsigp = info.si_status; /* TODO: or info.si_signo? */ 268 # ifdef SIGPIPE 269 if (info.si_status == SIGPIPE && ignore_sigpipe) 270 return 0; 271 # endif 272 if (exit_on_error || (!null_stderr && termsigp == NULL)) 273 error (exit_on_error ? EXIT_FAILURE : 0, 0, 274 _("%s subprocess got fatal signal %d"), 275 progname, info.si_status); 276 return 127; 277 case CLD_EXITED: 278 if (info.si_status == 127) 279 { 280 if (exit_on_error || !null_stderr) 281 error (exit_on_error ? EXIT_FAILURE : 0, 0, 282 _("%s subprocess failed"), progname); 283 return 127; 284 } 285 return info.si_status; 286 default: 287 abort (); 288 } 289 #else 290 /* waitpid() is just as portable as wait() nowadays. */ 291 int status; 292 293 if (termsigp != NULL) 294 *termsigp = 0; 295 status = 0; 296 for (;;) 297 { 298 int result = waitpid (child, &status, 0); 299 300 if (result != child) 301 { 302 # ifdef EINTR 303 if (errno == EINTR) 304 continue; 305 # endif 306 # if 0 /* defined ECHILD */ 307 if (errno == ECHILD) 308 { 309 /* Child process nonexistent?! Assume it terminated 310 successfully. */ 311 status = 0; 312 break; 313 } 314 # endif 315 if (exit_on_error || !null_stderr) 316 error (exit_on_error ? EXIT_FAILURE : 0, errno, 317 _("%s subprocess"), progname); 318 return 127; 319 } 320 321 /* One of WIFSIGNALED (status), WIFEXITED (status), WIFSTOPPED (status) 322 must always be true, since we did not specify WCONTINUED in the 323 waitpid() call. Loop until the program terminates. */ 324 if (!WIFSTOPPED (status)) 325 break; 326 } 327 328 /* The child process has exited or was signalled. */ 329 330 if (slave_process) 331 /* Unregister the child from the list of slave subprocesses, so that 332 later, when we exit, we don't kill a totally unrelated process which 333 may have acquired the same pid. */ 334 unregister_slave_subprocess (child); 335 336 if (WIFSIGNALED (status)) 337 { 338 if (termsigp != NULL) 339 *termsigp = WTERMSIG (status); 340 # ifdef SIGPIPE 341 if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe) 342 return 0; 343 # endif 344 if (exit_on_error || (!null_stderr && termsigp == NULL)) 345 error (exit_on_error ? EXIT_FAILURE : 0, 0, 346 _("%s subprocess got fatal signal %d"), 347 progname, (int) WTERMSIG (status)); 348 return 127; 349 } 350 if (!WIFEXITED (status)) 351 abort (); 352 if (WEXITSTATUS (status) == 127) 353 { 354 if (exit_on_error || !null_stderr) 355 error (exit_on_error ? EXIT_FAILURE : 0, 0, 356 _("%s subprocess failed"), progname); 357 return 127; 358 } 359 return WEXITSTATUS (status); 360 #endif 361 } 362