D-Bus 1.6.12

dbus-spawn.c

00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-spawn.c Wrapper around fork/exec
00003  * 
00004  * Copyright (C) 2002, 2003, 2004  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 
00027 #include "dbus-spawn.h"
00028 #include "dbus-sysdeps-unix.h"
00029 #include "dbus-internals.h"
00030 #include "dbus-test.h"
00031 #include "dbus-protocol.h"
00032 
00033 #include <unistd.h>
00034 #include <fcntl.h>
00035 #include <signal.h>
00036 #include <sys/wait.h>
00037 #include <stdlib.h>
00038 #ifdef HAVE_ERRNO_H
00039 #include <errno.h>
00040 #endif
00041 
00042 extern char **environ;
00043 
00049 /*
00050  * I'm pretty sure this whole spawn file could be made simpler,
00051  * if you thought about it a bit.
00052  */
00053 
00057 typedef enum
00058 {
00059   READ_STATUS_OK,    
00060   READ_STATUS_ERROR, 
00061   READ_STATUS_EOF    
00062 } ReadStatus;
00063 
00064 static ReadStatus
00065 read_ints (int        fd,
00066            int       *buf,
00067            int        n_ints_in_buf,
00068            int       *n_ints_read,
00069            DBusError *error)
00070 {
00071   size_t bytes = 0;    
00072   ReadStatus retval;
00073   
00074   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00075 
00076   retval = READ_STATUS_OK;
00077   
00078   while (TRUE)
00079     {
00080       ssize_t chunk;
00081       size_t to_read;
00082 
00083       to_read = sizeof (int) * n_ints_in_buf - bytes;
00084 
00085       if (to_read == 0)
00086         break;
00087 
00088     again:
00089       
00090       chunk = read (fd,
00091                     ((char*)buf) + bytes,
00092                     to_read);
00093       
00094       if (chunk < 0 && errno == EINTR)
00095         goto again;
00096           
00097       if (chunk < 0)
00098         {
00099           dbus_set_error (error,
00100                           DBUS_ERROR_SPAWN_FAILED,
00101                           "Failed to read from child pipe (%s)",
00102                           _dbus_strerror (errno));
00103 
00104           retval = READ_STATUS_ERROR;
00105           break;
00106         }
00107       else if (chunk == 0)
00108         {
00109           retval = READ_STATUS_EOF;
00110           break; /* EOF */
00111         }
00112       else /* chunk > 0 */
00113         bytes += chunk;
00114     }
00115 
00116   *n_ints_read = (int)(bytes / sizeof(int));
00117 
00118   return retval;
00119 }
00120 
00121 static ReadStatus
00122 read_pid (int        fd,
00123           pid_t     *buf,
00124           DBusError *error)
00125 {
00126   size_t bytes = 0;    
00127   ReadStatus retval;
00128   
00129   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00130 
00131   retval = READ_STATUS_OK;
00132   
00133   while (TRUE)
00134     {
00135       ssize_t chunk;
00136       size_t to_read;
00137 
00138       to_read = sizeof (pid_t) - bytes;
00139 
00140       if (to_read == 0)
00141         break;
00142 
00143     again:
00144       
00145       chunk = read (fd,
00146                     ((char*)buf) + bytes,
00147                     to_read);
00148       if (chunk < 0 && errno == EINTR)
00149         goto again;
00150           
00151       if (chunk < 0)
00152         {
00153           dbus_set_error (error,
00154                           DBUS_ERROR_SPAWN_FAILED,
00155                           "Failed to read from child pipe (%s)",
00156                           _dbus_strerror (errno));
00157 
00158           retval = READ_STATUS_ERROR;
00159           break;
00160         }
00161       else if (chunk == 0)
00162         {
00163           retval = READ_STATUS_EOF;
00164           break; /* EOF */
00165         }
00166       else /* chunk > 0 */
00167         bytes += chunk;
00168     }
00169 
00170   return retval;
00171 }
00172 
00173 /* The implementation uses an intermediate child between the main process
00174  * and the grandchild. The grandchild is our spawned process. The intermediate
00175  * child is a babysitter process; it keeps track of when the grandchild
00176  * exits/crashes, and reaps the grandchild.
00177  */
00178 
00179 /* Messages from children to parents */
00180 enum
00181 {
00182   CHILD_EXITED,            /* This message is followed by the exit status int */
00183   CHILD_FORK_FAILED,       /* Followed by errno */
00184   CHILD_EXEC_FAILED,       /* Followed by errno */
00185   CHILD_PID                /* Followed by pid_t */
00186 };
00187 
00191 struct DBusBabysitter
00192 {
00193   int refcount; 
00195   char *executable; 
00197   int socket_to_babysitter; 
00198   int error_pipe_from_child; 
00200   pid_t sitter_pid;  
00201   pid_t grandchild_pid; 
00203   DBusWatchList *watches; 
00205   DBusWatch *error_watch; 
00206   DBusWatch *sitter_watch; 
00208   DBusBabysitterFinishedFunc finished_cb;
00209   void *finished_data;
00210 
00211   int errnum; 
00212   int status; 
00213   unsigned int have_child_status : 1; 
00214   unsigned int have_fork_errnum : 1; 
00215   unsigned int have_exec_errnum : 1; 
00216 };
00217 
00218 static DBusBabysitter*
00219 _dbus_babysitter_new (void)
00220 {
00221   DBusBabysitter *sitter;
00222 
00223   sitter = dbus_new0 (DBusBabysitter, 1);
00224   if (sitter == NULL)
00225     return NULL;
00226 
00227   sitter->refcount = 1;
00228 
00229   sitter->socket_to_babysitter = -1;
00230   sitter->error_pipe_from_child = -1;
00231   
00232   sitter->sitter_pid = -1;
00233   sitter->grandchild_pid = -1;
00234 
00235   sitter->watches = _dbus_watch_list_new ();
00236   if (sitter->watches == NULL)
00237     goto failed;
00238   
00239   return sitter;
00240 
00241  failed:
00242   _dbus_babysitter_unref (sitter);
00243   return NULL;
00244 }
00245 
00252 DBusBabysitter *
00253 _dbus_babysitter_ref (DBusBabysitter *sitter)
00254 {
00255   _dbus_assert (sitter != NULL);
00256   _dbus_assert (sitter->refcount > 0);
00257   
00258   sitter->refcount += 1;
00259 
00260   return sitter;
00261 }
00262 
00263 static void close_socket_to_babysitter  (DBusBabysitter *sitter);
00264 static void close_error_pipe_from_child (DBusBabysitter *sitter);
00265 
00274 void
00275 _dbus_babysitter_unref (DBusBabysitter *sitter)
00276 {
00277   _dbus_assert (sitter != NULL);
00278   _dbus_assert (sitter->refcount > 0);
00279   
00280   sitter->refcount -= 1;
00281   if (sitter->refcount == 0)
00282     {
00283       /* If we haven't forked other babysitters
00284        * since this babysitter and socket were
00285        * created then this close will cause the
00286        * babysitter to wake up from poll with
00287        * a hangup and then the babysitter will
00288        * quit itself.
00289        */
00290       close_socket_to_babysitter (sitter);
00291 
00292       close_error_pipe_from_child (sitter);
00293 
00294       if (sitter->sitter_pid > 0)
00295         {
00296           int status;
00297           int ret;
00298 
00299           /* It's possible the babysitter died on its own above 
00300            * from the close, or was killed randomly
00301            * by some other process, so first try to reap it
00302            */
00303           ret = waitpid (sitter->sitter_pid, &status, WNOHANG);
00304 
00305           /* If we couldn't reap the child then kill it, and
00306            * try again
00307            */
00308           if (ret == 0)
00309             kill (sitter->sitter_pid, SIGKILL);
00310 
00311         again:
00312           if (ret == 0)
00313             ret = waitpid (sitter->sitter_pid, &status, 0);
00314 
00315           if (ret < 0)
00316             {
00317               if (errno == EINTR)
00318                 goto again;
00319               else if (errno == ECHILD)
00320                 _dbus_warn ("Babysitter process not available to be reaped; should not happen\n");
00321               else
00322                 _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s\n",
00323                             errno, _dbus_strerror (errno));
00324             }
00325           else
00326             {
00327               _dbus_verbose ("Reaped %ld, waiting for babysitter %ld\n",
00328                              (long) ret, (long) sitter->sitter_pid);
00329               
00330               if (WIFEXITED (sitter->status))
00331                 _dbus_verbose ("Babysitter exited with status %d\n",
00332                                WEXITSTATUS (sitter->status));
00333               else if (WIFSIGNALED (sitter->status))
00334                 _dbus_verbose ("Babysitter received signal %d\n",
00335                                WTERMSIG (sitter->status));
00336               else
00337                 _dbus_verbose ("Babysitter exited abnormally\n");
00338             }
00339 
00340           sitter->sitter_pid = -1;
00341         }
00342 
00343       if (sitter->watches)
00344         _dbus_watch_list_free (sitter->watches);
00345 
00346       dbus_free (sitter->executable);
00347       
00348       dbus_free (sitter);
00349     }
00350 }
00351 
00352 static ReadStatus
00353 read_data (DBusBabysitter *sitter,
00354            int             fd)
00355 {
00356   int what;
00357   int got;
00358   DBusError error = DBUS_ERROR_INIT;
00359   ReadStatus r;
00360 
00361   r = read_ints (fd, &what, 1, &got, &error);
00362 
00363   switch (r)
00364     {
00365     case READ_STATUS_ERROR:
00366       _dbus_warn ("Failed to read data from fd %d: %s\n", fd, error.message);
00367       dbus_error_free (&error);
00368       return r;
00369 
00370     case READ_STATUS_EOF:
00371       return r;
00372 
00373     case READ_STATUS_OK:
00374       break;
00375     }
00376   
00377   if (got == 1)
00378     {
00379       switch (what)
00380         {
00381         case CHILD_EXITED:
00382         case CHILD_FORK_FAILED:
00383         case CHILD_EXEC_FAILED:
00384           {
00385             int arg;
00386             
00387             r = read_ints (fd, &arg, 1, &got, &error);
00388 
00389             switch (r)
00390               {
00391               case READ_STATUS_ERROR:
00392                 _dbus_warn ("Failed to read arg from fd %d: %s\n", fd, error.message);
00393                 dbus_error_free (&error);
00394                 return r;
00395               case READ_STATUS_EOF:
00396                 return r;
00397               case READ_STATUS_OK:
00398                 break;
00399               }
00400             
00401             if (got == 1)
00402               {
00403                 if (what == CHILD_EXITED)
00404                   {
00405                     sitter->have_child_status = TRUE;
00406                     sitter->status = arg;
00407                     sitter->errnum = 0;
00408                     _dbus_verbose ("recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n",
00409                                    WIFEXITED (sitter->status), WIFSIGNALED (sitter->status),
00410                                    WEXITSTATUS (sitter->status), WTERMSIG (sitter->status));
00411                   }
00412                 else if (what == CHILD_FORK_FAILED)
00413                   {
00414                     sitter->have_fork_errnum = TRUE;
00415                     sitter->errnum = arg;
00416                     _dbus_verbose ("recorded fork errnum %d\n", sitter->errnum);
00417                   }
00418                 else if (what == CHILD_EXEC_FAILED)
00419                   {
00420                     sitter->have_exec_errnum = TRUE;
00421                     sitter->errnum = arg;
00422                     _dbus_verbose ("recorded exec errnum %d\n", sitter->errnum);
00423                   }
00424               }
00425           }
00426           break;
00427         case CHILD_PID:
00428           {
00429             pid_t pid = -1;
00430 
00431             r = read_pid (fd, &pid, &error);
00432             
00433             switch (r)
00434               {
00435               case READ_STATUS_ERROR:
00436                 _dbus_warn ("Failed to read PID from fd %d: %s\n", fd, error.message);
00437                 dbus_error_free (&error);
00438                 return r;
00439               case READ_STATUS_EOF:
00440                 return r;
00441               case READ_STATUS_OK:
00442                 break;
00443               }
00444             
00445             sitter->grandchild_pid = pid;
00446             
00447             _dbus_verbose ("recorded grandchild pid %d\n", sitter->grandchild_pid);
00448           }
00449           break;
00450         default:
00451           _dbus_warn ("Unknown message received from babysitter process\n");
00452           break;
00453         }
00454     }
00455 
00456   return r;
00457 }
00458 
00459 static void
00460 close_socket_to_babysitter (DBusBabysitter *sitter)
00461 {
00462   _dbus_verbose ("Closing babysitter\n");
00463 
00464   if (sitter->sitter_watch != NULL)
00465     {
00466       _dbus_assert (sitter->watches != NULL);
00467       _dbus_watch_list_remove_watch (sitter->watches,  sitter->sitter_watch);
00468       _dbus_watch_invalidate (sitter->sitter_watch);
00469       _dbus_watch_unref (sitter->sitter_watch);
00470       sitter->sitter_watch = NULL;
00471     }
00472 
00473   if (sitter->socket_to_babysitter >= 0)
00474     {
00475       _dbus_close_socket (sitter->socket_to_babysitter, NULL);
00476       sitter->socket_to_babysitter = -1;
00477     }
00478 }
00479 
00480 static void
00481 close_error_pipe_from_child (DBusBabysitter *sitter)
00482 {
00483   _dbus_verbose ("Closing child error\n");
00484 
00485   if (sitter->error_watch != NULL)
00486     {
00487       _dbus_assert (sitter->watches != NULL);
00488       _dbus_watch_list_remove_watch (sitter->watches,  sitter->error_watch);
00489       _dbus_watch_invalidate (sitter->error_watch);
00490       _dbus_watch_unref (sitter->error_watch);
00491       sitter->error_watch = NULL;
00492     }
00493 
00494   if (sitter->error_pipe_from_child >= 0)
00495     {
00496       _dbus_close_socket (sitter->error_pipe_from_child, NULL);
00497       sitter->error_pipe_from_child = -1;
00498     }
00499 }
00500 
00501 static void
00502 handle_babysitter_socket (DBusBabysitter *sitter,
00503                           int             revents)
00504 {
00505   /* Even if we have POLLHUP, we want to keep reading
00506    * data until POLLIN goes away; so this function only
00507    * looks at HUP/ERR if no IN is set.
00508    */
00509   if (revents & _DBUS_POLLIN)
00510     {
00511       _dbus_verbose ("Reading data from babysitter\n");
00512       if (read_data (sitter, sitter->socket_to_babysitter) != READ_STATUS_OK)
00513         close_socket_to_babysitter (sitter);
00514     }
00515   else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
00516     {
00517       close_socket_to_babysitter (sitter);
00518     }
00519 }
00520 
00521 static void
00522 handle_error_pipe (DBusBabysitter *sitter,
00523                    int             revents)
00524 {
00525   if (revents & _DBUS_POLLIN)
00526     {
00527       _dbus_verbose ("Reading data from child error\n");
00528       if (read_data (sitter, sitter->error_pipe_from_child) != READ_STATUS_OK)
00529         close_error_pipe_from_child (sitter);
00530     }
00531   else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
00532     {
00533       close_error_pipe_from_child (sitter);
00534     }
00535 }
00536 
00537 /* returns whether there were any poll events handled */
00538 static dbus_bool_t
00539 babysitter_iteration (DBusBabysitter *sitter,
00540                       dbus_bool_t     block)
00541 {
00542   DBusPollFD fds[2];
00543   int i;
00544   dbus_bool_t descriptors_ready;
00545 
00546   descriptors_ready = FALSE;
00547   
00548   i = 0;
00549 
00550   if (sitter->error_pipe_from_child >= 0)
00551     {
00552       fds[i].fd = sitter->error_pipe_from_child;
00553       fds[i].events = _DBUS_POLLIN;
00554       fds[i].revents = 0;
00555       ++i;
00556     }
00557   
00558   if (sitter->socket_to_babysitter >= 0)
00559     {
00560       fds[i].fd = sitter->socket_to_babysitter;
00561       fds[i].events = _DBUS_POLLIN;
00562       fds[i].revents = 0;
00563       ++i;
00564     }
00565 
00566   if (i > 0)
00567     {
00568       int ret;
00569 
00570       do
00571         {
00572           ret = _dbus_poll (fds, i, 0);
00573         }
00574       while (ret < 0 && errno == EINTR);
00575 
00576       if (ret == 0 && block)
00577         {
00578           do
00579             {
00580               ret = _dbus_poll (fds, i, -1);
00581             }
00582           while (ret < 0 && errno == EINTR);
00583         }
00584 
00585       if (ret > 0)
00586         {
00587           descriptors_ready = TRUE;
00588           
00589           while (i > 0)
00590             {
00591               --i;
00592               if (fds[i].fd == sitter->error_pipe_from_child)
00593                 handle_error_pipe (sitter, fds[i].revents);
00594               else if (fds[i].fd == sitter->socket_to_babysitter)
00595                 handle_babysitter_socket (sitter, fds[i].revents);
00596             }
00597         }
00598     }
00599 
00600   return descriptors_ready;
00601 }
00602 
00607 #define LIVE_CHILDREN(sitter) ((sitter)->socket_to_babysitter >= 0 || (sitter)->error_pipe_from_child >= 0)
00608 
00615 void
00616 _dbus_babysitter_kill_child (DBusBabysitter *sitter)
00617 {
00618   /* be sure we have the PID of the child */
00619   while (LIVE_CHILDREN (sitter) &&
00620          sitter->grandchild_pid == -1)
00621     babysitter_iteration (sitter, TRUE);
00622 
00623   _dbus_verbose ("Got child PID %ld for killing\n",
00624                  (long) sitter->grandchild_pid);
00625   
00626   if (sitter->grandchild_pid == -1)
00627     return; /* child is already dead, or we're so hosed we'll never recover */
00628 
00629   kill (sitter->grandchild_pid, SIGKILL);
00630 }
00631 
00637 dbus_bool_t
00638 _dbus_babysitter_get_child_exited (DBusBabysitter *sitter)
00639 {
00640 
00641   /* Be sure we're up-to-date */
00642   while (LIVE_CHILDREN (sitter) &&
00643          babysitter_iteration (sitter, FALSE))
00644     ;
00645 
00646   /* We will have exited the babysitter when the child has exited */
00647   return sitter->socket_to_babysitter < 0;
00648 }
00649 
00662 dbus_bool_t
00663 _dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter,
00664                                         int            *status)
00665 {
00666   if (!_dbus_babysitter_get_child_exited (sitter))
00667     _dbus_assert_not_reached ("Child has not exited");
00668   
00669   if (!sitter->have_child_status ||
00670       !(WIFEXITED (sitter->status)))
00671     return FALSE;
00672 
00673   *status = WEXITSTATUS (sitter->status);
00674   return TRUE;
00675 }
00676 
00686 void
00687 _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
00688                                        DBusError      *error)
00689 {
00690   if (!_dbus_babysitter_get_child_exited (sitter))
00691     return;
00692 
00693   /* Note that if exec fails, we will also get a child status
00694    * from the babysitter saying the child exited,
00695    * so we need to give priority to the exec error
00696    */
00697   if (sitter->have_exec_errnum)
00698     {
00699       dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
00700                       "Failed to execute program %s: %s",
00701                       sitter->executable, _dbus_strerror (sitter->errnum));
00702     }
00703   else if (sitter->have_fork_errnum)
00704     {
00705       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00706                       "Failed to fork a new process %s: %s",
00707                       sitter->executable, _dbus_strerror (sitter->errnum));
00708     }
00709   else if (sitter->have_child_status)
00710     {
00711       if (WIFEXITED (sitter->status))
00712         dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
00713                         "Process %s exited with status %d",
00714                         sitter->executable, WEXITSTATUS (sitter->status));
00715       else if (WIFSIGNALED (sitter->status))
00716         dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED,
00717                         "Process %s received signal %d",
00718                         sitter->executable, WTERMSIG (sitter->status));
00719       else
00720         dbus_set_error (error, DBUS_ERROR_FAILED,
00721                         "Process %s exited abnormally",
00722                         sitter->executable);
00723     }
00724   else
00725     {
00726       dbus_set_error (error, DBUS_ERROR_FAILED,
00727                       "Process %s exited, reason unknown",
00728                       sitter->executable);
00729     }
00730 }
00731 
00744 dbus_bool_t
00745 _dbus_babysitter_set_watch_functions (DBusBabysitter            *sitter,
00746                                       DBusAddWatchFunction       add_function,
00747                                       DBusRemoveWatchFunction    remove_function,
00748                                       DBusWatchToggledFunction   toggled_function,
00749                                       void                      *data,
00750                                       DBusFreeFunction           free_data_function)
00751 {
00752   return _dbus_watch_list_set_functions (sitter->watches,
00753                                          add_function,
00754                                          remove_function,
00755                                          toggled_function,
00756                                          data,
00757                                          free_data_function);
00758 }
00759 
00760 static dbus_bool_t
00761 handle_watch (DBusWatch       *watch,
00762               unsigned int     condition,
00763               void            *data)
00764 {
00765   DBusBabysitter *sitter = _dbus_babysitter_ref (data);
00766   int revents;
00767   int fd;
00768   
00769   revents = 0;
00770   if (condition & DBUS_WATCH_READABLE)
00771     revents |= _DBUS_POLLIN;
00772   if (condition & DBUS_WATCH_ERROR)
00773     revents |= _DBUS_POLLERR;
00774   if (condition & DBUS_WATCH_HANGUP)
00775     revents |= _DBUS_POLLHUP;
00776 
00777   fd = dbus_watch_get_socket (watch);
00778 
00779   if (fd == sitter->error_pipe_from_child)
00780     handle_error_pipe (sitter, revents);
00781   else if (fd == sitter->socket_to_babysitter)
00782     handle_babysitter_socket (sitter, revents);
00783 
00784   while (LIVE_CHILDREN (sitter) &&
00785          babysitter_iteration (sitter, FALSE))
00786     ;
00787 
00788   /* fd.o #32992: if the handle_* methods closed their sockets, they previously
00789    * didn't always remove the watches. Check that we don't regress. */
00790   _dbus_assert (sitter->socket_to_babysitter != -1 || sitter->sitter_watch == NULL);
00791   _dbus_assert (sitter->error_pipe_from_child != -1 || sitter->error_watch == NULL);
00792 
00793   if (_dbus_babysitter_get_child_exited (sitter) &&
00794       sitter->finished_cb != NULL)
00795     {
00796       sitter->finished_cb (sitter, sitter->finished_data);
00797       sitter->finished_cb = NULL;
00798     }
00799 
00800   _dbus_babysitter_unref (sitter);
00801   return TRUE;
00802 }
00803 
00805 #define READ_END 0
00806 
00807 #define WRITE_END 1
00808 
00809 
00810 /* Avoids a danger in threaded situations (calling close()
00811  * on a file descriptor twice, and another thread has
00812  * re-opened it since the first close)
00813  */
00814 static int
00815 close_and_invalidate (int *fd)
00816 {
00817   int ret;
00818 
00819   if (*fd < 0)
00820     return -1;
00821   else
00822     {
00823       ret = _dbus_close_socket (*fd, NULL);
00824       *fd = -1;
00825     }
00826 
00827   return ret;
00828 }
00829 
00830 static dbus_bool_t
00831 make_pipe (int         p[2],
00832            DBusError  *error)
00833 {
00834   int retval;
00835 
00836 #ifdef HAVE_PIPE2
00837   dbus_bool_t cloexec_done;
00838 
00839   retval = pipe2 (p, O_CLOEXEC);
00840   cloexec_done = retval >= 0;
00841 
00842   /* Check if kernel seems to be too old to know pipe2(). We assume
00843      that if pipe2 is available, O_CLOEXEC is too.  */
00844   if (retval < 0 && errno == ENOSYS)
00845 #endif
00846     {
00847       retval = pipe(p);
00848     }
00849 
00850   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00851 
00852   if (retval < 0)
00853     {
00854       dbus_set_error (error,
00855                       DBUS_ERROR_SPAWN_FAILED,
00856                       "Failed to create pipe for communicating with child process (%s)",
00857                       _dbus_strerror (errno));
00858       return FALSE;
00859     }
00860 
00861 #ifdef HAVE_PIPE2
00862   if (!cloexec_done)
00863 #endif
00864     {
00865       _dbus_fd_set_close_on_exec (p[0]);
00866       _dbus_fd_set_close_on_exec (p[1]);
00867     }
00868 
00869   return TRUE;
00870 }
00871 
00872 static void
00873 do_write (int fd, const void *buf, size_t count)
00874 {
00875   size_t bytes_written;
00876   int ret;
00877   
00878   bytes_written = 0;
00879   
00880  again:
00881   
00882   ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
00883 
00884   if (ret < 0)
00885     {
00886       if (errno == EINTR)
00887         goto again;
00888       else
00889         {
00890           _dbus_warn ("Failed to write data to pipe!\n");
00891           exit (1); /* give up, we suck */
00892         }
00893     }
00894   else
00895     bytes_written += ret;
00896   
00897   if (bytes_written < count)
00898     goto again;
00899 }
00900 
00901 static void
00902 write_err_and_exit (int fd, int msg)
00903 {
00904   int en = errno;
00905 
00906   do_write (fd, &msg, sizeof (msg));
00907   do_write (fd, &en, sizeof (en));
00908   
00909   exit (1);
00910 }
00911 
00912 static void
00913 write_pid (int fd, pid_t pid)
00914 {
00915   int msg = CHILD_PID;
00916   
00917   do_write (fd, &msg, sizeof (msg));
00918   do_write (fd, &pid, sizeof (pid));
00919 }
00920 
00921 static void
00922 write_status_and_exit (int fd, int status)
00923 {
00924   int msg = CHILD_EXITED;
00925   
00926   do_write (fd, &msg, sizeof (msg));
00927   do_write (fd, &status, sizeof (status));
00928   
00929   exit (0);
00930 }
00931 
00932 static void
00933 do_exec (int                       child_err_report_fd,
00934          char                    **argv,
00935          char                    **envp,
00936          DBusSpawnChildSetupFunc   child_setup,
00937          void                     *user_data)
00938 {
00939 #ifdef DBUS_BUILD_TESTS
00940   int i, max_open;
00941 #endif
00942 
00943   _dbus_verbose_reset ();
00944   _dbus_verbose ("Child process has PID " DBUS_PID_FORMAT "\n",
00945                  _dbus_getpid ());
00946   
00947   if (child_setup)
00948     (* child_setup) (user_data);
00949 
00950 #ifdef DBUS_BUILD_TESTS
00951   max_open = sysconf (_SC_OPEN_MAX);
00952   
00953   for (i = 3; i < max_open; i++)
00954     {
00955       int retval;
00956 
00957       if (i == child_err_report_fd)
00958         continue;
00959       
00960       retval = fcntl (i, F_GETFD);
00961 
00962       if (retval != -1 && !(retval & FD_CLOEXEC))
00963         _dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i);
00964     }
00965 #endif
00966 
00967   if (envp == NULL)
00968     {
00969       _dbus_assert (environ != NULL);
00970 
00971       envp = environ;
00972     }
00973   
00974   execve (argv[0], argv, envp);
00975   
00976   /* Exec failed */
00977   write_err_and_exit (child_err_report_fd,
00978                       CHILD_EXEC_FAILED);
00979 }
00980 
00981 static void
00982 check_babysit_events (pid_t grandchild_pid,
00983                       int   parent_pipe,
00984                       int   revents)
00985 {
00986   pid_t ret;
00987   int status;
00988   
00989   do
00990     {
00991       ret = waitpid (grandchild_pid, &status, WNOHANG);
00992       /* The man page says EINTR can't happen with WNOHANG,
00993        * but there are reports of it (maybe only with valgrind?)
00994        */
00995     }
00996   while (ret < 0 && errno == EINTR);
00997 
00998   if (ret == 0)
00999     {
01000       _dbus_verbose ("no child exited\n");
01001       
01002       ; /* no child exited */
01003     }
01004   else if (ret < 0)
01005     {
01006       /* This isn't supposed to happen. */
01007       _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s\n",
01008                   _dbus_strerror (errno));
01009       exit (1);
01010     }
01011   else if (ret == grandchild_pid)
01012     {
01013       /* Child exited */
01014       _dbus_verbose ("reaped child pid %ld\n", (long) ret);
01015       
01016       write_status_and_exit (parent_pipe, status);
01017     }
01018   else
01019     {
01020       _dbus_warn ("waitpid() reaped pid %d that we've never heard of\n",
01021                   (int) ret);
01022       exit (1);
01023     }
01024 
01025   if (revents & _DBUS_POLLIN)
01026     {
01027       _dbus_verbose ("babysitter got POLLIN from parent pipe\n");
01028     }
01029 
01030   if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
01031     {
01032       /* Parent is gone, so we just exit */
01033       _dbus_verbose ("babysitter got POLLERR or POLLHUP from parent\n");
01034       exit (0);
01035     }
01036 }
01037 
01038 static int babysit_sigchld_pipe = -1;
01039 
01040 static void
01041 babysit_signal_handler (int signo)
01042 {
01043   char b = '\0';
01044  again:
01045   if (write (babysit_sigchld_pipe, &b, 1) <= 0) 
01046     if (errno == EINTR)
01047       goto again;
01048 }
01049 
01050 static void
01051 babysit (pid_t grandchild_pid,
01052          int   parent_pipe)
01053 {
01054   int sigchld_pipe[2];
01055 
01056   /* We don't exec, so we keep parent state, such as the pid that
01057    * _dbus_verbose() uses. Reset the pid here.
01058    */
01059   _dbus_verbose_reset ();
01060   
01061   /* I thought SIGCHLD would just wake up the poll, but
01062    * that didn't seem to work, so added this pipe.
01063    * Probably the pipe is more likely to work on busted
01064    * operating systems anyhow.
01065    */
01066   if (pipe (sigchld_pipe) < 0)
01067     {
01068       _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n");
01069       exit (1);
01070     }
01071 
01072   babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
01073 
01074   _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler);
01075   
01076   write_pid (parent_pipe, grandchild_pid);
01077 
01078   check_babysit_events (grandchild_pid, parent_pipe, 0);
01079 
01080   while (TRUE)
01081     {
01082       DBusPollFD pfds[2];
01083       
01084       pfds[0].fd = parent_pipe;
01085       pfds[0].events = _DBUS_POLLIN;
01086       pfds[0].revents = 0;
01087 
01088       pfds[1].fd = sigchld_pipe[READ_END];
01089       pfds[1].events = _DBUS_POLLIN;
01090       pfds[1].revents = 0;
01091       
01092       if (_dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1) < 0 && errno != EINTR)
01093         {
01094           _dbus_warn ("_dbus_poll() error: %s\n", strerror (errno));
01095           exit (1);
01096         }
01097 
01098       if (pfds[0].revents != 0)
01099         {
01100           check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents);
01101         }
01102       else if (pfds[1].revents & _DBUS_POLLIN)
01103         {
01104           char b;
01105           if (read (sigchld_pipe[READ_END], &b, 1) == -1)
01106             {
01107               /* ignore */
01108             }
01109           /* do waitpid check */
01110           check_babysit_events (grandchild_pid, parent_pipe, 0);
01111         }
01112     }
01113   
01114   exit (1);
01115 }
01116 
01136 dbus_bool_t
01137 _dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
01138                                    char                    **argv,
01139                                    char                    **env,
01140                                    DBusSpawnChildSetupFunc   child_setup,
01141                                    void                     *user_data,
01142                                    DBusError                *error)
01143 {
01144   DBusBabysitter *sitter;
01145   int child_err_report_pipe[2] = { -1, -1 };
01146   int babysitter_pipe[2] = { -1, -1 };
01147   pid_t pid;
01148   
01149   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01150 
01151   if (sitter_p != NULL)
01152     *sitter_p = NULL;
01153 
01154   sitter = NULL;
01155 
01156   sitter = _dbus_babysitter_new ();
01157   if (sitter == NULL)
01158     {
01159       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01160       return FALSE;
01161     }
01162 
01163   sitter->executable = _dbus_strdup (argv[0]);
01164   if (sitter->executable == NULL)
01165     {
01166       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01167       goto cleanup_and_fail;
01168     }
01169   
01170   if (!make_pipe (child_err_report_pipe, error))
01171     goto cleanup_and_fail;
01172 
01173   if (!_dbus_full_duplex_pipe (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
01174     goto cleanup_and_fail;
01175 
01176   /* Setting up the babysitter is only useful in the parent,
01177    * but we don't want to run out of memory and fail
01178    * after we've already forked, since then we'd leak
01179    * child processes everywhere.
01180    */
01181   sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
01182                                          DBUS_WATCH_READABLE,
01183                                          TRUE, handle_watch, sitter, NULL);
01184   if (sitter->error_watch == NULL)
01185     {
01186       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01187       goto cleanup_and_fail;
01188     }
01189         
01190   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->error_watch))
01191     {
01192       /* we need to free it early so the destructor won't try to remove it
01193        * without it having been added, which DBusLoop doesn't allow */
01194       _dbus_watch_invalidate (sitter->error_watch);
01195       _dbus_watch_unref (sitter->error_watch);
01196       sitter->error_watch = NULL;
01197 
01198       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01199       goto cleanup_and_fail;
01200     }
01201       
01202   sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0],
01203                                           DBUS_WATCH_READABLE,
01204                                           TRUE, handle_watch, sitter, NULL);
01205   if (sitter->sitter_watch == NULL)
01206     {
01207       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01208       goto cleanup_and_fail;
01209     }
01210       
01211   if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->sitter_watch))
01212     {
01213       /* we need to free it early so the destructor won't try to remove it
01214        * without it having been added, which DBusLoop doesn't allow */
01215       _dbus_watch_invalidate (sitter->sitter_watch);
01216       _dbus_watch_unref (sitter->sitter_watch);
01217       sitter->sitter_watch = NULL;
01218 
01219       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01220       goto cleanup_and_fail;
01221     }
01222 
01223   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01224   
01225   pid = fork ();
01226   
01227   if (pid < 0)
01228     {
01229       dbus_set_error (error,
01230                       DBUS_ERROR_SPAWN_FORK_FAILED,
01231                       "Failed to fork (%s)",
01232                       _dbus_strerror (errno));
01233       goto cleanup_and_fail;
01234     }
01235   else if (pid == 0)
01236     {
01237       /* Immediate child, this is the babysitter process. */
01238       int grandchild_pid;
01239       
01240       /* Be sure we crash if the parent exits
01241        * and we write to the err_report_pipe
01242        */
01243       signal (SIGPIPE, SIG_DFL);
01244 
01245       /* Close the parent's end of the pipes. */
01246       close_and_invalidate (&child_err_report_pipe[READ_END]);
01247       close_and_invalidate (&babysitter_pipe[0]);
01248       
01249       /* Create the child that will exec () */
01250       grandchild_pid = fork ();
01251       
01252       if (grandchild_pid < 0)
01253         {
01254           write_err_and_exit (babysitter_pipe[1],
01255                               CHILD_FORK_FAILED);
01256           _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
01257         }
01258       else if (grandchild_pid == 0)
01259         {
01260           /* Go back to ignoring SIGPIPE, since it's evil
01261            */
01262           signal (SIGPIPE, SIG_IGN);
01263 
01264           do_exec (child_err_report_pipe[WRITE_END],
01265                    argv,
01266                    env,
01267                    child_setup, user_data);
01268           _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
01269         }
01270       else
01271         {
01272           babysit (grandchild_pid, babysitter_pipe[1]);
01273           _dbus_assert_not_reached ("Got to code after babysit()");
01274         }
01275     }
01276   else
01277     {      
01278       /* Close the uncared-about ends of the pipes */
01279       close_and_invalidate (&child_err_report_pipe[WRITE_END]);
01280       close_and_invalidate (&babysitter_pipe[1]);
01281 
01282       sitter->socket_to_babysitter = babysitter_pipe[0];
01283       babysitter_pipe[0] = -1;
01284       
01285       sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
01286       child_err_report_pipe[READ_END] = -1;
01287 
01288       sitter->sitter_pid = pid;
01289 
01290       if (sitter_p != NULL)
01291         *sitter_p = sitter;
01292       else
01293         _dbus_babysitter_unref (sitter);
01294 
01295       dbus_free_string_array (env);
01296 
01297       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01298       
01299       return TRUE;
01300     }
01301 
01302  cleanup_and_fail:
01303 
01304   _DBUS_ASSERT_ERROR_IS_SET (error);
01305   
01306   close_and_invalidate (&child_err_report_pipe[READ_END]);
01307   close_and_invalidate (&child_err_report_pipe[WRITE_END]);
01308   close_and_invalidate (&babysitter_pipe[0]);
01309   close_and_invalidate (&babysitter_pipe[1]);
01310 
01311   if (sitter != NULL)
01312     _dbus_babysitter_unref (sitter);
01313   
01314   return FALSE;
01315 }
01316 
01317 void
01318 _dbus_babysitter_set_result_function  (DBusBabysitter             *sitter,
01319                                        DBusBabysitterFinishedFunc  finished,
01320                                        void                       *user_data)
01321 {
01322   sitter->finished_cb = finished;
01323   sitter->finished_data = user_data;
01324 }
01325 
01328 #ifdef DBUS_BUILD_TESTS
01329 
01330 static char *
01331 get_test_exec (const char *exe,
01332                DBusString *scratch_space)
01333 {
01334   const char *dbus_test_exec;
01335 
01336   dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC");
01337 
01338   if (dbus_test_exec == NULL)
01339     dbus_test_exec = DBUS_TEST_EXEC;
01340 
01341   if (!_dbus_string_init (scratch_space))
01342     return NULL;
01343 
01344   if (!_dbus_string_append_printf (scratch_space, "%s/%s%s",
01345                                    dbus_test_exec, exe, DBUS_EXEEXT))
01346     {
01347       _dbus_string_free (scratch_space);
01348       return NULL;
01349     }
01350 
01351   return _dbus_string_get_data (scratch_space);
01352 }
01353 
01354 static void
01355 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter)
01356 {
01357   while (LIVE_CHILDREN (sitter))
01358     babysitter_iteration (sitter, TRUE);
01359 }
01360 
01361 static dbus_bool_t
01362 check_spawn_nonexistent (void *data)
01363 {
01364   char *argv[4] = { NULL, NULL, NULL, NULL };
01365   DBusBabysitter *sitter = NULL;
01366   DBusError error = DBUS_ERROR_INIT;
01367 
01368   /*** Test launching nonexistent binary */
01369   
01370   argv[0] = "/this/does/not/exist/32542sdgafgafdg";
01371   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
01372                                          NULL, NULL, NULL,
01373                                          &error))
01374     {
01375       _dbus_babysitter_block_for_child_exit (sitter);
01376       _dbus_babysitter_set_child_exit_error (sitter, &error);
01377     }
01378 
01379   if (sitter)
01380     _dbus_babysitter_unref (sitter);
01381 
01382   if (!dbus_error_is_set (&error))
01383     {
01384       _dbus_warn ("Did not get an error launching nonexistent executable\n");
01385       return FALSE;
01386     }
01387 
01388   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
01389         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
01390     {
01391       _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n",
01392                   error.name, error.message);
01393       dbus_error_free (&error);
01394       return FALSE;
01395     }
01396 
01397   dbus_error_free (&error);
01398   
01399   return TRUE;
01400 }
01401 
01402 static dbus_bool_t
01403 check_spawn_segfault (void *data)
01404 {
01405   char *argv[4] = { NULL, NULL, NULL, NULL };
01406   DBusBabysitter *sitter = NULL;
01407   DBusError error = DBUS_ERROR_INIT;
01408   DBusString argv0;
01409 
01410   /*** Test launching segfault binary */
01411 
01412   argv[0] = get_test_exec ("test-segfault", &argv0);
01413 
01414   if (argv[0] == NULL)
01415     {
01416       /* OOM was simulated, never mind */
01417       return TRUE;
01418     }
01419 
01420   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
01421                                          NULL, NULL, NULL,
01422                                          &error))
01423     {
01424       _dbus_babysitter_block_for_child_exit (sitter);
01425       _dbus_babysitter_set_child_exit_error (sitter, &error);
01426     }
01427 
01428   _dbus_string_free (&argv0);
01429 
01430   if (sitter)
01431     _dbus_babysitter_unref (sitter);
01432 
01433   if (!dbus_error_is_set (&error))
01434     {
01435       _dbus_warn ("Did not get an error launching segfaulting binary\n");
01436       return FALSE;
01437     }
01438 
01439   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
01440         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
01441     {
01442       _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n",
01443                   error.name, error.message);
01444       dbus_error_free (&error);
01445       return FALSE;
01446     }
01447 
01448   dbus_error_free (&error);
01449   
01450   return TRUE;
01451 }
01452 
01453 static dbus_bool_t
01454 check_spawn_exit (void *data)
01455 {
01456   char *argv[4] = { NULL, NULL, NULL, NULL };
01457   DBusBabysitter *sitter = NULL;
01458   DBusError error = DBUS_ERROR_INIT;
01459   DBusString argv0;
01460 
01461   /*** Test launching exit failure binary */
01462 
01463   argv[0] = get_test_exec ("test-exit", &argv0);
01464 
01465   if (argv[0] == NULL)
01466     {
01467       /* OOM was simulated, never mind */
01468       return TRUE;
01469     }
01470 
01471   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
01472                                          NULL, NULL, NULL,
01473                                          &error))
01474     {
01475       _dbus_babysitter_block_for_child_exit (sitter);
01476       _dbus_babysitter_set_child_exit_error (sitter, &error);
01477     }
01478 
01479   _dbus_string_free (&argv0);
01480 
01481   if (sitter)
01482     _dbus_babysitter_unref (sitter);
01483 
01484   if (!dbus_error_is_set (&error))
01485     {
01486       _dbus_warn ("Did not get an error launching binary that exited with failure code\n");
01487       return FALSE;
01488     }
01489 
01490   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
01491         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
01492     {
01493       _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n",
01494                   error.name, error.message);
01495       dbus_error_free (&error);
01496       return FALSE;
01497     }
01498 
01499   dbus_error_free (&error);
01500   
01501   return TRUE;
01502 }
01503 
01504 static dbus_bool_t
01505 check_spawn_and_kill (void *data)
01506 {
01507   char *argv[4] = { NULL, NULL, NULL, NULL };
01508   DBusBabysitter *sitter = NULL;
01509   DBusError error = DBUS_ERROR_INIT;
01510   DBusString argv0;
01511 
01512   /*** Test launching sleeping binary then killing it */
01513 
01514   argv[0] = get_test_exec ("test-sleep-forever", &argv0);
01515 
01516   if (argv[0] == NULL)
01517     {
01518       /* OOM was simulated, never mind */
01519       return TRUE;
01520     }
01521 
01522   if (_dbus_spawn_async_with_babysitter (&sitter, argv,
01523                                          NULL, NULL, NULL,
01524                                          &error))
01525     {
01526       _dbus_babysitter_kill_child (sitter);
01527       
01528       _dbus_babysitter_block_for_child_exit (sitter);
01529       
01530       _dbus_babysitter_set_child_exit_error (sitter, &error);
01531     }
01532 
01533   _dbus_string_free (&argv0);
01534 
01535   if (sitter)
01536     _dbus_babysitter_unref (sitter);
01537 
01538   if (!dbus_error_is_set (&error))
01539     {
01540       _dbus_warn ("Did not get an error after killing spawned binary\n");
01541       return FALSE;
01542     }
01543 
01544   if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
01545         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
01546     {
01547       _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
01548                   error.name, error.message);
01549       dbus_error_free (&error);
01550       return FALSE;
01551     }
01552 
01553   dbus_error_free (&error);
01554   
01555   return TRUE;
01556 }
01557 
01558 dbus_bool_t
01559 _dbus_spawn_test (const char *test_data_dir)
01560 {
01561   if (!_dbus_test_oom_handling ("spawn_nonexistent",
01562                                 check_spawn_nonexistent,
01563                                 NULL))
01564     return FALSE;
01565 
01566   if (!_dbus_test_oom_handling ("spawn_segfault",
01567                                 check_spawn_segfault,
01568                                 NULL))
01569     return FALSE;
01570 
01571   if (!_dbus_test_oom_handling ("spawn_exit",
01572                                 check_spawn_exit,
01573                                 NULL))
01574     return FALSE;
01575 
01576   if (!_dbus_test_oom_handling ("spawn_and_kill",
01577                                 check_spawn_and_kill,
01578                                 NULL))
01579     return FALSE;
01580   
01581   return TRUE;
01582 }
01583 #endif