27 #include "dbus-spawn.h" 
   28 #include "dbus-sysdeps-unix.h" 
   29 #include "dbus-internals.h" 
   30 #include "dbus-test.h" 
   31 #include "dbus-protocol.h" 
   45 #include <systemd/sd-journal.h> 
   48 #if defined(__APPLE__) 
   49 # include <crt_externs.h> 
   50 # define environ (*_NSGetEnviron ()) 
   51 #elif !HAVE_DECL_ENVIRON 
   52 extern char **environ;
 
   85   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
   94       to_read = 
sizeof (int) * n_ints_in_buf - bytes;
 
  102                     ((
char*)buf) + bytes,
 
  105       if (chunk < 0 && errno == EINTR)
 
  112                           "Failed to read from child pipe (%s)",
 
  113                           _dbus_strerror (errno));
 
  127   *n_ints_read = (int)(bytes / 
sizeof(
int));
 
  140   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
  149       to_read = 
sizeof (pid_t) - bytes;
 
  157                     ((
char*)buf) + bytes,
 
  159       if (chunk < 0 && errno == EINTR)
 
  166                           "Failed to read from child pipe (%s)",
 
  167                           _dbus_strerror (errno));
 
  262   DBusBabysitterFinishedFunc finished_cb;
 
  273 _dbus_babysitter_new (
void)
 
  281   sitter->refcount = 1;
 
  312   sitter->refcount += 1;
 
  334   sitter->refcount -= 1;
 
  335   if (sitter->refcount == 0)
 
  344       close_socket_to_babysitter (sitter);
 
  346       close_error_pipe_from_child (sitter);
 
  357           ret = waitpid (sitter->
sitter_pid, &status, WNOHANG);
 
  369                   ret = waitpid (sitter->
sitter_pid, &status, 0);
 
  371               while (_DBUS_UNLIKELY (ret < 0 && errno == EINTR));
 
  377                 _dbus_warn (
"Babysitter process not available to be reaped; should not happen");
 
  379                 _dbus_warn (
"Unexpected error %d in waitpid() for babysitter: %s",
 
  380                             errno, _dbus_strerror (errno));
 
  384               _dbus_verbose (
"Reaped %ld, waiting for babysitter %ld\n",
 
  387               if (WIFEXITED (sitter->
status))
 
  388                 _dbus_verbose (
"Babysitter exited with status %d\n",
 
  389                                WEXITSTATUS (sitter->
status));
 
  390               else if (WIFSIGNALED (sitter->
status))
 
  391                 _dbus_verbose (
"Babysitter received signal %d\n",
 
  392                                WTERMSIG (sitter->
status));
 
  394                 _dbus_verbose (
"Babysitter exited abnormally\n");
 
  418   r = read_ints (fd, &what, 1, &got, &error);
 
  443         case CHILD_FORK_FAILED:
 
  444         case CHILD_EXEC_FAILED:
 
  448             r = read_ints (fd, &arg, 1, &got, &error);
 
  467                 if (what == CHILD_EXITED)
 
  486                     sitter->have_child_status = 
TRUE;
 
  488                     _dbus_verbose (
"recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n",
 
  489                                    WIFEXITED (sitter->
status), WIFSIGNALED (sitter->
status),
 
  490                                    WEXITSTATUS (sitter->
status), WTERMSIG (sitter->
status));
 
  492                 else if (what == CHILD_FORK_FAILED)
 
  496                     _dbus_verbose (
"recorded fork errnum %d\n", sitter->
errnum);
 
  498                 else if (what == CHILD_EXEC_FAILED)
 
  502                     _dbus_verbose (
"recorded exec errnum %d\n", sitter->
errnum);
 
  511             r = read_pid (fd, &pid, &error);
 
  530             _dbus_verbose (
"recorded grandchild pid %d\n", sitter->
grandchild_pid);
 
  534           _dbus_warn (
"Unknown message received from babysitter process");
 
  545   _dbus_verbose (
"Closing babysitter\n");
 
  566   _dbus_verbose (
"Closing child error\n");
 
  594       _dbus_verbose (
"Reading data from babysitter\n");
 
  596         close_socket_to_babysitter (sitter);
 
  600       close_socket_to_babysitter (sitter);
 
  610       _dbus_verbose (
"Reading data from child error\n");
 
  612         close_error_pipe_from_child (sitter);
 
  616       close_error_pipe_from_child (sitter);
 
  629   descriptors_ready = 
FALSE;
 
  657       while (ret < 0 && errno == EINTR);
 
  659       if (ret == 0 && block)
 
  665           while (ret < 0 && errno == EINTR);
 
  670           descriptors_ready = 
TRUE;
 
  676                 handle_error_pipe (sitter, fds[i].revents);
 
  678                 handle_babysitter_socket (sitter, fds[i].revents);
 
  683   return descriptors_ready;
 
  690 #define LIVE_CHILDREN(sitter) ((sitter)->socket_to_babysitter.fd >= 0 || (sitter)->error_pipe_from_child >= 0) 
  704     babysitter_iteration (sitter, 
TRUE);
 
  706   _dbus_verbose (
"Got child PID %ld for killing\n",
 
  726          babysitter_iteration (sitter, 
FALSE))
 
  752   if (!sitter->have_child_status ||
 
  753       !(WIFEXITED (sitter->
status)))
 
  756   *status = WEXITSTATUS (sitter->
status);
 
  783                       "Failed to execute program %s: %s",
 
  789                       "Failed to fork a new process %s: %s",
 
  792   else if (sitter->have_child_status)
 
  794       if (WIFEXITED (sitter->
status))
 
  796                         "Process %s exited with status %d",
 
  798       else if (WIFSIGNALED (sitter->
status))
 
  800                         "Process %s received signal %d",
 
  804                         "Process %s exited abnormally",
 
  810                       "Process %s exited, reason unknown",
 
  845               unsigned int     condition,
 
  863     handle_error_pipe (sitter, revents);
 
  865     handle_babysitter_socket (sitter, revents);
 
  868          babysitter_iteration (sitter, 
FALSE))
 
  877       sitter->finished_cb != 
