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