2003-04-10 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  * Blocks until the babysitter process gives us the PID of the spawned grandchild,
549  * then kills the spawned grandchild.
550  *
551  * @param sitter the babysitter object
552  */
553 void
554 _dbus_babysitter_kill_child (DBusBabysitter *sitter)
555 {
556   /* be sure we have the PID of the child */
557   while (LIVE_CHILDREN (sitter) &&
558          sitter->grandchild_pid == -1)
559     babysitter_iteration (sitter, TRUE);
560
561   _dbus_verbose ("Got child PID %ld for killing\n",
562                  (long) sitter->grandchild_pid);
563   
564   if (sitter->grandchild_pid == -1)
565     return; /* child is already dead, or we're so hosed we'll never recover */
566
567   kill (sitter->grandchild_pid, SIGKILL);
568 }
569
570 /**
571  * Checks whether the child has exited, without blocking.
572  *
573  * @param sitter the babysitter
574  */
575 dbus_bool_t
576 _dbus_babysitter_get_child_exited (DBusBabysitter *sitter)
577 {
578
579   /* Be sure we're up-to-date */
580   while (LIVE_CHILDREN (sitter) &&
581          babysitter_iteration (sitter, FALSE))
582     ;
583
584   /* We will have exited the babysitter when the child has exited */
585   return sitter->socket_to_babysitter < 0;
586 }
587
588 static void
589 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter)
590 {
591   while (LIVE_CHILDREN (sitter))
592     babysitter_iteration (sitter, TRUE);
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 /**
679  * Handles watch when descriptors are ready.
680  *
681  * @param sitter the babysitter.
682  * @param watch the watch object
683  * @param condition the descriptor conditions
684  * @returns #FALSE if there wasn't enough memory.
685  * 
686  */
687 dbus_bool_t
688 _dbus_babysitter_handle_watch (DBusBabysitter  *sitter,
689                                DBusWatch       *watch,
690                                unsigned int     condition)
691 {
692   int revents;
693   int fd;
694   
695   revents = 0;
696   if (condition & DBUS_WATCH_READABLE)
697     revents |= _DBUS_POLLIN;
698   if (condition & DBUS_WATCH_ERROR)
699     revents |= _DBUS_POLLERR;
700   if (condition & DBUS_WATCH_HANGUP)
701     revents |= _DBUS_POLLHUP;
702
703   fd = dbus_watch_get_fd (watch);
704
705   if (fd == sitter->error_pipe_from_child)
706     handle_error_pipe (sitter, revents);
707   else if (fd == sitter->socket_to_babysitter)
708     handle_babysitter_socket (sitter, revents);
709
710   while (LIVE_CHILDREN (sitter) &&
711          babysitter_iteration (sitter, FALSE))
712     ;
713   
714   return TRUE;
715 }
716
717 /** Helps remember which end of the pipe is which */
718 #define READ_END 0
719 /** Helps remember which end of the pipe is which */
720 #define WRITE_END 1
721
722
723 /* Avoids a danger in threaded situations (calling close()
724  * on a file descriptor twice, and another thread has
725  * re-opened it since the first close)
726  */
727 static int
728 close_and_invalidate (int *fd)
729 {
730   int ret;
731
732   if (*fd < 0)
733     return -1;
734   else
735     {
736       ret = close (*fd);
737       *fd = -1;
738     }
739
740   return ret;
741 }
742
743 static dbus_bool_t
744 make_pipe (int         p[2],
745            DBusError  *error)
746 {
747   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
748   
749   if (pipe (p) < 0)
750     {
751       dbus_set_error (error,
752                       DBUS_ERROR_SPAWN_FAILED,
753                       "Failed to create pipe for communicating with child process (%s)",
754                       _dbus_strerror (errno));
755       return FALSE;
756     }
757
758   return TRUE;
759 }
760
761 static void
762 do_write (int fd, const void *buf, size_t count)
763 {
764   size_t bytes_written;
765   int ret;
766   
767   bytes_written = 0;
768   
769  again:
770   
771   ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
772
773   if (ret < 0)
774     {
775       if (errno == EINTR)
776         goto again;
777       else
778         {
779           _dbus_warn ("Failed to write data to pipe!\n");
780           _exit (1); /* give up, we suck */
781         }
782     }
783   else
784     bytes_written += ret;
785   
786   if (bytes_written < count)
787     goto again;
788 }
789
790 static void
791 write_err_and_exit (int fd, int msg)
792 {
793   int en = errno;
794
795   do_write (fd, &msg, sizeof (msg));
796   do_write (fd, &en, sizeof (en));
797   
798   _exit (1);
799 }
800
801 static void
802 write_pid (int fd, pid_t pid)
803 {
804   int msg = CHILD_PID;
805   
806   do_write (fd, &msg, sizeof (msg));
807   do_write (fd, &pid, sizeof (pid));
808 }
809
810 static void
811 write_status_and_exit (int fd, int status)
812 {
813   int msg = CHILD_EXITED;
814   
815   do_write (fd, &msg, sizeof (msg));
816   do_write (fd, &status, sizeof (status));
817   
818   _exit (0);
819 }
820
821 static void
822 do_exec (int                       child_err_report_fd,
823          char                    **argv,
824          DBusSpawnChildSetupFunc   child_setup,
825          void                     *user_data)
826 {
827 #ifdef DBUS_BUILD_TESTS
828   int i, max_open;
829 #endif
830
831   _dbus_verbose_reset ();
832   _dbus_verbose ("Child process has PID %lu\n",
833                  _dbus_getpid ());
834   
835   if (child_setup)
836     (* child_setup) (user_data);
837
838 #ifdef DBUS_BUILD_TESTS
839   max_open = sysconf (_SC_OPEN_MAX);
840   
841   for (i = 3; i < max_open; i++)
842     {
843       int retval;
844
845       if (i == child_err_report_fd)
846         continue;
847       
848       retval = fcntl (i, F_GETFD);
849
850       if (retval != -1 && !(retval & FD_CLOEXEC))
851         _dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i);
852     }
853 #endif
854   
855   execv (argv[0], argv);
856   
857   /* Exec failed */
858   write_err_and_exit (child_err_report_fd,
859                       CHILD_EXEC_FAILED);
860 }
861
862 static void
863 check_babysit_events (pid_t grandchild_pid,
864                       int   parent_pipe,
865                       int   revents)
866 {
867   pid_t ret;
868   int status;
869   
870   ret = waitpid (grandchild_pid, &status, WNOHANG);
871
872   if (ret == 0)
873     {
874       _dbus_verbose ("no child exited\n");
875       
876       ; /* no child exited */
877     }
878   else if (ret < 0)
879     {
880       /* This isn't supposed to happen. */
881       _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s\n",
882                   _dbus_strerror (errno));
883       _exit (1);
884     }
885   else if (ret == grandchild_pid)
886     {
887       /* Child exited */
888       _dbus_verbose ("reaped child pid %ld\n", (long) ret);
889       
890       write_status_and_exit (parent_pipe, status);
891     }
892   else
893     {
894       _dbus_warn ("waitpid() reaped pid %d that we've never heard of\n",
895                   (int) ret);
896       _exit (1);
897     }
898
899   if (revents & _DBUS_POLLIN)
900     {
901       _dbus_verbose ("babysitter got POLLIN from parent pipe\n");
902     }
903
904   if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
905     {
906       /* Parent is gone, so we just exit */
907       _dbus_verbose ("babysitter got POLLERR or POLLHUP from parent\n");
908       _exit (0);
909     }
910 }
911
912 static int babysit_sigchld_pipe = -1;
913
914 static void
915 babysit_signal_handler (int signo)
916 {
917   char b = '\0';
918  again:
919   write (babysit_sigchld_pipe, &b, 1);
920   if (errno == EINTR)
921     goto again;
922 }
923
924 static void
925 babysit (pid_t grandchild_pid,
926          int   parent_pipe)
927 {
928   int sigchld_pipe[2];
929
930   /* We don't exec, so we keep parent state, such as the pid that
931    * _dbus_verbose() uses. Reset the pid here.
932    */
933   _dbus_verbose_reset ();
934   
935   /* I thought SIGCHLD would just wake up the poll, but
936    * that didn't seem to work, so added this pipe.
937    * Probably the pipe is more likely to work on busted
938    * operating systems anyhow.
939    */
940   if (pipe (sigchld_pipe) < 0)
941     {
942       _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n");
943       _exit (1);
944     }
945
946   babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
947
948   _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler);
949   
950   write_pid (parent_pipe, grandchild_pid);
951
952   check_babysit_events (grandchild_pid, parent_pipe, 0);
953
954   while (TRUE)
955     {
956       DBusPollFD pfds[2];
957       
958       pfds[0].fd = parent_pipe;
959       pfds[0].events = _DBUS_POLLIN;
960       pfds[0].revents = 0;
961
962       pfds[1].fd = sigchld_pipe[READ_END];
963       pfds[1].events = _DBUS_POLLIN;
964       pfds[1].revents = 0;
965       
966       _dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1);
967
968       if (pfds[0].revents != 0)
969         {
970           check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents);
971         }
972       else if (pfds[1].revents & _DBUS_POLLIN)
973         {
974           char b;
975           read (sigchld_pipe[READ_END], &b, 1);
976           /* do waitpid check */
977           check_babysit_events (grandchild_pid, parent_pipe, 0);
978         }
979     }
980   
981   _exit (1);
982 }
983
984 /**
985  * Spawns a new process. The executable name and argv[0]
986  * are the same, both are provided in argv[0]. The child_setup
987  * function is passed the given user_data and is run in the child
988  * just before calling exec().
989  *
990  * Also creates a "babysitter" which tracks the status of the
991  * child process, advising the parent if the child exits.
992  * If the spawn fails, no babysitter is created.
993  * If sitter_p is #NULL, no babysitter is kept.
994  *
995  * @param sitter_p return location for babysitter or #NULL
996  * @param argv the executable and arguments
997  * @param child_setup function to call in child pre-exec()
998  * @param user_data user data for setup function
999  * @param error error object to be filled in if function fails
1000  * @returns #TRUE on success, #FALSE if error is filled in
1001  */
1002 dbus_bool_t
1003 _dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
1004                                    char                    **argv,
1005                                    DBusSpawnChildSetupFunc   child_setup,
1006                                    void                     *user_data,
1007                                    DBusError                *error)
1008 {
1009   DBusBabysitter *sitter;
1010   int child_err_report_pipe[2] = { -1, -1 };
1011   int babysitter_pipe[2] = { -1, -1 };
1012   pid_t pid;
1013   
1014   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1015
1016   *sitter_p = NULL;
1017   sitter = NULL;
1018
1019   sitter = _dbus_babysitter_new ();
1020   if (sitter == NULL)
1021     {
1022       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1023       return FALSE;
1024     }
1025
1026   sitter->executable = _dbus_strdup (argv[0]);
1027   if (sitter->executable == NULL)
1028     {
1029       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1030       goto cleanup_and_fail;
1031     }
1032   
1033   if (!make_pipe (child_err_report_pipe, error))
1034     goto cleanup_and_fail;
1035
1036   _dbus_fd_set_close_on_exec (child_err_report_pipe[READ_END]);
1037   
1038   if (!_dbus_full_duplex_pipe (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
1039     goto cleanup_and_fail;
1040
1041   _dbus_fd_set_close_on_exec (babysitter_pipe[0]);
1042   _dbus_fd_set_close_on_exec (babysitter_pipe[1]);
1043
1044   /* Setting up the babysitter is only useful in the parent,
1045    * but we don't want to run out of memory and fail
1046    * after we've already forked, since then we'd leak
1047    * child processes everywhere.
1048    */
1049   sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
1050                                          DBUS_WATCH_READABLE,
1051                                          TRUE);
1052   if (sitter->error_watch == NULL)
1053     {
1054       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1055       goto cleanup_and_fail;
1056     }
1057         
1058   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->error_watch))
1059     {
1060       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1061       goto cleanup_and_fail;
1062     }
1063       
1064   sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0],
1065                                           DBUS_WATCH_READABLE,
1066                                           TRUE);
1067   if (sitter->sitter_watch == NULL)
1068     {
1069       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1070       goto cleanup_and_fail;
1071     }
1072       
1073   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->sitter_watch))
1074     {
1075       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1076       goto cleanup_and_fail;
1077     }
1078
1079   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1080   
1081   pid = fork ();
1082   
1083   if (pid < 0)
1084     {
1085       dbus_set_error (error,
1086                       DBUS_ERROR_SPAWN_FORK_FAILED,
1087                       "Failed to fork (%s)",
1088                       _dbus_strerror (errno));
1089       goto cleanup_and_fail;
1090     }
1091   else if (pid == 0)
1092     {
1093       /* Immediate child, this is the babysitter process. */
1094       int grandchild_pid;
1095       
1096       /* Be sure we crash if the parent exits
1097        * and we write to the err_report_pipe
1098        */
1099       signal (SIGPIPE, SIG_DFL);
1100
1101       /* Close the parent's end of the pipes. */
1102       close_and_invalidate (&child_err_report_pipe[READ_END]);
1103       close_and_invalidate (&babysitter_pipe[0]);
1104       
1105       /* Create the child that will exec () */
1106       grandchild_pid = fork ();
1107       
1108       if (grandchild_pid < 0)
1109         {
1110           write_err_and_exit (babysitter_pipe[1],
1111                               CHILD_FORK_FAILED);
1112           _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
1113         }
1114       else if (grandchild_pid == 0)
1115         {
1116           do_exec (child_err_report_pipe[WRITE_END],
1117                    argv,
1118                    child_setup, user_data);
1119           _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
1120         }
1121       else
1122         {
1123           babysit (grandchild_pid, babysitter_pipe[1]);
1124           _dbus_assert_not_reached ("Got to code after babysit()");
1125         }
1126     }
1127   else
1128     {      
1129       /* Close the uncared-about ends of the pipes */
1130       close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1131       close_and_invalidate (&babysitter_pipe[1]);
1132
1133       sitter->socket_to_babysitter = babysitter_pipe[0];
1134       babysitter_pipe[0] = -1;
1135       
1136       sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
1137       child_err_report_pipe[READ_END] = -1;
1138
1139       sitter->sitter_pid = pid;
1140
1141       if (sitter_p != NULL)
1142         *sitter_p = sitter;
1143       else
1144         _dbus_babysitter_unref (sitter);
1145
1146       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1147       
1148       return TRUE;
1149     }
1150
1151  cleanup_and_fail:
1152
1153   _DBUS_ASSERT_ERROR_IS_SET (error);
1154   
1155   close_and_invalidate (&child_err_report_pipe[READ_END]);
1156   close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1157   close_and_invalidate (&babysitter_pipe[0]);
1158   close_and_invalidate (&babysitter_pipe[1]);
1159
1160   if (sitter != NULL)
1161     _dbus_babysitter_unref (sitter);
1162   
1163   return FALSE;
1164 }
1165
1166 /** @} */
1167
1168 #ifdef DBUS_BUILD_TESTS
1169
1170 static dbus_bool_t
1171 check_spawn_nonexistent (void *data)
1172 {
1173   char *argv[4] = { NULL, NULL, NULL, NULL };
1174   DBusBabysitter *sitter;
1175   DBusError error;
1176   
1177   sitter = NULL;
1178   
1179   dbus_error_init (&error);
1180
1181   /*** Test launching nonexistent binary */
1182   
1183   argv[0] = "/this/does/not/exist/32542sdgafgafdg";
1184   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1185                                          NULL, NULL,
1186                                          &error))
1187     {
1188       _dbus_babysitter_block_for_child_exit (sitter);
1189       _dbus_babysitter_set_child_exit_error (sitter, &error);
1190     }
1191
1192   if (sitter)
1193     _dbus_babysitter_unref (sitter);
1194
1195   if (!dbus_error_is_set (&error))
1196     {
1197       _dbus_warn ("Did not get an error launching nonexistent executable\n");
1198       return FALSE;
1199     }
1200
1201   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1202         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
1203     {
1204       _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n",
1205                   error.name, error.message);
1206       dbus_error_free (&error);
1207       return FALSE;
1208     }
1209
1210   dbus_error_free (&error);
1211   
1212   return TRUE;
1213 }
1214
1215 static dbus_bool_t
1216 check_spawn_segfault (void *data)
1217 {
1218   char *argv[4] = { NULL, NULL, NULL, NULL };
1219   DBusBabysitter *sitter;
1220   DBusError error;
1221   
1222   sitter = NULL;
1223   
1224   dbus_error_init (&error);
1225
1226   /*** Test launching segfault binary */
1227   
1228   argv[0] = TEST_SEGFAULT_BINARY;
1229   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1230                                          NULL, NULL,
1231                                          &error))
1232     {
1233       _dbus_babysitter_block_for_child_exit (sitter);
1234       _dbus_babysitter_set_child_exit_error (sitter, &error);
1235     }
1236
1237   if (sitter)
1238     _dbus_babysitter_unref (sitter);
1239
1240   if (!dbus_error_is_set (&error))
1241     {
1242       _dbus_warn ("Did not get an error launching segfaulting binary\n");
1243       return FALSE;
1244     }
1245
1246   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1247         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1248     {
1249       _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n",
1250                   error.name, error.message);
1251       dbus_error_free (&error);
1252       return FALSE;
1253     }
1254
1255   dbus_error_free (&error);
1256   
1257   return TRUE;
1258 }
1259
1260 static dbus_bool_t
1261 check_spawn_exit (void *data)
1262 {
1263   char *argv[4] = { NULL, NULL, NULL, NULL };
1264   DBusBabysitter *sitter;
1265   DBusError error;
1266   
1267   sitter = NULL;
1268   
1269   dbus_error_init (&error);
1270
1271   /*** Test launching exit failure binary */
1272   
1273   argv[0] = TEST_EXIT_BINARY;
1274   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1275                                          NULL, NULL,
1276                                          &error))
1277     {
1278       _dbus_babysitter_block_for_child_exit (sitter);
1279       _dbus_babysitter_set_child_exit_error (sitter, &error);
1280     }
1281
1282   if (sitter)
1283     _dbus_babysitter_unref (sitter);
1284
1285   if (!dbus_error_is_set (&error))
1286     {
1287       _dbus_warn ("Did not get an error launching binary that exited with failure code\n");
1288       return FALSE;
1289     }
1290
1291   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1292         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
1293     {
1294       _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n",
1295                   error.name, error.message);
1296       dbus_error_free (&error);
1297       return FALSE;
1298     }
1299
1300   dbus_error_free (&error);
1301   
1302   return TRUE;
1303 }
1304
1305 static dbus_bool_t
1306 check_spawn_and_kill (void *data)
1307 {
1308   char *argv[4] = { NULL, NULL, NULL, NULL };
1309   DBusBabysitter *sitter;
1310   DBusError error;
1311   
1312   sitter = NULL;
1313   
1314   dbus_error_init (&error);
1315
1316   /*** Test launching sleeping binary then killing it */
1317
1318   argv[0] = TEST_SLEEP_FOREVER_BINARY;
1319   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
1320                                          NULL, NULL,
1321                                          &error))
1322     {
1323       _dbus_babysitter_kill_child (sitter);
1324       
1325       _dbus_babysitter_block_for_child_exit (sitter);
1326       
1327       _dbus_babysitter_set_child_exit_error (sitter, &error);
1328     }
1329
1330   if (sitter)
1331     _dbus_babysitter_unref (sitter);
1332
1333   if (!dbus_error_is_set (&error))
1334     {
1335       _dbus_warn ("Did not get an error after killing spawned binary\n");
1336       return FALSE;
1337     }
1338
1339   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
1340         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
1341     {
1342       _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
1343                   error.name, error.message);
1344       dbus_error_free (&error);
1345       return FALSE;
1346     }
1347
1348   dbus_error_free (&error);
1349   
1350   return TRUE;
1351 }
1352
1353 dbus_bool_t
1354 _dbus_spawn_test (const char *test_data_dir)
1355 {
1356   if (!_dbus_test_oom_handling ("spawn_nonexistent",
1357                                 check_spawn_nonexistent,
1358                                 NULL))
1359     return FALSE;
1360
1361   if (!_dbus_test_oom_handling ("spawn_segfault",
1362                                 check_spawn_segfault,
1363                                 NULL))
1364     return FALSE;
1365
1366   if (!_dbus_test_oom_handling ("spawn_exit",
1367                                 check_spawn_exit,
1368                                 NULL))
1369     return FALSE;
1370
1371   if (!_dbus_test_oom_handling ("spawn_and_kill",
1372                                 check_spawn_and_kill,
1373                                 NULL))
1374     return FALSE;
1375   
1376   return TRUE;
1377 }
1378 #endif