1/* Waiting for a subprocess to finish.
2   Copyright (C) 2001-2003, 2005-2014 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 <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'.  */
61typedef struct
62{
63  volatile sig_atomic_t used;
64  volatile pid_t child;
65}
66slaves_entry_t;
67
68/* The registered slave subprocesses.  */
69static slaves_entry_t static_slaves[32];
70static slaves_entry_t * volatile slaves = static_slaves;
71static sig_atomic_t volatile slaves_count = 0;
72static 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.  */
83static void
84cleanup_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.  */
109void
110register_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.  */
174static void
175unregister_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.  */
192int
193wait_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