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"
42 #include <systemd/sd-journal.h>
45 extern char **environ;
77 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
86 to_read =
sizeof (int) * n_ints_in_buf - bytes;
97 if (chunk < 0 && errno == EINTR)
104 "Failed to read from child pipe (%s)",
105 _dbus_strerror (errno));
119 *n_ints_read = (int)(bytes /
sizeof(
int));
132 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
141 to_read =
sizeof (pid_t) - bytes;
149 ((
char*)buf) + bytes,
151 if (chunk < 0 && errno == EINTR)
158 "Failed to read from child pipe (%s)",
159 _dbus_strerror (errno));
254 DBusBabysitterFinishedFunc finished_cb;
259 unsigned int have_child_status : 1;
265 _dbus_babysitter_new (
void)
336 close_socket_to_babysitter (sitter);
338 close_error_pipe_from_child (sitter);
349 ret = waitpid (sitter->
sitter_pid, &status, WNOHANG);
361 ret = waitpid (sitter->
sitter_pid, &status, 0);
363 while (_DBUS_UNLIKELY (ret < 0 && errno == EINTR));
369 _dbus_warn (
"Babysitter process not available to be reaped; should not happen\n");
371 _dbus_warn (
"Unexpected error %d in waitpid() for babysitter: %s\n",
372 errno, _dbus_strerror (errno));
376 _dbus_verbose (
"Reaped %ld, waiting for babysitter %ld\n",
379 if (WIFEXITED (sitter->
status))
380 _dbus_verbose (
"Babysitter exited with status %d\n",
381 WEXITSTATUS (sitter->
status));
382 else if (WIFSIGNALED (sitter->
status))
383 _dbus_verbose (
"Babysitter received signal %d\n",
384 WTERMSIG (sitter->
status));
386 _dbus_verbose (
"Babysitter exited abnormally\n");
410 r = read_ints (fd, &what, 1, &got, &error);
431 case CHILD_FORK_FAILED:
432 case CHILD_EXEC_FAILED:
436 r = read_ints (fd, &arg, 1, &got, &error);
452 if (what == CHILD_EXITED)
454 sitter->have_child_status =
TRUE;
457 _dbus_verbose (
"recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n",
458 WIFEXITED (sitter->
status), WIFSIGNALED (sitter->
status),
459 WEXITSTATUS (sitter->
status), WTERMSIG (sitter->
status));
461 else if (what == CHILD_FORK_FAILED)
465 _dbus_verbose (
"recorded fork errnum %d\n", sitter->
errnum);
467 else if (what == CHILD_EXEC_FAILED)
471 _dbus_verbose (
"recorded exec errnum %d\n", sitter->
errnum);
480 r = read_pid (fd, &pid, &error);
496 _dbus_verbose (
"recorded grandchild pid %d\n", sitter->
grandchild_pid);
500 _dbus_warn (
"Unknown message received from babysitter process\n");
511 _dbus_verbose (
"Closing babysitter\n");
532 _dbus_verbose (
"Closing child error\n");
560 _dbus_verbose (
"Reading data from babysitter\n");
562 close_socket_to_babysitter (sitter);
566 close_socket_to_babysitter (sitter);
574 if (revents & _DBUS_POLLIN)
576 _dbus_verbose (
"Reading data from child error\n");
578 close_error_pipe_from_child (sitter);
582 close_error_pipe_from_child (sitter);
595 descriptors_ready =
FALSE;
623 while (ret < 0 && errno == EINTR);
625 if (ret == 0 && block)
631 while (ret < 0 && errno == EINTR);
636 descriptors_ready =
TRUE;
642 handle_error_pipe (sitter, fds[i].revents);
644 handle_babysitter_socket (sitter, fds[i].revents);
649 return descriptors_ready;
656 #define LIVE_CHILDREN(sitter) ((sitter)->socket_to_babysitter >= 0 || (sitter)->error_pipe_from_child >= 0)
670 babysitter_iteration (sitter,
TRUE);
672 _dbus_verbose (
"Got child PID %ld for killing\n",
692 babysitter_iteration (sitter,
FALSE))
718 if (!sitter->have_child_status ||
719 !(WIFEXITED (sitter->
status)))
722 *status = WEXITSTATUS (sitter->
status);
749 "Failed to execute program %s: %s",
755 "Failed to fork a new process %s: %s",
758 else if (sitter->have_child_status)
760 if (WIFEXITED (sitter->
status))
762 "Process %s exited with status %d",
764 else if (WIFSIGNALED (sitter->
status))
766 "Process %s received signal %d",
770 "Process %s exited abnormally",
776 "Process %s exited, reason unknown",
811 unsigned int condition,
829 handle_error_pipe (sitter, revents);
831 handle_babysitter_socket (sitter, revents);
834 babysitter_iteration (sitter,
FALSE))
843 sitter->finished_cb !=
NULL)
845 sitter->finished_cb (sitter, sitter->finished_data);
846 sitter->finished_cb =
NULL;
869 close_and_invalidate (
int *fd)
893 retval = pipe2 (p, O_CLOEXEC);
894 cloexec_done = retval >= 0;
898 if (retval < 0 && errno == ENOSYS)
904 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
910 "Failed to create pipe for communicating with child process (%s)",
911 _dbus_strerror (errno));
927 do_write (
int fd,
const void *buf,
size_t count)
929 size_t bytes_written;
936 ret = write (fd, ((
const char*)buf) + bytes_written, count - bytes_written);
944 _dbus_warn (
"Failed to write data to pipe!\n");
949 bytes_written += ret;
951 if (bytes_written < count)
956 write_err_and_exit (
int fd,
int msg)
960 do_write (fd, &msg,
sizeof (msg));
961 do_write (fd, &en,
sizeof (en));
967 write_pid (
int fd, pid_t pid)
971 do_write (fd, &msg,
sizeof (msg));
972 do_write (fd, &pid,
sizeof (pid));
976 write_status_and_exit (
int fd,
int status)
978 int msg = CHILD_EXITED;
980 do_write (fd, &msg,
sizeof (msg));
981 do_write (fd, &status,
sizeof (status));
987 do_exec (
int child_err_report_fd,
990 DBusSpawnChildSetupFunc child_setup,
993 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
997 _dbus_verbose_reset ();
1002 (* child_setup) (user_data);
1004 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1005 max_open = sysconf (_SC_OPEN_MAX);
1007 for (i = 3; i < max_open; i++)
1011 if (i == child_err_report_fd)
1014 retval = fcntl (i, F_GETFD);
1016 if (retval != -1 && !(retval & FD_CLOEXEC))
1017 _dbus_warn (
"Fd %d did not have the close-on-exec flag set!\n", i);
1028 execve (argv[0], argv, envp);
1031 write_err_and_exit (child_err_report_fd,
1036 check_babysit_events (pid_t grandchild_pid,
1045 ret = waitpid (grandchild_pid, &status, WNOHANG);
1050 while (ret < 0 && errno == EINTR);
1054 _dbus_verbose (
"no child exited\n");
1061 _dbus_warn (
"unexpected waitpid() failure in check_babysit_events(): %s\n",
1062 _dbus_strerror (errno));
1065 else if (ret == grandchild_pid)
1068 _dbus_verbose (
"reaped child pid %ld\n", (
long) ret);
1070 write_status_and_exit (parent_pipe, status);
1074 _dbus_warn (
"waitpid() reaped pid %d that we've never heard of\n",
1079 if (revents & _DBUS_POLLIN)
1081 _dbus_verbose (
"babysitter got POLLIN from parent pipe\n");
1087 _dbus_verbose (
"babysitter got POLLERR or POLLHUP from parent\n");
1092 static int babysit_sigchld_pipe = -1;
1095 babysit_signal_handler (
int signo)
1099 if (write (babysit_sigchld_pipe, &b, 1) <= 0)
1105 babysit (pid_t grandchild_pid,
1108 int sigchld_pipe[2];
1113 _dbus_verbose_reset ();
1120 if (pipe (sigchld_pipe) < 0)
1122 _dbus_warn (
"Not enough file descriptors to create pipe in babysitter process\n");
1126 babysit_sigchld_pipe = sigchld_pipe[
WRITE_END];
1130 write_pid (parent_pipe, grandchild_pid);
1132 check_babysit_events (grandchild_pid, parent_pipe, 0);
1138 pfds[0].
fd = parent_pipe;
1148 _dbus_warn (
"_dbus_poll() error: %s\n", strerror (errno));
1152 if (pfds[0].revents != 0)
1154 check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents);
1156 else if (pfds[1].revents & _DBUS_POLLIN)
1159 if (read (sigchld_pipe[
READ_END], &b, 1) == -1)
1164 check_babysit_events (grandchild_pid, parent_pipe, 0);
1192 const char *log_name,
1195 DBusSpawnChildSetupFunc child_setup,
1200 int child_err_report_pipe[2] = { -1, -1 };
1201 int babysitter_pipe[2] = { -1, -1 };
1208 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1211 if (sitter_p !=
NULL)
1216 sitter = _dbus_babysitter_new ();
1227 goto cleanup_and_fail;
1236 goto cleanup_and_fail;
1239 if (!make_pipe (child_err_report_pipe, error))
1240 goto cleanup_and_fail;
1243 goto cleanup_and_fail;
1251 DBUS_WATCH_READABLE,
1256 goto cleanup_and_fail;
1268 goto cleanup_and_fail;
1272 DBUS_WATCH_READABLE,
1277 goto cleanup_and_fail;
1289 goto cleanup_and_fail;
1292 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1299 fd_out = sd_journal_stream_fd (sitter->
log_name, LOG_INFO,
FALSE);
1300 fd_err = sd_journal_stream_fd (sitter->
log_name, LOG_WARNING,
FALSE);
1309 "Failed to fork (%s)",
1310 _dbus_strerror (errno));
1311 goto cleanup_and_fail;
1321 signal (SIGPIPE, SIG_DFL);
1324 close_and_invalidate (&child_err_report_pipe[READ_END]);
1325 close_and_invalidate (&babysitter_pipe[0]);
1328 grandchild_pid = fork ();
1330 if (grandchild_pid < 0)
1332 write_err_and_exit (babysitter_pipe[1],
1336 else if (grandchild_pid == 0)
1340 signal (SIGPIPE, SIG_IGN);
1342 close_and_invalidate (&babysitter_pipe[1]);
1346 dup2 (fd_out, STDOUT_FILENO);
1348 dup2 (fd_err, STDERR_FILENO);
1349 close_and_invalidate (&fd_out);
1350 close_and_invalidate (&fd_err);
1352 do_exec (child_err_report_pipe[
WRITE_END],
1355 child_setup, user_data);
1360 close_and_invalidate (&child_err_report_pipe[
WRITE_END]);
1362 close_and_invalidate (&fd_out);
1363 close_and_invalidate (&fd_err);
1365 babysit (grandchild_pid, babysitter_pipe[1]);
1372 close_and_invalidate (&child_err_report_pipe[
WRITE_END]);
1373 close_and_invalidate (&babysitter_pipe[1]);
1375 close_and_invalidate (&fd_out);
1376 close_and_invalidate (&fd_err);
1380 babysitter_pipe[0] = -1;
1383 child_err_report_pipe[
READ_END] = -1;
1387 if (sitter_p !=
NULL)
1394 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1401 _DBUS_ASSERT_ERROR_IS_SET (error);
1403 close_and_invalidate (&child_err_report_pipe[READ_END]);
1404 close_and_invalidate (&child_err_report_pipe[
WRITE_END]);
1405 close_and_invalidate (&babysitter_pipe[0]);
1406 close_and_invalidate (&babysitter_pipe[1]);
1408 close_and_invalidate (&fd_out);
1409 close_and_invalidate (&fd_err);
1420 DBusBabysitterFinishedFunc finished,
1423 sitter->finished_cb = finished;
1424 sitter->finished_data = user_data;
1429 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1432 get_test_exec (
const char *exe,
1435 const char *dbus_test_exec;
1439 if (dbus_test_exec ==
NULL)
1440 dbus_test_exec = DBUS_TEST_EXEC;
1446 dbus_test_exec, exe, DBUS_EXEEXT))
1452 return _dbus_string_get_data (scratch_space);
1459 babysitter_iteration (sitter,
TRUE);
1463 check_spawn_nonexistent (
void *data)
1471 argv[0] =
"/this/does/not/exist/32542sdgafgafdg";
1476 _dbus_babysitter_block_for_child_exit (sitter);
1485 _dbus_warn (
"Did not get an error launching nonexistent executable\n");
1492 _dbus_warn (
"Not expecting error when launching nonexistent executable: %s: %s\n",
1504 check_spawn_segfault (
void *data)
1513 argv[0] = get_test_exec (
"test-segfault", &argv0);
1515 if (argv[0] ==
NULL)
1525 _dbus_babysitter_block_for_child_exit (sitter);
1536 _dbus_warn (
"Did not get an error launching segfaulting binary\n");
1543 _dbus_warn (
"Not expecting error when launching segfaulting executable: %s: %s\n",
1555 check_spawn_exit (
void *data)
1564 argv[0] = get_test_exec (
"test-exit", &argv0);
1566 if (argv[0] ==
NULL)
1576 _dbus_babysitter_block_for_child_exit (sitter);
1587 _dbus_warn (
"Did not get an error launching binary that exited with failure code\n");
1594 _dbus_warn (
"Not expecting error when launching exiting executable: %s: %s\n",
1606 check_spawn_and_kill (
void *data)
1615 argv[0] = get_test_exec (
"test-sleep-forever", &argv0);
1617 if (argv[0] ==
NULL)
1629 _dbus_babysitter_block_for_child_exit (sitter);
1641 _dbus_warn (
"Did not get an error after killing spawned binary\n");
1648 _dbus_warn (
"Not expecting error when killing executable: %s: %s\n",
1660 _dbus_spawn_test (
const char *test_data_dir)
1662 if (!_dbus_test_oom_handling (
"spawn_nonexistent",
1663 check_spawn_nonexistent,
1667 if (!_dbus_test_oom_handling (
"spawn_segfault",
1668 check_spawn_segfault,
1672 if (!_dbus_test_oom_handling (
"spawn_exit",
1677 if (!_dbus_test_oom_handling (
"spawn_and_kill",
1678 check_spawn_and_kill,