ddd254dc5c8feaf1971afe8b24f1b89c7b71cf06
[platform/upstream/dbus.git] / dbus / dbus-spawn.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-spawn.c Wrapper around fork/exec
3  * 
4  * Copyright (C) 2002, 2003, 2004  Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include <config.h>
26
27 #include "dbus-spawn.h"
28 #include "dbus-sysdeps-unix.h"
29 #include "dbus-internals.h"
30 #include "dbus-test.h"
31 #include "dbus-protocol.h"
32
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <signal.h>
36 #include <sys/wait.h>
37 #include <stdlib.h>
38 #ifdef HAVE_ERRNO_H
39 #include <errno.h>
40 #endif
41 #ifdef HAVE_SYSTEMD
42 #ifdef HAVE_SYSLOG_H
43 #include <syslog.h>
44 #endif
45 #include <systemd/sd-journal.h>
46 #endif
47
48 extern char **environ;
49
50 /**
51  * @addtogroup DBusInternalsUtils
52  * @{
53  */
54
55 /*
56  * I'm pretty sure this whole spawn file could be made simpler,
57  * if you thought about it a bit.
58  */
59
60 /**
61  * Enumeration for status of a read()
62  */
63 typedef enum
64 {
65   READ_STATUS_OK,    /**< Read succeeded */
66   READ_STATUS_ERROR, /**< Some kind of error */
67   READ_STATUS_EOF    /**< EOF returned */
68 } ReadStatus;
69
70 static ReadStatus
71 read_ints (int        fd,
72            int       *buf,
73            int        n_ints_in_buf,
74            int       *n_ints_read,
75            DBusError *error)
76 {
77   size_t bytes = 0;    
78   ReadStatus retval;
79   
80   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
81
82   retval = READ_STATUS_OK;
83   
84   while (TRUE)
85     {
86       ssize_t chunk;
87       size_t to_read;
88
89       to_read = sizeof (int) * n_ints_in_buf - bytes;
90
91       if (to_read == 0)
92         break;
93
94     again:
95       
96       chunk = read (fd,
97                     ((char*)buf) + bytes,
98                     to_read);
99       
100       if (chunk < 0 && errno == EINTR)
101         goto again;
102           
103       if (chunk < 0)
104         {
105           dbus_set_error (error,
106                           DBUS_ERROR_SPAWN_FAILED,
107                           "Failed to read from child pipe (%s)",
108                           _dbus_strerror (errno));
109
110           retval = READ_STATUS_ERROR;
111           break;
112         }
113       else if (chunk == 0)
114         {
115           retval = READ_STATUS_EOF;
116           break; /* EOF */
117         }
118       else /* chunk > 0 */
119         bytes += chunk;
120     }
121
122   *n_ints_read = (int)(bytes / sizeof(int));
123
124   return retval;
125 }
126
127 static ReadStatus
128 read_pid (int        fd,
129           pid_t     *buf,
130           DBusError *error)
131 {
132   size_t bytes = 0;    
133   ReadStatus retval;
134   
135   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
136
137   retval = READ_STATUS_OK;
138   
139   while (TRUE)
140     {
141       ssize_t chunk;
142       size_t to_read;
143
144       to_read = sizeof (pid_t) - bytes;
145
146       if (to_read == 0)
147         break;
148
149     again:
150       
151       chunk = read (fd,
152                     ((char*)buf) + bytes,
153                     to_read);
154       if (chunk < 0 && errno == EINTR)
155         goto again;
156           
157       if (chunk < 0)
158         {
159           dbus_set_error (error,
160                           DBUS_ERROR_SPAWN_FAILED,
161                           "Failed to read from child pipe (%s)",
162                           _dbus_strerror (errno));
163
164           retval = READ_STATUS_ERROR;
165           break;
166         }
167       else if (chunk == 0)
168         {
169           retval = READ_STATUS_EOF;
170           break; /* EOF */
171         }
172       else /* chunk > 0 */
173         bytes += chunk;
174     }
175
176   return retval;
177 }
178
179 /* The implementation uses an intermediate child between the main process
180  * and the grandchild. The grandchild is our spawned process. The intermediate
181  * child is a babysitter process; it keeps track of when the grandchild
182  * exits/crashes, and reaps the grandchild.
183  *
184  * We automatically reap the babysitter process, killing it if necessary,
185  * when the DBusBabysitter's refcount goes to zero.
186  *
187  * Processes:
188  *
189  * main process
190  * | fork() A
191  * \- babysitter
192  *    | fork () B
193  *    \- grandchild     --> exec -->    spawned process
194  *
195  * IPC:
196  *                  child_err_report_pipe
197  *          /-----------<---------<--------------\
198  *          |                                    ^
199  *          v                                    |
200  * main process           babysitter          grandchild
201  *          ^                 ^
202  *          v                 v
203  *          \-------<->-------/
204  *            babysitter_pipe
205  *
206  * child_err_report_pipe is genuinely a pipe.
207  * The READ_END (also called error_pipe_from_child) is used in the main
208  * process. The WRITE_END (also called child_err_report_fd) is used in
209  * the grandchild process.
210  *
211  * On failure, the grandchild process sends CHILD_EXEC_FAILED + errno.
212  * On success, the pipe just closes (because it's close-on-exec) without
213  * sending any bytes.
214  *
215  * babysitter_pipe is mis-named: it's really a bidirectional socketpair.
216  * The [0] end (also called socket_to_babysitter) is used in the main
217  * process, the [1] end (also called parent_pipe) is used in the babysitter.
218  *
219  * If the fork() labelled B in the diagram above fails, the babysitter sends
220  * CHILD_FORK_FAILED + errno.
221  * On success, the babysitter sends CHILD_PID + the grandchild's pid.
222  * On SIGCHLD, the babysitter sends CHILD_EXITED + the exit status.
223  * The main process doesn't explicitly send anything, but when it exits,
224  * the babysitter gets POLLHUP or POLLERR.
225  */
226
227 /* Messages from children to parents */
228 enum
229 {
230   CHILD_EXITED,            /* This message is followed by the exit status int */
231   CHILD_FORK_FAILED,       /* Followed by errno */
232   CHILD_EXEC_FAILED,       /* Followed by errno */
233   CHILD_PID                /* Followed by pid_t */
234 };
235
236 /**
237  * Babysitter implementation details
238  */
239 struct DBusBabysitter
240 {
241   int refcount; /**< Reference count */
242
243   char *log_name; /**< the name under which to log messages about this
244                     process being spawned */
245   
246   DBusSocket socket_to_babysitter; /**< Connection to the babysitter process */
247   int error_pipe_from_child; /**< Connection to the process that does the exec() */
248   
249   pid_t sitter_pid;  /**< PID Of the babysitter */
250   pid_t grandchild_pid; /**< PID of the grandchild */
251
252   DBusWatchList *watches; /**< Watches */
253
254   DBusWatch *error_watch; /**< Error pipe watch */
255   DBusWatch *sitter_watch; /**< Sitter pipe watch */
256
257   DBusBabysitterFinishedFunc finished_cb;
258   void *finished_data;
259
260   int errnum; /**< Error number */
261   int status; /**< Exit status code */
262   unsigned int have_child_status : 1; /**< True if child status has been reaped */
263   unsigned int have_fork_errnum : 1; /**< True if we have an error code from fork() */
264   unsigned int have_exec_errnum : 1; /**< True if we have an error code from exec() */
265 };
266
267 static DBusBabysitter*
268 _dbus_babysitter_new (void)
269 {
270   DBusBabysitter *sitter;
271
272   sitter = dbus_new0 (DBusBabysitter, 1);
273   if (sitter == NULL)
274     return NULL;
275
276   sitter->refcount = 1;
277
278   sitter->socket_to_babysitter.fd = -1;
279   sitter->error_pipe_from_child = -1;
280   
281   sitter->sitter_pid = -1;
282   sitter->grandchild_pid = -1;
283
284   sitter->watches = _dbus_watch_list_new ();
285   if (sitter->watches == NULL)
286     goto failed;
287   
288   return sitter;
289
290  failed:
291   _dbus_babysitter_unref (sitter);
292   return NULL;
293 }
294
295 /**
296  * Increment the reference count on the babysitter object.
297  *
298  * @param sitter the babysitter
299  * @returns the babysitter
300  */
301 DBusBabysitter *
302 _dbus_babysitter_ref (DBusBabysitter *sitter)
303 {
304   _dbus_assert (sitter != NULL);
305   _dbus_assert (sitter->refcount > 0);
306   
307   sitter->refcount += 1;
308
309   return sitter;
310 }
311
312 static void close_socket_to_babysitter  (DBusBabysitter *sitter);
313 static void close_error_pipe_from_child (DBusBabysitter *sitter);
314
315 /**
316  * Decrement the reference count on the babysitter object.
317  * When the reference count of the babysitter object reaches
318  * zero, the babysitter is killed and the child that was being
319  * babysat gets emancipated.
320  *
321  * @param sitter the babysitter
322  */
323 void
324 _dbus_babysitter_unref (DBusBabysitter *sitter)
325 {
326   _dbus_assert (sitter != NULL);
327   _dbus_assert (sitter->refcount > 0);
328   
329   sitter->refcount -= 1;
330   if (sitter->refcount == 0)
331     {
332       /* If we haven't forked other babysitters
333        * since this babysitter and socket were
334        * created then this close will cause the
335        * babysitter to wake up from poll with
336        * a hangup and then the babysitter will
337        * quit itself.
338        */
339       close_socket_to_babysitter (sitter);
340
341       close_error_pipe_from_child (sitter);
342
343       if (sitter->sitter_pid > 0)
344         {
345           int status;
346           int ret;
347
348           /* It's possible the babysitter died on its own above 
349            * from the close, or was killed randomly
350            * by some other process, so first try to reap it
351            */
352           ret = waitpid (sitter->sitter_pid, &status, WNOHANG);
353
354           /* If we couldn't reap the child then kill it, and
355            * try again
356            */
357           if (ret == 0)
358             kill (sitter->sitter_pid, SIGKILL);
359
360           if (ret == 0)
361             {
362               do
363                 {
364                   ret = waitpid (sitter->sitter_pid, &status, 0);
365                 }
366               while (_DBUS_UNLIKELY (ret < 0 && errno == EINTR));
367             }
368
369           if (ret < 0)
370             {
371               if (errno == ECHILD)
372                 _dbus_warn ("Babysitter process not available to be reaped; should not happen\n");
373               else
374                 _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s\n",
375                             errno, _dbus_strerror (errno));
376             }
377           else
378             {
379               _dbus_verbose ("Reaped %ld, waiting for babysitter %ld\n",
380                              (long) ret, (long) sitter->sitter_pid);
381               
382               if (WIFEXITED (sitter->status))
383                 _dbus_verbose ("Babysitter exited with status %d\n",
384                                WEXITSTATUS (sitter->status));
385               else if (WIFSIGNALED (sitter->status))
386                 _dbus_verbose ("Babysitter received signal %d\n",
387                                WTERMSIG (sitter->status));
388               else
389                 _dbus_verbose ("Babysitter exited abnormally\n");
390             }
391
392           sitter->sitter_pid = -1;
393         }
394
395       if (sitter->watches)
396         _dbus_watch_list_free (sitter->watches);
397
398       dbus_free (sitter->log_name);
399       
400       dbus_free (sitter);
401     }
402 }
403
404 static ReadStatus
405 read_data (DBusBabysitter *sitter,
406            int             fd)
407 {
408   int what;
409   int got;
410   DBusError error = DBUS_ERROR_INIT;
411   ReadStatus r;
412
413   r = read_ints (fd, &what, 1, &got, &error);
414
415   switch (r)
416     {
417     case READ_STATUS_ERROR:
418       _dbus_warn ("Failed to read data from fd %d: %s\n", fd, error.message);
419       dbus_error_free (&error);
420       return r;
421
422     case READ_STATUS_EOF:
423       return r;
424
425     case READ_STATUS_OK:
426       break;
427     }
428   
429   if (got == 1)
430     {
431       switch (what)
432         {
433         case CHILD_EXITED:
434         case CHILD_FORK_FAILED:
435         case CHILD_EXEC_FAILED:
436           {
437             int arg;
438             
439             r = read_ints (fd, &arg, 1, &got, &error);
440
441             switch (r)
442               {
443               case READ_STATUS_ERROR:
444                 _dbus_warn ("Failed to read arg from fd %d: %s\n", fd, error.message);
445                 dbus_error_free (&error);
446                 return r;
447               case READ_STATUS_EOF:
448                 return r;
449               case READ_STATUS_OK:
450                 break;
451               }
452             
453             if (got == 1)
454               {
455                 if (what == CHILD_EXITED)
456                   {
457                     /* Do not reset sitter->errnum to 0 here. We get here if
458                      * the babysitter reports that the grandchild process has
459                      * exited, and there are two ways that can happen:
460                      *
461                      * 1. grandchild successfully exec()s the desired process,
462                      * but then the desired process exits or is terminated
463                      * by a signal. The babysitter observes this and reports
464                      * CHILD_EXITED.
465                      *
466                      * 2. grandchild fails to exec() the desired process,
467                      * attempts to report the exec() failure (which
468                      * we will receive as CHILD_EXEC_FAILED), and then
469                      * exits itself (which will prompt the babysitter to
470                      * send CHILD_EXITED). We want the CHILD_EXEC_FAILED
471                      * to take precedence (and have its errno logged),
472                      * which _dbus_babysitter_set_child_exit_error() does.
473                      */
474                     sitter->have_child_status = TRUE;
475                     sitter->status = arg;
476                     _dbus_verbose ("recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n",
477                                    WIFEXITED (sitter->status), WIFSIGNALED (sitter->status),
478                                    WEXITSTATUS (sitter->status), WTERMSIG (sitter->status));
479                   }
480                 else if (what == CHILD_FORK_FAILED)
481                   {
482                     sitter->have_fork_errnum = TRUE;
483                     sitter->errnum = arg;
484                     _dbus_verbose ("recorded fork errnum %d\n", sitter->errnum);
485                   }
486                 else if (what == CHILD_EXEC_FAILED)
487                   {
488                     sitter->have_exec_errnum = TRUE;
489                     sitter->errnum = arg;
490                     _dbus_verbose ("recorded exec errnum %d\n", sitter->errnum);
491                   }
492               }
493           }
494           break;
495         case CHILD_PID:
496           {
497             pid_t pid = -1;
498
499             r = read_pid (fd, &pid, &error);
500             
501             switch (r)
502               {
503               case READ_STATUS_ERROR:
504                 _dbus_warn ("Failed to read PID from fd %d: %s\n", fd, error.message);
505                 dbus_error_free (&error);
506                 return r;
507               case READ_STATUS_EOF:
508                 return r;
509               case READ_STATUS_OK:
510                 break;
511               }
512             
513             sitter->grandchild_pid = pid;
514             
515             _dbus_verbose ("recorded grandchild pid %d\n", sitter->grandchild_pid);
516           }
517           break;
518         default:
519           _dbus_warn ("Unknown message received from babysitter process\n");
520           break;
521         }
522     }
523
524   return r;
525 }
526
527 static void
528 close_socket_to_babysitter (DBusBabysitter *sitter)
529 {
530   _dbus_verbose ("Closing babysitter\n");
531
532   if (sitter->sitter_watch != NULL)
533     {
534       _dbus_assert (sitter->watches != NULL);
535       _dbus_watch_list_remove_watch (sitter->watches,  sitter->sitter_watch);
536       _dbus_watch_invalidate (sitter->sitter_watch);
537       _dbus_watch_unref (sitter->sitter_watch);
538       sitter->sitter_watch = NULL;
539     }
540
541   if (sitter->socket_to_babysitter.fd >= 0)
542     {
543       _dbus_close_socket (sitter->socket_to_babysitter, NULL);
544       sitter->socket_to_babysitter.fd = -1;
545     }
546 }
547
548 static void
549 close_error_pipe_from_child (DBusBabysitter *sitter)
550 {
551   _dbus_verbose ("Closing child error\n");
552
553   if (sitter->error_watch != NULL)
554     {
555       _dbus_assert (sitter->watches != NULL);
556       _dbus_watch_list_remove_watch (sitter->watches,  sitter->error_watch);
557       _dbus_watch_invalidate (sitter->error_watch);
558       _dbus_watch_unref (sitter->error_watch);
559       sitter->error_watch = NULL;
560     }
561
562   if (sitter->error_pipe_from_child >= 0)
563     {
564       _dbus_close (sitter->error_pipe_from_child, NULL);
565       sitter->error_pipe_from_child = -1;
566     }
567 }
568
569 static void
570 handle_babysitter_socket (DBusBabysitter *sitter,
571                           int             revents)
572 {
573   /* Even if we have POLLHUP, we want to keep reading
574    * data until POLLIN goes away; so this function only
575    * looks at HUP/ERR if no IN is set.
576    */
577   if (revents & _DBUS_POLLIN)
578     {
579       _dbus_verbose ("Reading data from babysitter\n");
580       if (read_data (sitter, sitter->socket_to_babysitter.fd) != READ_STATUS_OK)
581         close_socket_to_babysitter (sitter);
582     }
583   else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
584     {
585       close_socket_to_babysitter (sitter);
586     }
587 }
588
589 static void
590 handle_error_pipe (DBusBabysitter *sitter,
591                    int             revents)
592 {
593   if (revents & _DBUS_POLLIN)
594     {
595       _dbus_verbose ("Reading data from child error\n");
596       if (read_data (sitter, sitter->error_pipe_from_child) != READ_STATUS_OK)
597         close_error_pipe_from_child (sitter);
598     }
599   else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
600     {
601       close_error_pipe_from_child (sitter);
602     }
603 }
604
605 /* returns whether there were any poll events handled */
606 static dbus_bool_t
607 babysitter_iteration (DBusBabysitter *sitter,
608                       dbus_bool_t     block)
609 {
610   DBusPollFD fds[2];
611   int i;
612   dbus_bool_t descriptors_ready;
613
614   descriptors_ready = FALSE;
615   
616   i = 0;
617
618   if (sitter->error_pipe_from_child >= 0)
619     {
620       fds[i].fd = sitter->error_pipe_from_child;
621       fds[i].events = _DBUS_POLLIN;
622       fds[i].revents = 0;
623       ++i;
624     }
625   
626   if (sitter->socket_to_babysitter.fd >= 0)
627     {
628       fds[i].fd = sitter->socket_to_babysitter.fd;
629       fds[i].events = _DBUS_POLLIN;
630       fds[i].revents = 0;
631       ++i;
632     }
633
634   if (i > 0)
635     {
636       int ret;
637
638       do
639         {
640           ret = _dbus_poll (fds, i, 0);
641         }
642       while (ret < 0 && errno == EINTR);
643
644       if (ret == 0 && block)
645         {
646           do
647             {
648               ret = _dbus_poll (fds, i, -1);
649             }
650           while (ret < 0 && errno == EINTR);
651         }
652
653       if (ret > 0)
654         {
655           descriptors_ready = TRUE;
656           
657           while (i > 0)
658             {
659               --i;
660               if (fds[i].fd == sitter->error_pipe_from_child)
661                 handle_error_pipe (sitter, fds[i].revents);
662               else if (fds[i].fd == sitter->socket_to_babysitter.fd)
663                 handle_babysitter_socket (sitter, fds[i].revents);
664             }
665         }
666     }
667
668   return descriptors_ready;
669 }
670
671 /**
672  * Macro returns #TRUE if the babysitter still has live sockets open to the
673  * babysitter child or the grandchild.
674  */
675 #define LIVE_CHILDREN(sitter) ((sitter)->socket_to_babysitter.fd >= 0 || (sitter)->error_pipe_from_child >= 0)
676
677 /**
678  * Blocks until the babysitter process gives us the PID of the spawned grandchild,
679  * then kills the spawned grandchild.
680  *
681  * @param sitter the babysitter object
682  */
683 void
684 _dbus_babysitter_kill_child (DBusBabysitter *sitter)
685 {
686   /* be sure we have the PID of the child */
687   while (LIVE_CHILDREN (sitter) &&
688          sitter->grandchild_pid == -1)
689     babysitter_iteration (sitter, TRUE);
690
691   _dbus_verbose ("Got child PID %ld for killing\n",
692                  (long) sitter->grandchild_pid);
693   
694   if (sitter->grandchild_pid == -1)
695     return; /* child is already dead, or we're so hosed we'll never recover */
696
697   kill (sitter->grandchild_pid, SIGKILL);
698 }
699
700 /**
701  * Checks whether the child has exited, without blocking.
702  *
703  * @param sitter the babysitter
704  */
705 dbus_bool_t
706 _dbus_babysitter_get_child_exited (DBusBabysitter *sitter)
707 {
708
709   /* Be sure we're up-to-date */
710   while (LIVE_CHILDREN (sitter) &&
711          babysitter_iteration (sitter, FALSE))
712     ;
713
714   /* We will have exited the babysitter when the child has exited */
715   return sitter->socket_to_babysitter.fd < 0;
716 }
717
718 /**
719  * Gets the exit status of the child. We do this so implementation specific
720  * detail is not cluttering up dbus, for example the system launcher code.
721  * This can only be called if the child has exited, i.e. call
722  * _dbus_babysitter_get_child_exited(). It returns FALSE if the child
723  * did not return a status code, e.g. because the child was signaled
724  * or we failed to ever launch the child in the first place.
725  *
726  * @param sitter the babysitter
727  * @param status the returned status code
728  * @returns #FALSE on failure
729  */
730 dbus_bool_t
731 _dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter,
732                                         int            *status)
733 {
734   if (!_dbus_babysitter_get_child_exited (sitter))
735     _dbus_assert_not_reached ("Child has not exited");
736   
737   if (!sitter->have_child_status ||
738       !(WIFEXITED (sitter->status)))
739     return FALSE;
740
741   *status = WEXITSTATUS (sitter->status);
742   return TRUE;
743 }
744
745 /**
746  * Sets the #DBusError with an explanation of why the spawned
747  * child process exited (on a signal, or whatever). If
748  * the child process has not exited, does nothing (error
749  * will remain unset).
750  *
751  * @param sitter the babysitter
752  * @param error an error to fill in
753  */
754 void
755 _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
756                                        DBusError      *error)
757 {
758   if (!_dbus_babysitter_get_child_exited (sitter))
759     return;
760
761   /* Note that if exec fails, we will also get a child status
762    * from the babysitter saying the child exited,
763    * so we need to give priority to the exec error
764    */
765   if (sitter->have_exec_errnum)
766     {
767       dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
768                       "Failed to execute program %s: %s",
769                       sitter->log_name, _dbus_strerror (sitter->errnum));
770     }
771   else if (sitter->have_fork_errnum)
772     {
773       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
774                       "Failed to fork a new process %s: %s",
775                       sitter->log_name, _dbus_strerror (sitter->errnum));
776     }
777   else if (sitter->have_child_status)
778     {
779       if (WIFEXITED (sitter->status))
780         dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
781                         "Process %s exited with status %d",
782                         sitter->log_name, WEXITSTATUS (sitter->status));
783       else if (WIFSIGNALED (sitter->status))
784         dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED,
785                         "Process %s received signal %d",
786                         sitter->log_name, WTERMSIG (sitter->status));
787       else
788         dbus_set_error (error, DBUS_ERROR_FAILED,
789                         "Process %s exited abnormally",
790                         sitter->log_name);
791     }
792   else
793     {
794       dbus_set_error (error, DBUS_ERROR_FAILED,
795                       "Process %s exited, reason unknown",
796                       sitter->log_name);
797     }
798 }
799
800 /**
801  * Sets watch functions to notify us when the
802  * babysitter object needs to read/write file descriptors.
803  *
804  * @param sitter the babysitter
805  * @param add_function function to begin monitoring a new descriptor.
806  * @param remove_function function to stop monitoring a descriptor.
807  * @param toggled_function function to notify when the watch is enabled/disabled
808  * @param data data to pass to add_function and remove_function.
809  * @param free_data_function function to be called to free the data.
810  * @returns #FALSE on failure (no memory)
811  */
812 dbus_bool_t
813 _dbus_babysitter_set_watch_functions (DBusBabysitter            *sitter,
814                                       DBusAddWatchFunction       add_function,
815                                       DBusRemoveWatchFunction    remove_function,
816                                       DBusWatchToggledFunction   toggled_function,
817                                       void                      *data,
818                                       DBusFreeFunction           free_data_function)
819 {
820   return _dbus_watch_list_set_functions (sitter->watches,
821                                          add_function,
822                                          remove_function,
823                                          toggled_function,
824                                          data,
825                                          free_data_function);
826 }
827
828 static dbus_bool_t
829 handle_watch (DBusWatch       *watch,
830               unsigned int     condition,
831               void            *data)
832 {
833   DBusBabysitter *sitter = _dbus_babysitter_ref (data);
834   int revents;
835   int fd;
836   
837   revents = 0;
838   if (condition & DBUS_WATCH_READABLE)
839     revents |= _DBUS_POLLIN;
840   if (condition & DBUS_WATCH_ERROR)
841     revents |= _DBUS_POLLERR;
842   if (condition & DBUS_WATCH_HANGUP)
843     revents |= _DBUS_POLLHUP;
844
845   fd = dbus_watch_get_socket (watch);
846
847   if (fd == sitter->error_pipe_from_child)
848     handle_error_pipe (sitter, revents);
849   else if (fd == sitter->socket_to_babysitter.fd)
850     handle_babysitter_socket (sitter, revents);
851
852   while (LIVE_CHILDREN (sitter) &&
853          babysitter_iteration (sitter, FALSE))
854     ;
855
856   /* fd.o #32992: if the handle_* methods closed their sockets, they previously
857    * didn't always remove the watches. Check that we don't regress. */
858   _dbus_assert (sitter->socket_to_babysitter.fd != -1 || sitter->sitter_watch == NULL);
859   _dbus_assert (sitter->error_pipe_from_child != -1 || sitter->error_watch == NULL);
860
861   if (_dbus_babysitter_get_child_exited (sitter) &&
862       sitter->finished_cb != NULL)
863     {
864       sitter->finished_cb (sitter, sitter->finished_data);
865       sitter->finished_cb = NULL;
866     }
867
868   _dbus_babysitter_unref (sitter);
869   return TRUE;
870 }
871
872 /** Helps remember which end of the pipe is which */
873 #define READ_END 0
874 /** Helps remember which end of the pipe is which */
875 #define WRITE_END 1
876
877
878 /* Avoids a danger in re-entrant situations (calling close()
879  * on a file descriptor twice, and another module has
880  * re-opened it since the first close).
881  *
882  * This previously claimed to be relevant for threaded situations, but by
883  * trivial inspection, it is not thread-safe. It doesn't actually
884  * matter, since this module is only used in the -util variant of the
885  * library, which is only used in single-threaded situations.
886  */
887 static int
888 close_and_invalidate (int *fd)
889 {
890   int ret;
891
892   if (*fd < 0)
893     return -1;
894   else
895     {
896       ret = _dbus_close (*fd, NULL);
897       *fd = -1;
898     }
899
900   return ret;
901 }
902
903 static dbus_bool_t
904 make_pipe (int         p[2],
905            DBusError  *error)
906 {
907   int retval;
908
909 #ifdef HAVE_PIPE2
910   dbus_bool_t cloexec_done;
911
912   retval = pipe2 (p, O_CLOEXEC);
913   cloexec_done = retval >= 0;
914
915   /* Check if kernel seems to be too old to know pipe2(). We assume
916      that if pipe2 is available, O_CLOEXEC is too.  */
917   if (retval < 0 && errno == ENOSYS)
918 #endif
919     {
920       retval = pipe(p);
921     }
922
923   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
924
925   if (retval < 0)
926     {
927       dbus_set_error (error,
928                       DBUS_ERROR_SPAWN_FAILED,
929                       "Failed to create pipe for communicating with child process (%s)",
930                       _dbus_strerror (errno));
931       return FALSE;
932     }
933
934 #ifdef HAVE_PIPE2
935   if (!cloexec_done)
936 #endif
937     {
938       _dbus_fd_set_close_on_exec (p[0]);
939       _dbus_fd_set_close_on_exec (p[1]);
940     }
941
942   return TRUE;
943 }
944
945 static void
946 do_write (int fd, const void *buf, size_t count)
947 {
948   size_t bytes_written;
949   int ret;
950   
951   bytes_written = 0;
952   
953  again:
954   
955   ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
956
957   if (ret < 0)
958     {
959       if (errno == EINTR)
960         goto again;
961       else
962         {
963           _dbus_warn ("Failed to write data to pipe!\n");
964           exit (1); /* give up, we suck */
965         }
966     }
967   else
968     bytes_written += ret;
969   
970   if (bytes_written < count)
971     goto again;
972 }
973
974 static void
975 write_err_and_exit (int fd, int msg)
976 {
977   int en = errno;
978
979   do_write (fd, &msg, sizeof (msg));
980   do_write (fd, &en, sizeof (en));
981   
982   exit (1);
983 }
984
985 static void
986 write_pid (int fd, pid_t pid)
987 {
988   int msg = CHILD_PID;
989   
990   do_write (fd, &msg, sizeof (msg));
991   do_write (fd, &pid, sizeof (pid));
992 }
993
994 static void
995 write_status_and_exit (int fd, int status)
996 {
997   int msg = CHILD_EXITED;
998   
999   do_write (fd, &msg, sizeof (msg));
1000   do_write (fd, &status, sizeof (status));
1001   
1002   exit (0);
1003 }
1004
1005 static void
1006 do_exec (int                       child_err_report_fd,
1007          char                    **argv,
1008          char                    **envp,
1009          DBusSpawnChildSetupFunc   child_setup,
1010          void                     *user_data)
1011 {
1012 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1013   int i, max_open;
1014 #endif
1015
1016   _dbus_verbose_reset ();
1017   _dbus_verbose ("Child process has PID " DBUS_PID_FORMAT "\n",
1018                  _dbus_getpid ());
1019   
1020   if (child_setup)
1021     (* child_setup) (user_data);
1022
1023 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1024   max_open = sysconf (_SC_OPEN_MAX);
1025   
1026   for (i = 3; i < max_open; i++)
1027     {
1028       int retval;
1029
1030       if (i == child_err_report_fd)
1031         continue;
1032       
1033       retval = fcntl (i, F_GETFD);
1034
1035       if (retval != -1 && !(retval & FD_CLOEXEC))
1036         _dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i);
1037     }
1038 #endif
1039
1040   if (envp == NULL)
1041     {
1042       _dbus_assert (environ != NULL);
1043
1044       envp = environ;
1045     }
1046   
1047   execve (argv[0], argv, envp);
1048   
1049   /* Exec failed */
1050   write_err_and_exit (child_err_report_fd,
1051                       CHILD_EXEC_FAILED);
1052 }
1053
1054 static void
1055 check_babysit_events (pid_t grandchild_pid,
1056                       int   parent_pipe,
1057                       int   revents)
1058 {
1059   pid_t ret;
1060   int status;
1061   
1062   do
1063     {
1064       ret = waitpid (grandchild_pid, &status, WNOHANG);
1065       /* The man page says EINTR can't happen with WNOHANG,
1066        * but there are reports of it (maybe only with valgrind?)
1067        */
1068     }
1069   while (ret < 0 && errno == EINTR);
1070
1071   if (ret == 0)
1072     {
1073       _dbus_verbose ("no child exited\n");
1074       
1075       ; /* no child exited */
1076     }
1077   else if (ret < 0)
1078     {
1079       /* This isn't supposed to happen. */
1080       _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s\n",
1081                   _dbus_strerror (errno));
1082       exit (1);
1083     }
1084   else if (ret == grandchild_pid)
1085     {
1086       /* Child exited */
1087       _dbus_verbose ("reaped child pid %ld\n", (long) ret);
1088       
1089       write_status_and_exit (parent_pipe, status);
1090     }
1091   else
1092     {
1093       _dbus_warn ("waitpid() reaped pid %d that we've never heard of\n",
1094                   (int) ret);
1095       exit (1);
1096     }
1097
1098   if (revents & _DBUS_POLLIN)
1099     {
1100       _dbus_verbose ("babysitter got POLLIN from parent pipe\n");
1101     }
1102
1103   if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
1104     {
1105       /* Parent is gone, so we just exit */
1106       _dbus_verbose ("babysitter got POLLERR or POLLHUP from parent\n");
1107       exit (0);
1108     }
1109 }
1110
1111 static int babysit_sigchld_pipe = -1;
1112
1113 static void
1114 babysit_signal_handler (int signo)
1115 {
1116   char b = '\0';
1117  again:
1118   if (write (babysit_sigchld_pipe, &b, 1) <= 0) 
1119     if (errno == EINTR)
1120       goto again;
1121 }
1122
1123 static void
1124 babysit (pid_t grandchild_pid,
1125          int   parent_pipe)
1126 {
1127   int sigchld_pipe[2];
1128
1129   /* We don't exec, so we keep parent state, such as the pid that
1130    * _dbus_verbose() uses. Reset the pid here.
1131    */
1132   _dbus_verbose_reset ();
1133   
1134   /* I thought SIGCHLD would just wake up the poll, but
1135    * that didn't seem to work, so added this pipe.
1136    * Probably the pipe is more likely to work on busted
1137    * operating systems anyhow.
1138    */
1139   if (pipe (sigchld_pipe) < 0)
1140     {
1141       _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n");
1142       exit (1);
1143     }
1144
1145   babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
1146
1147   _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler);
1148   
1149   write_pid (parent_pipe, grandchild_pid);
1150
1151   check_babysit_events (grandchild_pid, parent_pipe, 0);
1152
1153   while (TRUE)
1154     {
1155       DBusPollFD pfds[2];
1156       
1157       pfds[0].fd = parent_pipe;
1158       pfds[0].events = _DBUS_POLLIN;
1159       pfds[0].revents = 0;
1160
1161       pfds[1].fd = sigchld_pipe[READ_END];
1162       pfds[1].events = _DBUS_POLLIN;
1163       pfds[1].revents = 0;
1164       
1165       if (_dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1) < 0 && errno != EINTR)
1166         {
1167           _dbus_warn ("_dbus_poll() error: %s\n", strerror (errno));
1168           exit (1);
1169         }
1170
1171       if (pfds[0].revents != 0)
1172         {
1173           check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents);
1174         }
1175       else if (pfds[1].revents & _DBUS_POLLIN)
1176         {
1177           char b;
1178           if (read (sigchld_pipe[READ_END], &b, 1) == -1)
1179             {
1180               /* ignore */
1181             }
1182           /* do waitpid check */
1183           check_babysit_events (grandchild_pid, parent_pipe, 0);
1184         }
1185     }
1186   
1187   exit (1);
1188 }
1189
1190 /**
1191  * Spawns a new process. The child_setup
1192  * function is passed the given user_data and is run in the child
1193  * just before calling exec().
1194  *
1195  * Also creates a "babysitter" which tracks the status of the
1196  * child process, advising the parent if the child exits.
1197  * If the spawn fails, no babysitter is created.
1198  * If sitter_p is #NULL, no babysitter is kept.
1199  *
1200  * @param sitter_p return location for babysitter or #NULL
1201  * @param log_name the name under which to log messages about this process being spawned
1202  * @param argv the executable and arguments
1203  * @param env the environment, or #NULL to copy the parent's
1204  * @param child_setup function to call in child pre-exec()
1205  * @param user_data user data for setup function
1206  * @param error error object to be filled in if function fails
1207  * @returns #TRUE on success, #FALSE if error is filled in
1208  */
1209 dbus_bool_t
1210 _dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
1211                                    const char               *log_name,
1212                                    char                    **argv,
1213                                    char                    **env,
1214                                    DBusSpawnChildSetupFunc   child_setup,
1215                                    void                     *user_data,
1216                                    DBusError                *error)
1217 {
1218   DBusBabysitter *sitter;
1219   int child_err_report_pipe[2] = { -1, -1 };
1220   DBusSocket babysitter_pipe[2] = { DBUS_SOCKET_INIT, DBUS_SOCKET_INIT };
1221   pid_t pid;
1222 #ifdef HAVE_SYSTEMD
1223   int fd_out = -1;
1224   int fd_err = -1;
1225 #endif
1226   
1227   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1228   _dbus_assert (argv[0] != NULL);
1229
1230   if (sitter_p != NULL)
1231     *sitter_p = NULL;
1232
1233   sitter = NULL;
1234
1235   sitter = _dbus_babysitter_new ();
1236   if (sitter == NULL)
1237     {
1238       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1239       return FALSE;
1240     }
1241
1242   sitter->log_name = _dbus_strdup (log_name);
1243   if (sitter->log_name == NULL && log_name != NULL)
1244     {
1245       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1246       goto cleanup_and_fail;
1247     }
1248
1249   if (sitter->log_name == NULL)
1250     sitter->log_name = _dbus_strdup (argv[0]);
1251
1252   if (sitter->log_name == NULL)
1253     {
1254       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1255       goto cleanup_and_fail;
1256     }
1257   
1258   if (!make_pipe (child_err_report_pipe, error))
1259     goto cleanup_and_fail;
1260
1261   if (!_dbus_socketpair (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
1262     goto cleanup_and_fail;
1263
1264   /* Setting up the babysitter is only useful in the parent,
1265    * but we don't want to run out of memory and fail
1266    * after we've already forked, since then we'd leak
1267    * child processes everywhere.
1268    */
1269   sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
1270                                          DBUS_WATCH_READABLE,
1271                                          TRUE, handle_watch, sitter, NULL);
1272   if (sitter->error_watch == NULL)
1273     {
1274       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1275       goto cleanup_and_fail;
1276     }
1277         
1278   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->error_watch))
1279     {
1280       /* we need to free it early so the destructor won't try to remove it
1281        * without it having been added, which DBusLoop doesn't allow */
1282       _dbus_watch_invalidate (sitter->error_watch);
1283       _dbus_watch_unref (sitter->error_watch);
1284       sitter->error_watch = NULL;
1285
1286       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1287       goto cleanup_and_fail;
1288     }
1289       
1290   sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0].fd,
1291                                           DBUS_WATCH_READABLE,
1292                                           TRUE, handle_watch, sitter, NULL);
1293   if (sitter->sitter_watch == NULL)
1294     {
1295       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1296       goto cleanup_and_fail;
1297     }
1298       
1299   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->sitter_watch))
1300     {
1301       /* we need to free it early so the destructor won't try to remove it
1302        * without it having been added, which DBusLoop doesn't allow */
1303       _dbus_watch_invalidate (sitter->sitter_watch);
1304       _dbus_watch_unref (sitter->sitter_watch);
1305       sitter->sitter_watch = NULL;
1306
1307       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1308       goto cleanup_and_fail;
1309     }
1310
1311   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1312
1313 #ifdef HAVE_SYSTEMD
1314   /* This may fail, but it's not critical.
1315    * In particular, if we were compiled with journald support but are now
1316    * running on a non-systemd system, this is going to fail, so we
1317    * have to cope gracefully. */
1318   fd_out = sd_journal_stream_fd (sitter->log_name, LOG_INFO, FALSE);
1319   fd_err = sd_journal_stream_fd (sitter->log_name, LOG_WARNING, FALSE);
1320 #endif
1321
1322   pid = fork ();
1323   
1324   if (pid < 0)
1325     {
1326       dbus_set_error (error,
1327                       DBUS_ERROR_SPAWN_FORK_FAILED,
1328                       "Failed to fork (%s)",
1329                       _dbus_strerror (errno));
1330       goto cleanup_and_fail;
1331     }
1332   else if (pid == 0)
1333     {
1334       /* Immediate child, this is the babysitter process. */
1335       int grandchild_pid;
1336       
1337       /* Be sure we crash if the parent exits
1338        * and we write to the err_report_pipe
1339        */
1340       signal (SIGPIPE, SIG_DFL);
1341
1342       /* Close the parent's end of the pipes. */
1343       close_and_invalidate (&child_err_report_pipe[READ_END]);
1344       close_and_invalidate (&babysitter_pipe[0].fd);
1345       
1346       /* Create the child that will exec () */
1347       grandchild_pid = fork ();
1348       
1349       if (grandchild_pid < 0)
1350         {
1351           write_err_and_exit (babysitter_pipe[1].fd,
1352                               CHILD_FORK_FAILED);
1353           _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
1354         }
1355       else if (grandchild_pid == 0)
1356       {
1357           /* Go back to ignoring SIGPIPE, since it's evil
1358            */
1359           signal (SIGPIPE, SIG_IGN);
1360
1361           close_and_invalidate (&babysitter_pipe[1].fd);
1362 #ifdef HAVE_SYSTEMD
1363           /* log to systemd journal if possible */
1364           if (fd_out >= 0)
1365             dup2 (fd_out, STDOUT_FILENO);
1366           if (fd_err >= 0)
1367             dup2 (fd_err, STDERR_FILENO);
1368           close_and_invalidate (&fd_out);
1369           close_and_invalidate (&fd_err);
1370 #endif
1371           do_exec (child_err_report_pipe[WRITE_END],
1372                    argv,
1373                    env,
1374                    child_setup, user_data);
1375           _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
1376         }
1377       else
1378         {
1379           close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1380 #ifdef HAVE_SYSTEMD
1381           close_and_invalidate (&fd_out);
1382           close_and_invalidate (&fd_err);
1383 #endif
1384           babysit (grandchild_pid, babysitter_pipe[1].fd);
1385           _dbus_assert_not_reached ("Got to code after babysit()");
1386         }
1387     }
1388   else
1389     {      
1390       /* Close the uncared-about ends of the pipes */
1391       close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1392       close_and_invalidate (&babysitter_pipe[1].fd);
1393 #ifdef HAVE_SYSTEMD
1394       close_and_invalidate (&fd_out);
1395       close_and_invalidate (&fd_err);
1396 #endif
1397
1398       sitter->socket_to_babysitter = babysitter_pipe[0];
1399       babysitter_pipe[0].fd = -1;
1400       
1401       sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
1402       child_err_report_pipe[READ_END] = -1;
1403
1404       sitter->sitter_pid = pid;
1405
1406       if (sitter_p != NULL)
1407         *sitter_p = sitter;
1408       else
1409         _dbus_babysitter_unref (sitter);
1410
1411       dbus_free_string_array (env);
1412
1413       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1414       
1415       return TRUE;
1416     }
1417
1418  cleanup_and_fail:
1419
1420   _DBUS_ASSERT_ERROR_IS_SET (error);
1421   
1422   close_and_invalidate (&child_err_report_pipe[READ_END]);
1423   close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1424   close_and_invalidate (&babysitter_pipe[0].fd);
1425   close_and_invalidate (&babysitter_pipe[1].fd);
1426 #ifdef HAVE_SYSTEMD
1427   close_and_invalidate (&fd_out);
1428   close_and_invalidate (&fd_err);
1429 #endif
1430
1431   if (sitter != NULL)
1432     _dbus_babysitter_unref (sitter);
1433   
1434   return FALSE;
1435 }
1436
1437 void
1438 _dbus_babysitter_set_result_function  (DBusBabysitter             *sitter,
1439                                        DBusBabysitterFinishedFunc  finished,
1440                                        void                       *user_data)
1441 {
1442   sitter->finished_cb = finished;
1443   sitter->finished_data = user_data;
1444 }
1445
1446 /** @} */
1447
1448 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1449
1450 static char *
1451 get_test_exec (const char *exe,
1452                DBusString *scratch_space)
1453 {
1454   const char *dbus_test_exec;
1455
1456   dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC");
1457
1458   if (dbus_test_exec == NULL)
1459     dbus_test_exec = DBUS_TEST_EXEC;
1460
1461   if (!_dbus_string_init (scratch_space))
1462     return NULL;
1463
1464   if (!_dbus_string_append_printf (scratch_space, "%s/%s%s",
1465                                    dbus_test_exec, exe, DBUS_EXEEXT))
1466     {
1467       _dbus_string_free (scratch_space);
1468       return NULL;
1469     }
1470
1471   return _dbus_string_get_data (scratch_space);
1472 }
1473
1474 static void
1475 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter)
1476 {
1477   while (LIVE_CHILDREN (sitter))
1478     babysitter_iteration (sitter, TRUE);
1479 }
1480
1481 static dbus_bool_t
1482 check_spawn_nonexistent (void *data)
1483 {
1484   char *argv[4] = { NULL, NULL, NULL, NULL };
1485   DBusBabysitter *sitter = NULL;
1486   DBusError error = DBUS_ERROR_INIT;
1487
1488   /*** Test launching nonexistent binary */
1489   
1490   argv[0] = "/this/does/not/exist/32542sdgafgafdg";
1491   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_nonexistent", argv,
1492                                          NULL, NULL, NULL,
1493                                          &error))
1494     {
1495       _dbus_babysitter_block_for_child_exit (sitter);
1496       _dbus_babysitter_set_child_exit_error (sitter, &error);
1497     }
1498
1499   if (sitter)
1500     _dbus_babysitter_unref (sitter);
1501
1502   if (!dbus_error_is_set (&error))
1503     {
1504       _dbus_warn ("Did not get an error launching nonexistent executable\n");
1505       return FALSE;
1506     }
1507
1508   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1509         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
1510     {
1511       _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n",
1512                   error.name, error.message);
1513       dbus_error_free (&error);
1514       return FALSE;
1515     }
1516
1517   dbus_error_free (&error);
1518   
1519   return TRUE;
1520 }
1521
1522 static dbus_bool_t
1523 check_spawn_segfault (void *data)
1524 {
1525   char *argv[4] = { NULL, NULL, NULL, NULL };
1526   DBusBabysitter *sitter = NULL;
1527   DBusError error = DBUS_ERROR_INIT;
1528   DBusString argv0;
1529
1530   /*** Test launching segfault binary */
1531
1532   argv[0] = get_test_exec ("test-segfault", &argv0);
1533
1534   if (argv[0] == NULL)
1535     {
1536       /* OOM was simulated, never mind */
1537       return TRUE;
1538     }
1539
1540   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_segfault", argv,
1541                                          NULL, NULL, NULL,
1542                                          &error))
1543     {
1544       _dbus_babysitter_block_for_child_exit (sitter);
1545       _dbus_babysitter_set_child_exit_error (sitter, &error);
1546     }
1547
1548   _dbus_string_free (&argv0);
1549
1550   if (sitter)
1551     _dbus_babysitter_unref (sitter);
1552
1553   if (!dbus_error_is_set (&error))
1554     {
1555       _dbus_warn ("Did not get an error launching segfaulting binary\n");
1556       return FALSE;
1557     }
1558
1559   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1560         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1561     {
1562       _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n",
1563                   error.name, error.message);
1564       dbus_error_free (&error);
1565       return FALSE;
1566     }
1567
1568   dbus_error_free (&error);
1569   
1570   return TRUE;
1571 }
1572
1573 static dbus_bool_t
1574 check_spawn_exit (void *data)
1575 {
1576   char *argv[4] = { NULL, NULL, NULL, NULL };
1577   DBusBabysitter *sitter = NULL;
1578   DBusError error = DBUS_ERROR_INIT;
1579   DBusString argv0;
1580
1581   /*** Test launching exit failure binary */
1582
1583   argv[0] = get_test_exec ("test-exit", &argv0);
1584
1585   if (argv[0] == NULL)
1586     {
1587       /* OOM was simulated, never mind */
1588       return TRUE;
1589     }
1590
1591   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_exit", argv,
1592                                          NULL, NULL, NULL,
1593                                          &error))
1594     {
1595       _dbus_babysitter_block_for_child_exit (sitter);
1596       _dbus_babysitter_set_child_exit_error (sitter, &error);
1597     }
1598
1599   _dbus_string_free (&argv0);
1600
1601   if (sitter)
1602     _dbus_babysitter_unref (sitter);
1603
1604   if (!dbus_error_is_set (&error))
1605     {
1606       _dbus_warn ("Did not get an error launching binary that exited with failure code\n");
1607       return FALSE;
1608     }
1609
1610   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1611         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
1612     {
1613       _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n",
1614                   error.name, error.message);
1615       dbus_error_free (&error);
1616       return FALSE;
1617     }
1618
1619   dbus_error_free (&error);
1620   
1621   return TRUE;
1622 }
1623
1624 static dbus_bool_t
1625 check_spawn_and_kill (void *data)
1626 {
1627   char *argv[4] = { NULL, NULL, NULL, NULL };
1628   DBusBabysitter *sitter = NULL;
1629   DBusError error = DBUS_ERROR_INIT;
1630   DBusString argv0;
1631
1632   /*** Test launching sleeping binary then killing it */
1633
1634   argv[0] = get_test_exec ("test-sleep-forever", &argv0);
1635
1636   if (argv[0] == NULL)
1637     {
1638       /* OOM was simulated, never mind */
1639       return TRUE;
1640     }
1641
1642   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_and_kill", argv,
1643                                          NULL, NULL, NULL,
1644                                          &error))
1645     {
1646       _dbus_babysitter_kill_child (sitter);
1647       
1648       _dbus_babysitter_block_for_child_exit (sitter);
1649       
1650       _dbus_babysitter_set_child_exit_error (sitter, &error);
1651     }
1652
1653   _dbus_string_free (&argv0);
1654
1655   if (sitter)
1656     _dbus_babysitter_unref (sitter);
1657
1658   if (!dbus_error_is_set (&error))
1659     {
1660       _dbus_warn ("Did not get an error after killing spawned binary\n");
1661       return FALSE;
1662     }
1663
1664   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1665         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1666     {
1667       _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
1668                   error.name, error.message);
1669       dbus_error_free (&error);
1670       return FALSE;
1671     }
1672
1673   dbus_error_free (&error);
1674   
1675   return TRUE;
1676 }
1677
1678 dbus_bool_t
1679 _dbus_spawn_test (const char *test_data_dir)
1680 {
1681   if (!_dbus_test_oom_handling ("spawn_nonexistent",
1682                                 check_spawn_nonexistent,
1683                                 NULL))
1684     return FALSE;
1685
1686   if (!_dbus_test_oom_handling ("spawn_segfault",
1687                                 check_spawn_segfault,
1688                                 NULL))
1689     return FALSE;
1690
1691   if (!_dbus_test_oom_handling ("spawn_exit",
1692                                 check_spawn_exit,
1693                                 NULL))
1694     return FALSE;
1695
1696   if (!_dbus_test_oom_handling ("spawn_and_kill",
1697                                 check_spawn_and_kill,
1698                                 NULL))
1699     return FALSE;
1700   
1701   return TRUE;
1702 }
1703 #endif