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