Merge branch 'dbus-1.10'
[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.
1192  *
1193  * On Unix platforms, the child_setup function is passed the given
1194  * user_data and is run in the child after fork() but before calling exec().
1195  * This can be used to change uid, resource limits and so on.
1196  * On Windows, this functionality does not fit the multi-processing model
1197  * (Windows does the equivalent of fork() and exec() in a single API call),
1198  * and the child_setup function and its user_data are ignored.
1199  *
1200  * Also creates a "babysitter" which tracks the status of the
1201  * child process, advising the parent if the child exits.
1202  * If the spawn fails, no babysitter is created.
1203  * If sitter_p is #NULL, no babysitter is kept.
1204  *
1205  * @param sitter_p return location for babysitter or #NULL
1206  * @param log_name the name under which to log messages about this process being spawned
1207  * @param argv the executable and arguments
1208  * @param env the environment, or #NULL to copy the parent's
1209  * @param child_setup function to call in child pre-exec()
1210  * @param user_data user data for setup function
1211  * @param error error object to be filled in if function fails
1212  * @returns #TRUE on success, #FALSE if error is filled in
1213  */
1214 dbus_bool_t
1215 _dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
1216                                    const char               *log_name,
1217                                    char                    **argv,
1218                                    char                    **env,
1219                                    DBusSpawnChildSetupFunc   child_setup,
1220                                    void                     *user_data,
1221                                    DBusError                *error)
1222 {
1223   DBusBabysitter *sitter;
1224   int child_err_report_pipe[2] = { -1, -1 };
1225   DBusSocket babysitter_pipe[2] = { DBUS_SOCKET_INIT, DBUS_SOCKET_INIT };
1226   pid_t pid;
1227 #ifdef HAVE_SYSTEMD
1228   int fd_out = -1;
1229   int fd_err = -1;
1230 #endif
1231   
1232   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1233   _dbus_assert (argv[0] != NULL);
1234
1235   if (sitter_p != NULL)
1236     *sitter_p = NULL;
1237
1238   sitter = NULL;
1239
1240   sitter = _dbus_babysitter_new ();
1241   if (sitter == NULL)
1242     {
1243       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1244       return FALSE;
1245     }
1246
1247   sitter->log_name = _dbus_strdup (log_name);
1248   if (sitter->log_name == NULL && log_name != NULL)
1249     {
1250       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1251       goto cleanup_and_fail;
1252     }
1253
1254   if (sitter->log_name == NULL)
1255     sitter->log_name = _dbus_strdup (argv[0]);
1256
1257   if (sitter->log_name == NULL)
1258     {
1259       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1260       goto cleanup_and_fail;
1261     }
1262   
1263   if (!make_pipe (child_err_report_pipe, error))
1264     goto cleanup_and_fail;
1265
1266   if (!_dbus_socketpair (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
1267     goto cleanup_and_fail;
1268
1269   /* Setting up the babysitter is only useful in the parent,
1270    * but we don't want to run out of memory and fail
1271    * after we've already forked, since then we'd leak
1272    * child processes everywhere.
1273    */
1274   sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
1275                                          DBUS_WATCH_READABLE,
1276                                          TRUE, handle_watch, sitter, NULL);
1277   if (sitter->error_watch == NULL)
1278     {
1279       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1280       goto cleanup_and_fail;
1281     }
1282         
1283   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->error_watch))
1284     {
1285       /* we need to free it early so the destructor won't try to remove it
1286        * without it having been added, which DBusLoop doesn't allow */
1287       _dbus_watch_invalidate (sitter->error_watch);
1288       _dbus_watch_unref (sitter->error_watch);
1289       sitter->error_watch = NULL;
1290
1291       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1292       goto cleanup_and_fail;
1293     }
1294       
1295   sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0].fd,
1296                                           DBUS_WATCH_READABLE,
1297                                           TRUE, handle_watch, sitter, NULL);
1298   if (sitter->sitter_watch == NULL)
1299     {
1300       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1301       goto cleanup_and_fail;
1302     }
1303       
1304   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->sitter_watch))
1305     {
1306       /* we need to free it early so the destructor won't try to remove it
1307        * without it having been added, which DBusLoop doesn't allow */
1308       _dbus_watch_invalidate (sitter->sitter_watch);
1309       _dbus_watch_unref (sitter->sitter_watch);
1310       sitter->sitter_watch = NULL;
1311
1312       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1313       goto cleanup_and_fail;
1314     }
1315
1316   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1317
1318 #ifdef HAVE_SYSTEMD
1319   /* This may fail, but it's not critical.
1320    * In particular, if we were compiled with journald support but are now
1321    * running on a non-systemd system, this is going to fail, so we
1322    * have to cope gracefully. */
1323   fd_out = sd_journal_stream_fd (sitter->log_name, LOG_INFO, FALSE);
1324   fd_err = sd_journal_stream_fd (sitter->log_name, LOG_WARNING, FALSE);
1325 #endif
1326
1327   pid = fork ();
1328   
1329   if (pid < 0)
1330     {
1331       dbus_set_error (error,
1332                       DBUS_ERROR_SPAWN_FORK_FAILED,
1333                       "Failed to fork (%s)",
1334                       _dbus_strerror (errno));
1335       goto cleanup_and_fail;
1336     }
1337   else if (pid == 0)
1338     {
1339       /* Immediate child, this is the babysitter process. */
1340       int grandchild_pid;
1341       
1342       /* Be sure we crash if the parent exits
1343        * and we write to the err_report_pipe
1344        */
1345       signal (SIGPIPE, SIG_DFL);
1346
1347       /* Close the parent's end of the pipes. */
1348       close_and_invalidate (&child_err_report_pipe[READ_END]);
1349       close_and_invalidate (&babysitter_pipe[0].fd);
1350       
1351       /* Create the child that will exec () */
1352       grandchild_pid = fork ();
1353       
1354       if (grandchild_pid < 0)
1355         {
1356           write_err_and_exit (babysitter_pipe[1].fd,
1357                               CHILD_FORK_FAILED);
1358           _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
1359         }
1360       else if (grandchild_pid == 0)
1361       {
1362           /* Go back to ignoring SIGPIPE, since it's evil
1363            */
1364           signal (SIGPIPE, SIG_IGN);
1365
1366           close_and_invalidate (&babysitter_pipe[1].fd);
1367 #ifdef HAVE_SYSTEMD
1368           /* log to systemd journal if possible */
1369           if (fd_out >= 0)
1370             dup2 (fd_out, STDOUT_FILENO);
1371           if (fd_err >= 0)
1372             dup2 (fd_err, STDERR_FILENO);
1373           close_and_invalidate (&fd_out);
1374           close_and_invalidate (&fd_err);
1375 #endif
1376           do_exec (child_err_report_pipe[WRITE_END],
1377                    argv,
1378                    env,
1379                    child_setup, user_data);
1380           _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
1381         }
1382       else
1383         {
1384           close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1385 #ifdef HAVE_SYSTEMD
1386           close_and_invalidate (&fd_out);
1387           close_and_invalidate (&fd_err);
1388 #endif
1389           babysit (grandchild_pid, babysitter_pipe[1].fd);
1390           _dbus_assert_not_reached ("Got to code after babysit()");
1391         }
1392     }
1393   else
1394     {      
1395       /* Close the uncared-about ends of the pipes */
1396       close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1397       close_and_invalidate (&babysitter_pipe[1].fd);
1398 #ifdef HAVE_SYSTEMD
1399       close_and_invalidate (&fd_out);
1400       close_and_invalidate (&fd_err);
1401 #endif
1402
1403       sitter->socket_to_babysitter = babysitter_pipe[0];
1404       babysitter_pipe[0].fd = -1;
1405       
1406       sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
1407       child_err_report_pipe[READ_END] = -1;
1408
1409       sitter->sitter_pid = pid;
1410
1411       if (sitter_p != NULL)
1412         *sitter_p = sitter;
1413       else
1414         _dbus_babysitter_unref (sitter);
1415
1416       dbus_free_string_array (env);
1417
1418       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1419       
1420       return TRUE;
1421     }
1422
1423  cleanup_and_fail:
1424
1425   _DBUS_ASSERT_ERROR_IS_SET (error);
1426   
1427   close_and_invalidate (&child_err_report_pipe[READ_END]);
1428   close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1429   close_and_invalidate (&babysitter_pipe[0].fd);
1430   close_and_invalidate (&babysitter_pipe[1].fd);
1431 #ifdef HAVE_SYSTEMD
1432   close_and_invalidate (&fd_out);
1433   close_and_invalidate (&fd_err);
1434 #endif
1435
1436   if (sitter != NULL)
1437     _dbus_babysitter_unref (sitter);
1438   
1439   return FALSE;
1440 }
1441
1442 void
1443 _dbus_babysitter_set_result_function  (DBusBabysitter             *sitter,
1444                                        DBusBabysitterFinishedFunc  finished,
1445                                        void                       *user_data)
1446 {
1447   sitter->finished_cb = finished;
1448   sitter->finished_data = user_data;
1449 }
1450
1451 /** @} */
1452
1453 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1454
1455 static char *
1456 get_test_exec (const char *exe,
1457                DBusString *scratch_space)
1458 {
1459   const char *dbus_test_exec;
1460
1461   dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC");
1462
1463   if (dbus_test_exec == NULL)
1464     dbus_test_exec = DBUS_TEST_EXEC;
1465
1466   if (!_dbus_string_init (scratch_space))
1467     return NULL;
1468
1469   if (!_dbus_string_append_printf (scratch_space, "%s/%s%s",
1470                                    dbus_test_exec, exe, DBUS_EXEEXT))
1471     {
1472       _dbus_string_free (scratch_space);
1473       return NULL;
1474     }
1475
1476   return _dbus_string_get_data (scratch_space);
1477 }
1478
1479 static void
1480 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter)
1481 {
1482   while (LIVE_CHILDREN (sitter))
1483     babysitter_iteration (sitter, TRUE);
1484 }
1485
1486 static dbus_bool_t
1487 check_spawn_nonexistent (void *data)
1488 {
1489   char *argv[4] = { NULL, NULL, NULL, NULL };
1490   DBusBabysitter *sitter = NULL;
1491   DBusError error = DBUS_ERROR_INIT;
1492
1493   /*** Test launching nonexistent binary */
1494   
1495   argv[0] = "/this/does/not/exist/32542sdgafgafdg";
1496   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_nonexistent", argv,
1497                                          NULL, NULL, NULL,
1498                                          &error))
1499     {
1500       _dbus_babysitter_block_for_child_exit (sitter);
1501       _dbus_babysitter_set_child_exit_error (sitter, &error);
1502     }
1503
1504   if (sitter)
1505     _dbus_babysitter_unref (sitter);
1506
1507   if (!dbus_error_is_set (&error))
1508     {
1509       _dbus_warn ("Did not get an error launching nonexistent executable\n");
1510       return FALSE;
1511     }
1512
1513   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1514         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
1515     {
1516       _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n",
1517                   error.name, error.message);
1518       dbus_error_free (&error);
1519       return FALSE;
1520     }
1521
1522   dbus_error_free (&error);
1523   
1524   return TRUE;
1525 }
1526
1527 static dbus_bool_t
1528 check_spawn_segfault (void *data)
1529 {
1530   char *argv[4] = { NULL, NULL, NULL, NULL };
1531   DBusBabysitter *sitter = NULL;
1532   DBusError error = DBUS_ERROR_INIT;
1533   DBusString argv0;
1534
1535   /*** Test launching segfault binary */
1536
1537   argv[0] = get_test_exec ("test-segfault", &argv0);
1538
1539   if (argv[0] == NULL)
1540     {
1541       /* OOM was simulated, never mind */
1542       return TRUE;
1543     }
1544
1545   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_segfault", argv,
1546                                          NULL, NULL, NULL,
1547                                          &error))
1548     {
1549       _dbus_babysitter_block_for_child_exit (sitter);
1550       _dbus_babysitter_set_child_exit_error (sitter, &error);
1551     }
1552
1553   _dbus_string_free (&argv0);
1554
1555   if (sitter)
1556     _dbus_babysitter_unref (sitter);
1557
1558   if (!dbus_error_is_set (&error))
1559     {
1560       _dbus_warn ("Did not get an error launching segfaulting binary\n");
1561       return FALSE;
1562     }
1563
1564   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1565         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1566     {
1567       _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n",
1568                   error.name, error.message);
1569       dbus_error_free (&error);
1570       return FALSE;
1571     }
1572
1573   dbus_error_free (&error);
1574   
1575   return TRUE;
1576 }
1577
1578 static dbus_bool_t
1579 check_spawn_exit (void *data)
1580 {
1581   char *argv[4] = { NULL, NULL, NULL, NULL };
1582   DBusBabysitter *sitter = NULL;
1583   DBusError error = DBUS_ERROR_INIT;
1584   DBusString argv0;
1585
1586   /*** Test launching exit failure binary */
1587
1588   argv[0] = get_test_exec ("test-exit", &argv0);
1589
1590   if (argv[0] == NULL)
1591     {
1592       /* OOM was simulated, never mind */
1593       return TRUE;
1594     }
1595
1596   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_exit", argv,
1597                                          NULL, NULL, NULL,
1598                                          &error))
1599     {
1600       _dbus_babysitter_block_for_child_exit (sitter);
1601       _dbus_babysitter_set_child_exit_error (sitter, &error);
1602     }
1603
1604   _dbus_string_free (&argv0);
1605
1606   if (sitter)
1607     _dbus_babysitter_unref (sitter);
1608
1609   if (!dbus_error_is_set (&error))
1610     {
1611       _dbus_warn ("Did not get an error launching binary that exited with failure code\n");
1612       return FALSE;
1613     }
1614
1615   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1616         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
1617     {
1618       _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n",
1619                   error.name, error.message);
1620       dbus_error_free (&error);
1621       return FALSE;
1622     }
1623
1624   dbus_error_free (&error);
1625   
1626   return TRUE;
1627 }
1628
1629 static dbus_bool_t
1630 check_spawn_and_kill (void *data)
1631 {
1632   char *argv[4] = { NULL, NULL, NULL, NULL };
1633   DBusBabysitter *sitter = NULL;
1634   DBusError error = DBUS_ERROR_INIT;
1635   DBusString argv0;
1636
1637   /*** Test launching sleeping binary then killing it */
1638
1639   argv[0] = get_test_exec ("test-sleep-forever", &argv0);
1640
1641   if (argv[0] == NULL)
1642     {
1643       /* OOM was simulated, never mind */
1644       return TRUE;
1645     }
1646
1647   if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_and_kill", argv,
1648                                          NULL, NULL, NULL,
1649                                          &error))
1650     {
1651       _dbus_babysitter_kill_child (sitter);
1652       
1653       _dbus_babysitter_block_for_child_exit (sitter);
1654       
1655       _dbus_babysitter_set_child_exit_error (sitter, &error);
1656     }
1657
1658   _dbus_string_free (&argv0);
1659
1660   if (sitter)
1661     _dbus_babysitter_unref (sitter);
1662
1663   if (!dbus_error_is_set (&error))
1664     {
1665       _dbus_warn ("Did not get an error after killing spawned binary\n");
1666       return FALSE;
1667     }
1668
1669   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1670         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1671     {
1672       _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
1673                   error.name, error.message);
1674       dbus_error_free (&error);
1675       return FALSE;
1676     }
1677
1678   dbus_error_free (&error);
1679   
1680   return TRUE;
1681 }
1682
1683 dbus_bool_t
1684 _dbus_spawn_test (const char *test_data_dir)
1685 {
1686   if (!_dbus_test_oom_handling ("spawn_nonexistent",
1687                                 check_spawn_nonexistent,
1688                                 NULL))
1689     return FALSE;
1690
1691   if (!_dbus_test_oom_handling ("spawn_segfault",
1692                                 check_spawn_segfault,
1693                                 NULL))
1694     return FALSE;
1695
1696   if (!_dbus_test_oom_handling ("spawn_exit",
1697                                 check_spawn_exit,
1698                                 NULL))
1699     return FALSE;
1700
1701   if (!_dbus_test_oom_handling ("spawn_and_kill",
1702                                 check_spawn_and_kill,
1703                                 NULL))
1704     return FALSE;
1705   
1706   return TRUE;
1707 }
1708 #endif