1 | /* Waiting for a subprocess to finish. |
2 | Copyright (C) 2001-2003, 2005-2019 Free Software Foundation, Inc. |
3 | Written by Bruno Haible <haible@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 <https://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 _WIN32 && ! defined __CYGWIN__ |
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 _GL_ASYNC_SAFE 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 | /* The cleanup action, taking a signal argument. |
106 | It gets called asynchronously. */ |
107 | static _GL_ASYNC_SAFE void |
108 | cleanup_slaves_action (int sig _GL_UNUSED) |
109 | { |
110 | cleanup_slaves (); |
111 | } |
112 | |
113 | /* Register a subprocess as being a slave process. This means that the |
114 | subprocess will be terminated when its creator receives a catchable fatal |
115 | signal or exits normally. Registration ends when wait_subprocess() |
116 | notices that the subprocess has exited. */ |
117 | void |
118 | register_slave_subprocess (pid_t child) |
119 | { |
120 | static bool cleanup_slaves_registered = false; |
121 | if (!cleanup_slaves_registered) |
122 | { |
123 | atexit (cleanup_slaves); |
124 | at_fatal_signal (cleanup_slaves_action); |
125 | cleanup_slaves_registered = true; |
126 | } |
127 | |
128 | /* Try to store the new slave in an unused entry of the slaves array. */ |
129 | { |
130 | slaves_entry_t *s = slaves; |
131 | slaves_entry_t *s_end = s + slaves_count; |
132 | |
133 | for (; s < s_end; s++) |
134 | if (!s->used) |
135 | { |
136 | /* The two uses of 'volatile' in the slaves_entry_t type above |
137 | (and ISO C 99 section 5.1.2.3.(5)) ensure that we mark the |
138 | entry as used only after the child pid has been written to the |
139 | memory location s->child. */ |
140 | s->child = child; |
141 | s->used = 1; |
142 | return; |
143 | } |
144 | } |
145 | |
146 | if (slaves_count == slaves_allocated) |
147 | { |
148 | /* Extend the slaves array. Note that we cannot use xrealloc(), |
149 | because then the cleanup_slaves() function could access an already |
150 | deallocated array. */ |
151 | slaves_entry_t *old_slaves = slaves; |
152 | size_t new_slaves_allocated = 2 * slaves_allocated; |
153 | slaves_entry_t *new_slaves = |
154 | (slaves_entry_t *) |
155 | malloc (new_slaves_allocated * sizeof (slaves_entry_t)); |
156 | if (new_slaves == NULL) |
157 | { |
158 | /* xalloc_die() will call exit() which will invoke cleanup_slaves(). |
159 | Additionally we need to kill child, because it's not yet among |
160 | the slaves list. */ |
161 | kill (child, TERMINATOR); |
162 | xalloc_die (); |
163 | } |
164 | memcpy (new_slaves, old_slaves, |
165 | slaves_allocated * sizeof (slaves_entry_t)); |
166 | slaves = new_slaves; |
167 | slaves_allocated = new_slaves_allocated; |
168 | /* Now we can free the old slaves array. */ |
169 | if (old_slaves != static_slaves) |
170 | free (old_slaves); |
171 | } |
172 | /* The three uses of 'volatile' in the types above (and ISO C 99 section |
173 | 5.1.2.3.(5)) ensure that we increment the slaves_count only after the |
174 | new slave and its 'used' bit have been written to the memory locations |
175 | that make up slaves[slaves_count]. */ |
176 | slaves[slaves_count].child = child; |
177 | slaves[slaves_count].used = 1; |
178 | slaves_count++; |
179 | } |
180 | |
181 | /* Unregister a child from the list of slave subprocesses. */ |
182 | static void |
183 | unregister_slave_subprocess (pid_t child) |
184 | { |
185 | /* The easiest way to remove an entry from a list that can be used by |
186 | an asynchronous signal handler is just to mark it as unused. For this, |
187 | we rely on sig_atomic_t. */ |
188 | slaves_entry_t *s = slaves; |
189 | slaves_entry_t *s_end = s + slaves_count; |
190 | |
191 | for (; s < s_end; s++) |
192 | if (s->used && s->child == child) |
193 | s->used = 0; |
194 | } |
195 | |
196 | |
197 | /* Wait for a subprocess to finish. Return its exit code. |
198 | If it didn't terminate correctly, exit if exit_on_error is true, otherwise |
199 | return 127. */ |
200 | int |
201 | wait_subprocess (pid_t child, const char *progname, |
202 | bool ignore_sigpipe, bool null_stderr, |
203 | bool slave_process, bool exit_on_error, |
204 | int *termsigp) |
205 | { |
206 | #if HAVE_WAITID && defined WNOWAIT && 0 |
207 | /* Commented out because waitid() without WEXITED and with WNOWAIT doesn't |
208 | work: On Solaris 7 and OSF/1 4.0, it returns -1 and sets errno = ECHILD, |
209 | and on HP-UX 10.20 it just hangs. */ |
210 | /* Use of waitid() with WNOWAIT avoids a race condition: If slave_process is |
211 | true, and this process sleeps a very long time between the return from |
212 | waitpid() and the execution of unregister_slave_subprocess(), and |
213 | meanwhile another process acquires the same PID as child, and then - still |
214 | before unregister_slave_subprocess() - this process gets a fatal signal, |
215 | it would kill the other totally unrelated process. */ |
216 | siginfo_t info; |
217 | |
218 | if (termsigp != NULL) |
219 | *termsigp = 0; |
220 | for (;;) |
221 | { |
222 | if (waitid (P_PID, child, &info, WEXITED | (slave_process ? WNOWAIT : 0)) |
223 | < 0) |
224 | { |
225 | # ifdef EINTR |
226 | if (errno == EINTR) |
227 | continue; |
228 | # endif |
229 | if (exit_on_error || !null_stderr) |
230 | error (exit_on_error ? EXIT_FAILURE : 0, errno, |
231 | _("%s subprocess" ), progname); |
232 | return 127; |
233 | } |
234 | |
235 | /* info.si_code is set to one of CLD_EXITED, CLD_KILLED, CLD_DUMPED, |
236 | CLD_TRAPPED, CLD_STOPPED, CLD_CONTINUED. Loop until the program |
237 | terminates. */ |
238 | if (info.si_code == CLD_EXITED |
239 | || info.si_code == CLD_KILLED || info.si_code == CLD_DUMPED) |
240 | break; |
241 | } |
242 | |
243 | /* The child process has exited or was signalled. */ |
244 | |
245 | if (slave_process) |
246 | { |
247 | /* Unregister the child from the list of slave subprocesses, so that |
248 | later, when we exit, we don't kill a totally unrelated process which |
249 | may have acquired the same pid. */ |
250 | unregister_slave_subprocess (child); |
251 | |
252 | /* Now remove the zombie from the process list. */ |
253 | for (;;) |
254 | { |
255 | if (waitid (P_PID, child, &info, WEXITED) < 0) |
256 | { |
257 | # ifdef EINTR |
258 | if (errno == EINTR) |
259 | continue; |
260 | # endif |
261 | if (exit_on_error || !null_stderr) |
262 | error (exit_on_error ? EXIT_FAILURE : 0, errno, |
263 | _("%s subprocess" ), progname); |
264 | return 127; |
265 | } |
266 | break; |
267 | } |
268 | } |
269 | |
270 | switch (info.si_code) |
271 | { |
272 | case CLD_KILLED: |
273 | case CLD_DUMPED: |
274 | if (termsigp != NULL) |
275 | *termsigp = info.si_status; /* TODO: or info.si_signo? */ |
276 | # ifdef SIGPIPE |
277 | if (info.si_status == SIGPIPE && ignore_sigpipe) |
278 | return 0; |
279 | # endif |
280 | if (exit_on_error || (!null_stderr && termsigp == NULL)) |
281 | error (exit_on_error ? EXIT_FAILURE : 0, 0, |
282 | _("%s subprocess got fatal signal %d" ), |
283 | progname, info.si_status); |
284 | return 127; |
285 | case CLD_EXITED: |
286 | if (info.si_status == 127) |
287 | { |
288 | if (exit_on_error || !null_stderr) |
289 | error (exit_on_error ? EXIT_FAILURE : 0, 0, |
290 | _("%s subprocess failed" ), progname); |
291 | return 127; |
292 | } |
293 | return info.si_status; |
294 | default: |
295 | abort (); |
296 | } |
297 | #else |
298 | /* waitpid() is just as portable as wait() nowadays. */ |
299 | int status; |
300 | |
301 | if (termsigp != NULL) |
302 | *termsigp = 0; |
303 | status = 0; |
304 | for (;;) |
305 | { |
306 | int result = waitpid (child, &status, 0); |
307 | |
308 | if (result != child) |
309 | { |
310 | # ifdef EINTR |
311 | if (errno == EINTR) |
312 | continue; |
313 | # endif |
314 | # if 0 /* defined ECHILD */ |
315 | if (errno == ECHILD) |
316 | { |
317 | /* Child process nonexistent?! Assume it terminated |
318 | successfully. */ |
319 | status = 0; |
320 | break; |
321 | } |
322 | # endif |
323 | if (exit_on_error || !null_stderr) |
324 | error (exit_on_error ? EXIT_FAILURE : 0, errno, |
325 | _("%s subprocess" ), progname); |
326 | return 127; |
327 | } |
328 | |
329 | /* One of WIFSIGNALED (status), WIFEXITED (status), WIFSTOPPED (status) |
330 | must always be true, since we did not specify WCONTINUED in the |
331 | waitpid() call. Loop until the program terminates. */ |
332 | if (!WIFSTOPPED (status)) |
333 | break; |
334 | } |
335 | |
336 | /* The child process has exited or was signalled. */ |
337 | |
338 | if (slave_process) |
339 | /* Unregister the child from the list of slave subprocesses, so that |
340 | later, when we exit, we don't kill a totally unrelated process which |
341 | may have acquired the same pid. */ |
342 | unregister_slave_subprocess (child); |
343 | |
344 | if (WIFSIGNALED (status)) |
345 | { |
346 | if (termsigp != NULL) |
347 | *termsigp = WTERMSIG (status); |
348 | # ifdef SIGPIPE |
349 | if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe) |
350 | return 0; |
351 | # endif |
352 | if (exit_on_error || (!null_stderr && termsigp == NULL)) |
353 | error (exit_on_error ? EXIT_FAILURE : 0, 0, |
354 | _("%s subprocess got fatal signal %d" ), |
355 | progname, (int) WTERMSIG (status)); |
356 | return 127; |
357 | } |
358 | if (!WIFEXITED (status)) |
359 | abort (); |
360 | if (WEXITSTATUS (status) == 127) |
361 | { |
362 | if (exit_on_error || !null_stderr) |
363 | error (exit_on_error ? EXIT_FAILURE : 0, 0, |
364 | _("%s subprocess failed" ), progname); |
365 | return 127; |
366 | } |
367 | return WEXITSTATUS (status); |
368 | #endif |
369 | } |
370 | |