2003-04-06 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / dbus / dbus-spawn.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-spawn.c Wrapper around fork/exec
3  * 
4  * Copyright (C) 2002, 2003  Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 1.2
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24 #include "dbus-spawn.h"
25 #include "dbus-sysdeps.h"
26 #include "dbus-internals.h"
27 #include "dbus-test.h"
28
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <signal.h>
32 #include <sys/wait.h>
33 #include <errno.h>
34
35 /**
36  * @addtogroup DBusInternalsUtils
37  * @{
38  */
39
40 /*
41  * I'm pretty sure this whole spawn file could be made simpler,
42  * if you thought about it a bit.
43  */
44
45 /**
46  * Enumeration for status of a read()
47  */
48 typedef enum
49 {
50   READ_STATUS_OK,    /**< Read succeeded */
51   READ_STATUS_ERROR, /**< Some kind of error */
52   READ_STATUS_EOF    /**< EOF returned */
53 } ReadStatus;
54
55 static ReadStatus
56 read_ints (int        fd,
57            int       *buf,
58            int        n_ints_in_buf,
59            int       *n_ints_read,
60            DBusError *error)
61 {
62   size_t bytes = 0;    
63   ReadStatus retval;
64   
65   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
66
67   retval = READ_STATUS_OK;
68   
69   while (TRUE)
70     {
71       size_t chunk;
72       size_t to_read;
73       
74     again:
75
76       to_read = sizeof (int) * n_ints_in_buf - bytes;
77
78       if (to_read == 0)
79         break;
80       
81       chunk = read (fd,
82                     ((char*)buf) + bytes,
83                     to_read);
84       
85       if (chunk < 0 && errno == EINTR)
86         goto again;
87           
88       if (chunk < 0)
89         {
90           dbus_set_error (error,
91                           DBUS_ERROR_SPAWN_FAILED,
92                           "Failed to read from child pipe (%s)",
93                           _dbus_strerror (errno));
94
95           retval = READ_STATUS_ERROR;
96           break;
97         }
98       else if (chunk == 0)
99         {
100           retval = READ_STATUS_EOF;
101           break; /* EOF */
102         }
103       else /* chunk > 0 */
104         bytes += chunk;
105     }
106
107   *n_ints_read = (int)(bytes / sizeof(int));
108
109   return retval;
110 }
111
112 static ReadStatus
113 read_pid (int        fd,
114           pid_t     *buf,
115           DBusError *error)
116 {
117   size_t bytes = 0;    
118   ReadStatus retval;
119   
120   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
121
122   retval = READ_STATUS_OK;
123   
124   while (TRUE)
125     {
126       size_t chunk;    
127       size_t to_read;
128       
129     again:
130       to_read = sizeof (pid_t) - bytes;
131
132       if (to_read == 0)
133         break;
134       
135       chunk = read (fd,
136                     ((char*)buf) + bytes,
137                     to_read);
138       if (chunk < 0 && errno == EINTR)
139         goto again;
140           
141       if (chunk < 0)
142         {
143           dbus_set_error (error,
144                           DBUS_ERROR_SPAWN_FAILED,
145                           "Failed to read from child pipe (%s)",
146                           _dbus_strerror (errno));
147
148           retval = READ_STATUS_ERROR;
149           break;
150         }
151       else if (chunk == 0)
152         {
153           retval = READ_STATUS_EOF;
154           break; /* EOF */
155         }
156       else /* chunk > 0 */
157         bytes += chunk;
158     }
159
160   return retval;
161 }
162
163 /* The implementation uses an intermediate child between the main process
164  * and the grandchild. The grandchild is our spawned process. The intermediate
165  * child is a babysitter process; it keeps track of when the grandchild
166  * exits/crashes, and reaps the grandchild.
167  */
168
169 /* Messages from children to parents */
170 enum
171 {
172   CHILD_EXITED,            /* This message is followed by the exit status int */
173   CHILD_FORK_FAILED,       /* Followed by errno */
174   CHILD_EXEC_FAILED,       /* Followed by errno */
175   CHILD_PID                /* Followed by pid_t */
176 };
177
178 struct DBusBabysitter
179 {
180   int refcount;
181
182   char *executable; /**< executable name to use in error messages */
183   
184   int socket_to_babysitter;
185   int error_pipe_from_child;
186   
187   pid_t sitter_pid;
188   pid_t grandchild_pid;
189
190   DBusWatchList *watches;
191
192   DBusWatch *error_watch;
193   DBusWatch *sitter_watch;
194
195   int errnum;
196   int status;
197   unsigned int have_child_status : 1;
198   unsigned int have_fork_errnum : 1;
199   unsigned int have_exec_errnum : 1;
200 };
201
202 static DBusBabysitter*
203 _dbus_babysitter_new (void)
204 {
205   DBusBabysitter *sitter;
206
207   sitter = dbus_new0 (DBusBabysitter, 1);
208   if (sitter == NULL)
209     return NULL;
210
211   sitter->refcount = 1;
212
213   sitter->socket_to_babysitter = -1;
214   sitter->error_pipe_from_child = -1;
215   
216   sitter->sitter_pid = -1;
217   sitter->grandchild_pid = -1;
218
219   sitter->watches = _dbus_watch_list_new ();
220   if (sitter->watches == NULL)
221     goto failed;
222   
223   return sitter;
224
225  failed:
226   _dbus_babysitter_unref (sitter);
227   return NULL;
228 }
229
230 /**
231  * Increment the reference count on the babysitter object.
232  *
233  * @param sitter the babysitter
234  */
235 void
236 _dbus_babysitter_ref (DBusBabysitter *sitter)
237 {
238   _dbus_assert (sitter != NULL);
239   _dbus_assert (sitter->refcount > 0);
240   
241   sitter->refcount += 1;
242 }
243
244 /**
245  * Decrement the reference count on the babysitter object.
246  *
247  * @param sitter the babysitter
248  */
249 void
250 _dbus_babysitter_unref (DBusBabysitter *sitter)
251 {
252   _dbus_assert (sitter != NULL);
253   _dbus_assert (sitter->refcount > 0);
254   
255   sitter->refcount -= 1;
256   if (sitter->refcount == 0)
257     {      
258       if (sitter->socket_to_babysitter >= 0)
259         {
260           close (sitter->socket_to_babysitter);
261           sitter->socket_to_babysitter = -1;
262         }
263
264       if (sitter->error_pipe_from_child >= 0)
265         {
266           close (sitter->error_pipe_from_child);
267           sitter->error_pipe_from_child = -1;
268         }
269
270       if (sitter->sitter_pid != -1)
271         {
272           int status;
273           int ret;
274
275           /* Reap the babysitter */
276         again:
277           ret = waitpid (sitter->sitter_pid, &status, 0);
278           if (ret < 0)
279             {
280               if (errno == EINTR)
281                 goto again;
282               else if (errno == ECHILD)
283                 _dbus_warn ("Babysitter process not available to be reaped; should not happen\n");
284               else
285                 _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s\n",
286                             errno, _dbus_strerror (errno));
287             }
288           else
289             {
290               if (WIFEXITED (sitter->status))
291                 _dbus_verbose ("Babysitter exited with status %d\n",
292                                WEXITSTATUS (sitter->status));
293               else if (WIFSIGNALED (sitter->status))
294                 _dbus_verbose ("Babysitter received signal %d\n",
295                                WTERMSIG (sitter->status));
296               else
297                 _dbus_verbose ("Babysitter exited abnormally\n");
298             }
299
300           sitter->sitter_pid = -1;
301         }
302       
303       if (sitter->error_watch)
304         {
305           _dbus_watch_invalidate (sitter->error_watch);
306           _dbus_watch_unref (sitter->error_watch);
307           sitter->error_watch = NULL;
308         }
309
310       if (sitter->sitter_watch)
311         {
312           _dbus_watch_invalidate (sitter->sitter_watch);
313           _dbus_watch_unref (sitter->sitter_watch);
314           sitter->sitter_watch = NULL;
315         }
316       
317       if (sitter->watches)
318         _dbus_watch_list_free (sitter->watches);
319
320       dbus_free (sitter->executable);
321       
322       dbus_free (sitter);
323     }
324 }
325
326 static ReadStatus
327 read_data (DBusBabysitter *sitter,
328            int             fd)
329 {
330   int what;
331   int got;
332   DBusError error;
333   ReadStatus r;
334   
335   dbus_error_init (&error);
336   
337   r = read_ints (fd, &what, 1, &got, &error);
338
339   switch (r)
340     {
341     case READ_STATUS_ERROR:
342       _dbus_warn ("Failed to read data from fd %d: %s\n", fd, error.message);
343       dbus_error_free (&error);
344       return r;
345
346     case READ_STATUS_EOF:
347       return r;
348
349     case READ_STATUS_OK:
350       break;
351     }
352   
353   if (got == 1)
354     {
355       switch (what)
356         {
357         case CHILD_EXITED:
358         case CHILD_FORK_FAILED:
359         case CHILD_EXEC_FAILED:
360           {
361             int arg;
362             
363             r = read_ints (fd, &arg, 1, &got, &error);
364
365             switch (r)
366               {
367               case READ_STATUS_ERROR:
368                 _dbus_warn ("Failed to read arg from fd %d: %s\n", fd, error.message);
369                 dbus_error_free (&error);
370                 return r;
371               case READ_STATUS_EOF:
372                 return r;
373               case READ_STATUS_OK:
374                 break;
375               }
376             
377             if (got == 1)
378               {
379                 if (what == CHILD_EXITED)
380                   {
381                     sitter->have_child_status = TRUE;
382                     sitter->status = arg;
383                     _dbus_verbose ("recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n",
384                                    WIFEXITED (sitter->status), WIFSIGNALED (sitter->status),
385                                    WEXITSTATUS (sitter->status), WTERMSIG (sitter->status));
386                   }
387                 else if (what == CHILD_FORK_FAILED)
388                   {
389                     sitter->have_fork_errnum = TRUE;
390                     sitter->errnum = arg;
391                     _dbus_verbose ("recorded fork errnum %d\n", sitter->errnum);
392                   }
393                 else if (what == CHILD_EXEC_FAILED)
394                   {
395                     sitter->have_exec_errnum = TRUE;
396                     sitter->errnum = arg;
397                     _dbus_verbose ("recorded exec errnum %d\n", sitter->errnum);
398                   }
399               }
400           }
401           break;
402         case CHILD_PID:
403           {
404             pid_t pid = -1;
405
406             r = read_pid (fd, &pid, &error);
407             
408             switch (r)
409               {
410               case READ_STATUS_ERROR:
411                 _dbus_warn ("Failed to read PID from fd %d: %s\n", fd, error.message);
412                 dbus_error_free (&error);
413                 return r;
414               case READ_STATUS_EOF:
415                 return r;
416               case READ_STATUS_OK:
417                 break;
418               }
419             
420             sitter->grandchild_pid = pid;
421             
422             _dbus_verbose ("recorded grandchild pid %d\n", sitter->grandchild_pid);
423           }
424           break;
425         default:
426           _dbus_warn ("Unknown message received from babysitter process\n");
427           break;
428         }
429     }
430
431   return r;
432 }
433
434 static void
435 close_socket_to_babysitter (DBusBabysitter *sitter)
436 {
437   _dbus_verbose ("Closing babysitter\n");
438   close (sitter->socket_to_babysitter);
439   sitter->socket_to_babysitter = -1;
440 }
441
442 static void
443 close_error_pipe_from_child (DBusBabysitter *sitter)
444 {
445   _dbus_verbose ("Closing child error\n");
446   close (sitter->error_pipe_from_child);
447   sitter->error_pipe_from_child = -1;
448 }
449
450 static void
451 handle_babysitter_socket (DBusBabysitter *sitter,
452                           int             revents)
453 {
454   /* Even if we have POLLHUP, we want to keep reading
455    * data until POLLIN goes away; so this function only
456    * looks at HUP/ERR if no IN is set.
457    */
458   if (revents & _DBUS_POLLIN)
459     {
460       _dbus_verbose ("Reading data from babysitter\n");
461       if (read_data (sitter, sitter->socket_to_babysitter) != READ_STATUS_OK)
462         close_socket_to_babysitter (sitter);
463     }
464   else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
465     {
466       close_socket_to_babysitter (sitter);
467     }
468 }
469
470 static void
471 handle_error_pipe (DBusBabysitter *sitter,
472                    int             revents)
473 {
474   if (revents & _DBUS_POLLIN)
475     {
476       _dbus_verbose ("Reading data from child error\n");
477       if (read_data (sitter, sitter->error_pipe_from_child) != READ_STATUS_OK)
478         close_error_pipe_from_child (sitter);
479     }
480   else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
481     {
482       close_error_pipe_from_child (sitter);
483     }
484 }
485
486 /* returns whether there were any poll events handled */
487 static dbus_bool_t
488 babysitter_iteration (DBusBabysitter *sitter,
489                       dbus_bool_t     block)
490 {
491   DBusPollFD fds[2];
492   int i;
493   dbus_bool_t descriptors_ready;
494
495   descriptors_ready = FALSE;
496   
497   i = 0;
498
499   if (sitter->error_pipe_from_child >= 0)
500     {
501       fds[i].fd = sitter->error_pipe_from_child;
502       fds[i].events = _DBUS_POLLIN;
503       fds[i].revents = 0;
504       ++i;
505     }
506   
507   if (sitter->socket_to_babysitter >= 0)
508     {
509       fds[i].fd = sitter->socket_to_babysitter;
510       fds[i].events = _DBUS_POLLIN;
511       fds[i].revents = 0;
512       ++i;
513     }
514
515   if (i > 0)
516     {
517       int ret;
518
519       ret = _dbus_poll (fds, i, 0);
520       if (ret == 0 && block)
521         ret = _dbus_poll (fds, i, -1);
522       
523       if (ret > 0)
524         {
525           descriptors_ready = TRUE;
526           
527           while (i > 0)
528             {
529               --i;
530               if (fds[i].fd == sitter->error_pipe_from_child)
531                 handle_error_pipe (sitter, fds[i].revents);
532               else if (fds[i].fd == sitter->socket_to_babysitter)
533                 handle_babysitter_socket (sitter, fds[i].revents);
534             }
535         }
536     }
537
538   return descriptors_ready;
539 }
540
541 /**
542  * Macro returns #TRUE if the babysitter still has live sockets open to the
543  * babysitter child or the grandchild.
544  */
545 #define LIVE_CHILDREN(sitter) ((sitter)->socket_to_babysitter >= 0 || (sitter)->error_pipe_from_child >= 0)
546
547
548 /**
549  * Blocks until the babysitter process gives us the PID of the spawned grandchild,
550  * then kills the spawned grandchild.
551  *
552  * @param sitter the babysitter object
553  */
554 void
555 _dbus_babysitter_kill_child (DBusBabysitter *sitter)
556 {
557   /* be sure we have the PID of the child */
558   while (LIVE_CHILDREN (sitter) &&
559          sitter->grandchild_pid == -1)
560     babysitter_iteration (sitter, TRUE);
561
562   if (sitter->grandchild_pid == -1)
563     return; /* child is already dead, or we're so hosed we'll never recover */
564
565   kill (sitter->grandchild_pid, SIGKILL);
566 }
567
568 /**
569  * Checks whether the child has exited, without blocking.
570  *
571  * @param sitter the babysitter
572  */
573 dbus_bool_t
574 _dbus_babysitter_get_child_exited (DBusBabysitter *sitter)
575 {
576
577   /* Be sure we're up-to-date */
578   while (LIVE_CHILDREN (sitter) &&
579          babysitter_iteration (sitter, FALSE))
580     ;
581
582   /* We will have exited the babysitter when the child has exited */
583   return sitter->socket_to_babysitter < 0;
584 }
585
586 static void
587 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter)
588 {
589   while (LIVE_CHILDREN (sitter))
590     babysitter_iteration (sitter, TRUE);
591 }
592
593 /**
594  * Sets the #DBusError with an explanation of why the spawned
595  * child process exited (on a signal, or whatever). If
596  * the child process has not exited, does nothing (error
597  * will remain unset).
598  *
599  * @param sitter the babysitter
600  * @param error an error to fill in
601  */
602 void
603 _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
604                                        DBusError      *error)
605 {
606   if (!_dbus_babysitter_get_child_exited (sitter))
607     return;
608
609   /* Note that if exec fails, we will also get a child status
610    * from the babysitter saying the child exited,
611    * so we need to give priority to the exec error
612    */
613   if (sitter->have_exec_errnum)
614     {
615       dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
616                       "Failed to execute program %s: %s",
617                       sitter->executable, _dbus_strerror (sitter->errnum));
618     }
619   else if (sitter->have_fork_errnum)
620     {
621       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
622                       "Failed to fork a new process %s: %s",
623                       sitter->executable, _dbus_strerror (sitter->errnum));
624     }
625   else if (sitter->have_child_status)
626     {
627       if (WIFEXITED (sitter->status))
628         dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
629                         "Process %s exited with status %d",
630                         sitter->executable, WEXITSTATUS (sitter->status));
631       else if (WIFSIGNALED (sitter->status))
632         dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED,
633                         "Process %s received signal %d",
634                         sitter->executable, WTERMSIG (sitter->status));
635       else
636         dbus_set_error (error, DBUS_ERROR_FAILED,
637                         "Process %s exited abnormally",
638                         sitter->executable);
639     }
640   else
641     {
642       dbus_set_error (error, DBUS_ERROR_FAILED,
643                       "Process %s exited, reason unknown",
644                       sitter->executable);
645     }
646 }
647
648 /**
649  * Sets watch functions to notify us when the
650  * babysitter object needs to read/write file descriptors.
651  *
652  * @param sitter the babysitter
653  * @param add_function function to begin monitoring a new descriptor.
654  * @param remove_function function to stop monitoring a descriptor.
655  * @param toggled_function function to notify when the watch is enabled/disabled
656  * @param data data to pass to add_function and remove_function.
657  * @param free_data_function function to be called to free the data.
658  * @returns #FALSE on failure (no memory)
659  */
660 dbus_bool_t
661 _dbus_babysitter_set_watch_functions (DBusBabysitter            *sitter,
662                                       DBusAddWatchFunction       add_function,
663                                       DBusRemoveWatchFunction    remove_function,
664                                       DBusWatchToggledFunction   toggled_function,
665                                       void                      *data,
666                                       DBusFreeFunction           free_data_function)
667 {
668   return _dbus_watch_list_set_functions (sitter->watches,
669                                          add_function,
670                                          remove_function,
671                                          toggled_function,
672                                          data,
673                                          free_data_function);
674 }
675
676 /**
677  * Handles watch when descriptors are ready.
678  *
679  * @param sitter the babysitter.
680  * @param watch the watch object
681  * @param condition the descriptor conditions
682  * @returns #FALSE if there wasn't enough memory.
683  * 
684  */
685 dbus_bool_t
686 _dbus_babysitter_handle_watch (DBusBabysitter  *sitter,
687                                DBusWatch       *watch,
688                                unsigned int     condition)
689 {
690   int revents;
691   int fd;
692   
693   revents = 0;
694   if (condition & DBUS_WATCH_READABLE)
695     revents |= _DBUS_POLLIN;
696   if (condition & DBUS_WATCH_ERROR)
697     revents |= _DBUS_POLLERR;
698   if (condition & DBUS_WATCH_HANGUP)
699     revents |= _DBUS_POLLHUP;
700
701   fd = dbus_watch_get_fd (watch);
702
703   if (fd == sitter->error_pipe_from_child)
704     handle_error_pipe (sitter, revents);
705   else if (fd == sitter->socket_to_babysitter)
706     handle_babysitter_socket (sitter, revents);
707
708   while (LIVE_CHILDREN (sitter) &&
709          babysitter_iteration (sitter, FALSE))
710     ;
711   
712   return TRUE;
713 }
714
715 /** Helps remember which end of the pipe is which */
716 #define READ_END 0
717 /** Helps remember which end of the pipe is which */
718 #define WRITE_END 1
719
720
721 /* Avoids a danger in threaded situations (calling close()
722  * on a file descriptor twice, and another thread has
723  * re-opened it since the first close)
724  */
725 static int
726 close_and_invalidate (int *fd)
727 {
728   int ret;
729
730   if (*fd < 0)
731     return -1;
732   else
733     {
734       ret = close (*fd);
735       *fd = -1;
736     }
737
738   return ret;
739 }
740
741 static dbus_bool_t
742 make_pipe (int         p[2],
743            DBusError  *error)
744 {
745   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
746   
747   if (pipe (p) < 0)
748     {
749       dbus_set_error (error,
750                       DBUS_ERROR_SPAWN_FAILED,
751                       "Failed to create pipe for communicating with child process (%s)",
752                       _dbus_strerror (errno));
753       return FALSE;
754     }
755
756   return TRUE;
757 }
758
759 static void
760 do_write (int fd, const void *buf, size_t count)
761 {
762   size_t bytes_written;
763   int ret;
764   
765   bytes_written = 0;
766   
767  again:
768   
769   ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
770
771   if (ret < 0)
772     {
773       if (errno == EINTR)
774         goto again;
775       else
776         {
777           _dbus_warn ("Failed to write data to pipe!\n");
778           _exit (1); /* give up, we suck */
779         }
780     }
781   else
782     bytes_written += ret;
783   
784   if (bytes_written < count)
785     goto again;
786 }
787
788 static void
789 write_err_and_exit (int fd, int msg)
790 {
791   int en = errno;
792
793   do_write (fd, &msg, sizeof (msg));
794   do_write (fd, &en, sizeof (en));
795   
796   _exit (1);
797 }
798
799 static void
800 write_pid (int fd, pid_t pid)
801 {
802   int msg = CHILD_PID;
803   
804   do_write (fd, &msg, sizeof (msg));
805   do_write (fd, &pid, sizeof (pid));
806 }
807
808 static void
809 write_status_and_exit (int fd, int status)
810 {
811   int msg = CHILD_EXITED;
812   
813   do_write (fd, &msg, sizeof (msg));
814   do_write (fd, &status, sizeof (status));
815   
816   _exit (0);
817 }
818
819 static void
820 do_exec (int                       child_err_report_fd,
821          char                    **argv,
822          DBusSpawnChildSetupFunc   child_setup,
823          void                     *user_data)
824 {
825 #ifdef DBUS_BUILD_TESTS
826   int i, max_open;
827 #endif
828
829   if (child_setup)
830     (* child_setup) (user_data);
831
832 #ifdef DBUS_BUILD_TESTS
833   max_open = sysconf (_SC_OPEN_MAX);
834   
835   for (i = 3; i < max_open; i++)
836     {
837       int retval;
838
839       if (i == child_err_report_fd)
840         continue;
841       
842       retval = fcntl (i, F_GETFD);
843
844       if (retval != -1 && !(retval & FD_CLOEXEC))
845         _dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i);
846     }
847 #endif
848   
849   execv (argv[0], argv);
850   
851   /* Exec failed */
852   write_err_and_exit (child_err_report_fd,
853                       CHILD_EXEC_FAILED);
854 }
855
856 static void
857 check_babysit_events (pid_t grandchild_pid,
858                       int   parent_pipe,
859                       int   revents)
860 {
861   pid_t ret;
862   int status;
863   
864   ret = waitpid (grandchild_pid, &status, WNOHANG);
865
866   if (ret == 0)
867     {
868       _dbus_verbose ("no child exited\n");
869       
870       ; /* no child exited */
871     }
872   else if (ret < 0)
873     {
874       /* This isn't supposed to happen. */
875       _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s\n",
876                   _dbus_strerror (errno));
877       _exit (1);
878     }
879   else if (ret == grandchild_pid)
880     {
881       /* Child exited */
882       write_status_and_exit (parent_pipe, status);
883     }
884   else
885     {
886       _dbus_warn ("waitpid() reaped pid %d that we've never heard of\n",
887                   (int) ret);
888       _exit (1);
889     }
890
891   if (revents & _DBUS_POLLIN)
892     {
893       /* Data to read from parent */
894
895     }
896
897   if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
898     {
899       /* Parent is gone, so we just exit */
900       _exit (0);
901     }
902 }
903
904 static int babysit_sigchld_pipe = -1;
905
906 static void
907 babysit_signal_handler (int signo)
908 {
909   char b = '\0';
910  again:
911   write (babysit_sigchld_pipe, &b, 1);
912   if (errno == EINTR)
913     goto again;
914 }
915
916 static void
917 babysit (pid_t grandchild_pid,
918          int   parent_pipe)
919 {
920   int sigchld_pipe[2];
921
922   /* I thought SIGCHLD would just wake up the poll, but
923    * that didn't seem to work, so added this pipe.
924    * Probably the pipe is more likely to work on busted
925    * operating systems anyhow.
926    */
927   if (pipe (sigchld_pipe) < 0)
928     {
929       _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n");
930       _exit (1);
931     }
932
933   babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
934
935   _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler);
936   
937   write_pid (parent_pipe, grandchild_pid);
938
939   check_babysit_events (grandchild_pid, parent_pipe, 0);
940
941   while (TRUE)
942     {
943       DBusPollFD pfds[2];
944       
945       pfds[0].fd = parent_pipe;
946       pfds[0].events = _DBUS_POLLIN;
947       pfds[0].revents = 0;
948
949       pfds[1].fd = sigchld_pipe[READ_END];
950       pfds[1].events = _DBUS_POLLIN;
951       pfds[1].revents = 0;
952       
953       _dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1);
954
955       if (pfds[0].revents != 0)
956         {
957           check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents);
958         }
959       else if (pfds[1].revents & _DBUS_POLLIN)
960         {
961           char b;
962           read (sigchld_pipe[READ_END], &b, 1);
963           /* do waitpid check */
964           check_babysit_events (grandchild_pid, parent_pipe, 0);
965         }
966     }
967   
968   _exit (1);
969 }
970
971 /**
972  * Spawns a new process. The executable name and argv[0]
973  * are the same, both are provided in argv[0]. The child_setup
974  * function is passed the given user_data and is run in the child
975  * just before calling exec().
976  *
977  * Also creates a "babysitter" which tracks the status of the
978  * child process, advising the parent if the child exits.
979  * If the spawn fails, no babysitter is created.
980  * If sitter_p is #NULL, no babysitter is kept.
981  *
982  * @param sitter_p return location for babysitter or #NULL
983  * @param argv the executable and arguments
984  * @param child_setup function to call in child pre-exec()
985  * @param user_data user data for setup function
986  * @param error error object to be filled in if function fails
987  * @returns #TRUE on success, #FALSE if error is filled in
988  */
989 dbus_bool_t
990 _dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
991                                    char                    **argv,
992                                    DBusSpawnChildSetupFunc   child_setup,
993                                    void                     *user_data,
994                                    DBusError                *error)
995 {
996   DBusBabysitter *sitter;
997   int child_err_report_pipe[2] = { -1, -1 };
998   int babysitter_pipe[2] = { -1, -1 };
999   pid_t pid;
1000   
1001   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1002
1003   *sitter_p = NULL;
1004   sitter = NULL;
1005
1006   sitter = _dbus_babysitter_new ();
1007   if (sitter == NULL)
1008     {
1009       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1010       return FALSE;
1011     }
1012
1013   sitter->executable = _dbus_strdup (argv[0]);
1014   if (sitter->executable == NULL)
1015     {
1016       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1017       goto cleanup_and_fail;
1018     }
1019   
1020   if (!make_pipe (child_err_report_pipe, error))
1021     goto cleanup_and_fail;
1022
1023   _dbus_fd_set_close_on_exec (child_err_report_pipe[READ_END]);
1024   
1025   if (!_dbus_full_duplex_pipe (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
1026     goto cleanup_and_fail;
1027
1028   _dbus_fd_set_close_on_exec (babysitter_pipe[0]);
1029   _dbus_fd_set_close_on_exec (babysitter_pipe[1]);
1030   
1031   pid = fork ();
1032   
1033   if (pid < 0)
1034     {
1035       dbus_set_error (error,
1036                       DBUS_ERROR_SPAWN_FORK_FAILED,
1037                       "Failed to fork (%s)",
1038                       _dbus_strerror (errno));
1039       goto cleanup_and_fail;
1040     }
1041   else if (pid == 0)
1042     {
1043       /* Immediate child, this is the babysitter process. */
1044       int grandchild_pid;
1045       
1046       /* Be sure we crash if the parent exits
1047        * and we write to the err_report_pipe
1048        */
1049       signal (SIGPIPE, SIG_DFL);
1050
1051       /* Close the parent's end of the pipes. */
1052       close_and_invalidate (&child_err_report_pipe[READ_END]);
1053       close_and_invalidate (&babysitter_pipe[0]);
1054       
1055       /* Create the child that will exec () */
1056       grandchild_pid = fork ();
1057       
1058       if (grandchild_pid < 0)
1059         {
1060           write_err_and_exit (babysitter_pipe[1],
1061                               CHILD_FORK_FAILED);
1062           _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
1063         }
1064       else if (grandchild_pid == 0)
1065         {
1066           do_exec (child_err_report_pipe[WRITE_END],
1067                    argv,
1068                    child_setup, user_data);
1069           _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
1070         }
1071       else
1072         {
1073           babysit (grandchild_pid, babysitter_pipe[1]);
1074           _dbus_assert_not_reached ("Got to code after babysit()");
1075         }
1076     }
1077   else
1078     {
1079       /* Parent */
1080       sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
1081                                              DBUS_WATCH_READABLE,
1082                                              TRUE);
1083       if (sitter->error_watch == NULL)
1084         {
1085           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1086           goto cleanup_and_fail;
1087         }
1088         
1089       if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->error_watch))
1090         {
1091           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1092           goto cleanup_and_fail;
1093         }
1094       
1095       sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0],
1096                                               DBUS_WATCH_READABLE,
1097                                               TRUE);
1098       if (sitter->sitter_watch == NULL)
1099         {
1100           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1101           goto cleanup_and_fail;
1102         }
1103       
1104       if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->sitter_watch))
1105         {
1106           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1107           goto cleanup_and_fail;
1108         }
1109       
1110       /* Close the uncared-about ends of the pipes */
1111       close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1112       close_and_invalidate (&babysitter_pipe[1]);
1113
1114       sitter->socket_to_babysitter = babysitter_pipe[0];
1115       babysitter_pipe[0] = -1;
1116       
1117       sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
1118       child_err_report_pipe[READ_END] = -1;
1119
1120       sitter->sitter_pid = pid;
1121
1122       if (sitter_p != NULL)
1123         *sitter_p = sitter;
1124       else
1125         _dbus_babysitter_unref (sitter);
1126
1127       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1128       
1129       return TRUE;
1130     }
1131
1132  cleanup_and_fail:
1133
1134   _DBUS_ASSERT_ERROR_IS_SET (error);
1135   
1136   close_and_invalidate (&child_err_report_pipe[READ_END]);
1137   close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1138   close_and_invalidate (&babysitter_pipe[0]);
1139   close_and_invalidate (&babysitter_pipe[1]);
1140
1141   if (sitter != NULL)
1142     _dbus_babysitter_unref (sitter);
1143   
1144   return FALSE;
1145 }
1146
1147 /** @} */
1148
1149 #ifdef DBUS_BUILD_TESTS
1150
1151 static dbus_bool_t
1152 check_spawn_nonexistent (void *data)
1153 {
1154   char *argv[4] = { NULL, NULL, NULL, NULL };
1155   DBusBabysitter *sitter;
1156   DBusError error;
1157   
1158   sitter = NULL;
1159   
1160   dbus_error_init (&error);
1161
1162   /*** Test launching nonexistent binary */
1163   
1164   argv[0] = "/this/does/not/exist/32542sdgafgafdg";
1165   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1166                                          NULL, NULL,
1167                                          &error))
1168     {
1169       _dbus_babysitter_block_for_child_exit (sitter);
1170       _dbus_babysitter_set_child_exit_error (sitter, &error);
1171     }
1172
1173   if (sitter)
1174     _dbus_babysitter_unref (sitter);
1175
1176   if (!dbus_error_is_set (&error))
1177     {
1178       _dbus_warn ("Did not get an error launching nonexistent executable\n");
1179       return FALSE;
1180     }
1181
1182   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1183         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
1184     {
1185       _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n",
1186                   error.name, error.message);
1187       dbus_error_free (&error);
1188       return FALSE;
1189     }
1190
1191   dbus_error_free (&error);
1192   
1193   return TRUE;
1194 }
1195
1196 static dbus_bool_t
1197 check_spawn_segfault (void *data)
1198 {
1199   char *argv[4] = { NULL, NULL, NULL, NULL };
1200   DBusBabysitter *sitter;
1201   DBusError error;
1202   
1203   sitter = NULL;
1204   
1205   dbus_error_init (&error);
1206
1207   /*** Test launching segfault binary */
1208   
1209   argv[0] = TEST_SEGFAULT_BINARY;
1210   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1211                                          NULL, NULL,
1212                                          &error))
1213     {
1214       _dbus_babysitter_block_for_child_exit (sitter);
1215       _dbus_babysitter_set_child_exit_error (sitter, &error);
1216     }
1217
1218   if (sitter)
1219     _dbus_babysitter_unref (sitter);
1220
1221   if (!dbus_error_is_set (&error))
1222     {
1223       _dbus_warn ("Did not get an error launching segfaulting binary\n");
1224       return FALSE;
1225     }
1226
1227   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1228         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1229     {
1230       _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n",
1231                   error.name, error.message);
1232       dbus_error_free (&error);
1233       return FALSE;
1234     }
1235
1236   dbus_error_free (&error);
1237   
1238   return TRUE;
1239 }
1240
1241 static dbus_bool_t
1242 check_spawn_exit (void *data)
1243 {
1244   char *argv[4] = { NULL, NULL, NULL, NULL };
1245   DBusBabysitter *sitter;
1246   DBusError error;
1247   
1248   sitter = NULL;
1249   
1250   dbus_error_init (&error);
1251
1252   /*** Test launching exit failure binary */
1253   
1254   argv[0] = TEST_EXIT_BINARY;
1255   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1256                                          NULL, NULL,
1257                                          &error))
1258     {
1259       _dbus_babysitter_block_for_child_exit (sitter);
1260       _dbus_babysitter_set_child_exit_error (sitter, &error);
1261     }
1262
1263   if (sitter)
1264     _dbus_babysitter_unref (sitter);
1265
1266   if (!dbus_error_is_set (&error))
1267     {
1268       _dbus_warn ("Did not get an error launching binary that exited with failure code\n");
1269       return FALSE;
1270     }
1271
1272   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1273         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
1274     {
1275       _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n",
1276                   error.name, error.message);
1277       dbus_error_free (&error);
1278       return FALSE;
1279     }
1280
1281   dbus_error_free (&error);
1282   
1283   return TRUE;
1284 }
1285
1286 static dbus_bool_t
1287 check_spawn_and_kill (void *data)
1288 {
1289   char *argv[4] = { NULL, NULL, NULL, NULL };
1290   DBusBabysitter *sitter;
1291   DBusError error;
1292   
1293   sitter = NULL;
1294   
1295   dbus_error_init (&error);
1296
1297   /*** Test launching sleeping binary then killing it */
1298
1299   argv[0] = TEST_SLEEP_FOREVER_BINARY;
1300   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1301                                          NULL, NULL,
1302                                          &error))
1303     {
1304       _dbus_babysitter_kill_child (sitter);
1305       
1306       _dbus_babysitter_block_for_child_exit (sitter);
1307       
1308       _dbus_babysitter_set_child_exit_error (sitter, &error);
1309     }
1310
1311   if (sitter)
1312     _dbus_babysitter_unref (sitter);
1313
1314   if (!dbus_error_is_set (&error))
1315     {
1316       _dbus_warn ("Did not get an error after killing spawned binary\n");
1317       return FALSE;
1318     }
1319
1320   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1321         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1322     {
1323       _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
1324                   error.name, error.message);
1325       dbus_error_free (&error);
1326       return FALSE;
1327     }
1328
1329   dbus_error_free (&error);
1330   
1331   return TRUE;
1332 }
1333
1334 dbus_bool_t
1335 _dbus_spawn_test (const char *test_data_dir)
1336 {
1337   if (!_dbus_test_oom_handling ("spawn_nonexistent",
1338                                 check_spawn_nonexistent,
1339                                 NULL))
1340     return FALSE;
1341
1342   if (!_dbus_test_oom_handling ("spawn_segfault",
1343                                 check_spawn_segfault,
1344                                 NULL))
1345     return FALSE;
1346
1347   if (!_dbus_test_oom_handling ("spawn_exit",
1348                                 check_spawn_exit,
1349                                 NULL))
1350     return FALSE;
1351
1352   if (!_dbus_test_oom_handling ("spawn_and_kill",
1353                                 check_spawn_and_kill,
1354                                 NULL))
1355     return FALSE;
1356   
1357   return TRUE;
1358 }
1359 #endif