NULL)
 
  879       sitter->finished_cb (sitter, sitter->finished_data);
 
  880       sitter->finished_cb = 
NULL;
 
  903 close_and_invalidate (
int *fd)
 
  927   retval = pipe2 (p, O_CLOEXEC);
 
  928   cloexec_done = retval >= 0;
 
  932   if (retval < 0 && errno == ENOSYS)
 
  938   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
  944                       "Failed to create pipe for communicating with child process (%s)",
 
  945                       _dbus_strerror (errno));
 
  961 do_write (
int fd, 
const void *buf, 
size_t count)
 
  963   size_t bytes_written;
 
  970   ret = write (fd, ((
const char*)buf) + bytes_written, count - bytes_written);
 
  983     bytes_written += ret;
 
  985   if (bytes_written < count)
 
  989 static void write_err_and_exit (
int fd, 
int msg) _DBUS_GNUC_NORETURN;
 
  992 write_err_and_exit (
int fd, 
int msg)
 
  996   do_write (fd, &msg, 
sizeof (msg));
 
  997   do_write (fd, &en, 
sizeof (en));
 
 1003 write_pid (
int fd, pid_t pid)
 
 1005   int msg = CHILD_PID;
 
 1007   do_write (fd, &msg, 
sizeof (msg));
 
 1008   do_write (fd, &pid, 
sizeof (pid));
 
 1011 static void write_status_and_exit (
int fd, 
int status) _DBUS_GNUC_NORETURN;
 
 1014 write_status_and_exit (
int fd, 
int status)
 
 1016   int msg = CHILD_EXITED;
 
 1018   do_write (fd, &msg, 
sizeof (msg));
 
 1019   do_write (fd, &status, 
sizeof (status));
 
 1024 static void do_exec (
int                       child_err_report_fd,
 
 1027                      DBusSpawnChildSetupFunc   child_setup,
 
 1028                      void                     *user_data) _DBUS_GNUC_NORETURN;
 
 1031 do_exec (
int                       child_err_report_fd,
 
 1034          DBusSpawnChildSetupFunc   child_setup,
 
 1037 #ifdef DBUS_ENABLE_EMBEDDED_TESTS 
 1041   _dbus_verbose_reset ();
 
 1046     (* child_setup) (user_data);
 
 1048 #ifdef DBUS_ENABLE_EMBEDDED_TESTS 
 1049   max_open = sysconf (_SC_OPEN_MAX);
 
 1051   for (i = 3; i < max_open; i++)
 
 1055       if (i == child_err_report_fd)
 
 1058       retval = fcntl (i, F_GETFD);
 
 1060       if (retval != -1 && !(retval & FD_CLOEXEC))
 
 1061         _dbus_warn (
"Fd %d did not have the close-on-exec flag set!", i);
 
 1072   execve (argv[0], argv, envp);
 
 1075   write_err_and_exit (child_err_report_fd,
 
 1080 check_babysit_events (pid_t grandchild_pid,
 
 1089       ret = waitpid (grandchild_pid, &status, WNOHANG);
 
 1094   while (ret < 0 && errno == EINTR);
 
 1098       _dbus_verbose (
"no child exited\n");
 
 1105       _dbus_warn (
"unexpected waitpid() failure in check_babysit_events(): %s",
 
 1106                   _dbus_strerror (errno));
 
 1109   else if (ret == grandchild_pid)
 
 1112       _dbus_verbose (
"reaped child pid %ld\n", (
long) ret);
 
 1114       write_status_and_exit (parent_pipe, status);
 
 1118       _dbus_warn (
"waitpid() reaped pid %d that we've never heard of",
 
 1125       _dbus_verbose (
"babysitter got POLLIN from parent pipe\n");
 
 1131       _dbus_verbose (
"babysitter got POLLERR or POLLHUP from parent\n");
 
 1136 static int babysit_sigchld_pipe = -1;
 
 1139 babysit_signal_handler (
int signo)
 
 1143   int saved_errno = errno;
 
 1147   if (write (babysit_sigchld_pipe, &b, 1) <= 0) 
 
 1151   errno = saved_errno;
 
 1154 static void babysit (pid_t grandchild_pid,
 
 1155                      int   parent_pipe) _DBUS_GNUC_NORETURN;
 
 1158 babysit (pid_t grandchild_pid,
 
 1161   int sigchld_pipe[2];
 
 1166   _dbus_verbose_reset ();
 
 1173   if (pipe (sigchld_pipe) < 0)
 
 1175       _dbus_warn (
"Not enough file descriptors to create pipe in babysitter process");
 
 1179   babysit_sigchld_pipe = sigchld_pipe[
WRITE_END];
 
 1183   write_pid (parent_pipe, grandchild_pid);
 
 1185   check_babysit_events (grandchild_pid, parent_pipe, 0);
 
 1191       pfds[0].
fd = parent_pipe;
 
 1201           _dbus_warn (
"_dbus_poll() error: %s", strerror (errno));
 
 1205       if (pfds[0].revents != 0)
 
 1207           check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents);
 
 1212           if (read (sigchld_pipe[
READ_END], &b, 1) == -1)
 
 1217           check_babysit_events (grandchild_pid, parent_pipe, 0);
 
 1250                                    const char               *log_name,
 
 1253                                    DBusSpawnFlags            flags,
 
 1254                                    DBusSpawnChildSetupFunc   child_setup,
 
 1259   int child_err_report_pipe[2] = { -1, -1 };
 
 1260   DBusSocket babysitter_pipe[2] = { DBUS_SOCKET_INIT, DBUS_SOCKET_INIT };
 
 1267   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
 1270   if (sitter_p != 
NULL)
 
 1275   sitter = _dbus_babysitter_new ();
 
 1286       goto cleanup_and_fail;
 
 1295       goto cleanup_and_fail;
 
 1298   if (!make_pipe (child_err_report_pipe, error))
 
 1299     goto cleanup_and_fail;
 
 1302     goto cleanup_and_fail;
 
 1315       goto cleanup_and_fail;
 
 1327       goto cleanup_and_fail;
 
 1336       goto cleanup_and_fail;
 
 1348       goto cleanup_and_fail;
 
 1351   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
 1354   if (flags & DBUS_SPAWN_REDIRECT_OUTPUT)
 
 1360       fd_out = sd_journal_stream_fd (sitter->
log_name, LOG_INFO, 
FALSE);
 
 1361       fd_err = sd_journal_stream_fd (sitter->
log_name, LOG_WARNING, 
FALSE);
 
 1371                       "Failed to fork (%s)",
 
 1372                       _dbus_strerror (errno));
 
 1373       goto cleanup_and_fail;
 
 1383       signal (SIGPIPE, SIG_DFL);
 
 1386       close_and_invalidate (&child_err_report_pipe[
READ_END]);
 
 1387       close_and_invalidate (&babysitter_pipe[0].fd);
 
 1390       grandchild_pid = fork ();
 
 1392       if (grandchild_pid < 0)
 
 1394           write_err_and_exit (babysitter_pipe[1].fd,
 
 1398       else if (grandchild_pid == 0)
 
 1404           fd = open (
"/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
 
 1409               fd = open (
"/proc/self/oom_score_adj", O_WRONLY);
 
 1415               if (write (fd, 
"0", 
sizeof (
char)) < 0)
 
 1416                 _dbus_warn (
"writing oom_score_adj error: %s", strerror (errno));
 
 1422           signal (SIGPIPE, SIG_IGN);
 
 1424           close_and_invalidate (&babysitter_pipe[1].fd);
 
 1428             dup2 (fd_out, STDOUT_FILENO);
 
 1430             dup2 (fd_err, STDERR_FILENO);
 
 1431           close_and_invalidate (&fd_out);
 
 1432           close_and_invalidate (&fd_err);
 
 1434           do_exec (child_err_report_pipe[
WRITE_END],
 
 1437                    child_setup, user_data);
 
 1442           close_and_invalidate (&child_err_report_pipe[
WRITE_END]);
 
 1444           close_and_invalidate (&fd_out);
 
 1445           close_and_invalidate (&fd_err);
 
 1447           babysit (grandchild_pid, babysitter_pipe[1].fd);
 
 1454       close_and_invalidate (&child_err_report_pipe[
WRITE_END]);
 
 1455       close_and_invalidate (&babysitter_pipe[1].fd);
 
 1457       close_and_invalidate (&fd_out);
 
 1458       close_and_invalidate (&fd_err);
 
 1462       babysitter_pipe[0].fd = -1;
 
 1465       child_err_report_pipe[
READ_END] = -1;
 
 1469       if (sitter_p != 
NULL)
 
 1476       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
 1483   _DBUS_ASSERT_ERROR_IS_SET (error);
 
 1485   close_and_invalidate (&child_err_report_pipe[
READ_END]);
 
 1486   close_and_invalidate (&child_err_report_pipe[
WRITE_END]);
 
 1487   close_and_invalidate (&babysitter_pipe[0].fd);
 
 1488   close_and_invalidate (&babysitter_pipe[1].fd);
 
 1490   close_and_invalidate (&fd_out);
 
 1491   close_and_invalidate (&fd_err);
 
 1502                                        DBusBabysitterFinishedFunc  finished,
 
 1505   sitter->finished_cb = finished;
 
 1506   sitter->finished_data = user_data;
 
 1515     babysitter_iteration (sitter, 
TRUE);