D-Bus 1.4.0
|
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 int errnum; 00209 int status; 00210 unsigned int have_child_status : 1; 00211 unsigned int have_fork_errnum : 1; 00212 unsigned int have_exec_errnum : 1; 00213 }; 00214 00215 static DBusBabysitter* 00216 _dbus_babysitter_new (void) 00217 { 00218 DBusBabysitter *sitter; 00219 00220 sitter = dbus_new0 (DBusBabysitter, 1); 00221 if (sitter == NULL) 00222 return NULL; 00223 00224 sitter->refcount = 1; 00225 00226 sitter->socket_to_babysitter = -1; 00227 sitter->error_pipe_from_child = -1; 00228 00229 sitter->sitter_pid = -1; 00230 sitter->grandchild_pid = -1; 00231 00232 sitter->watches = _dbus_watch_list_new (); 00233 if (sitter->watches == NULL) 00234 goto failed; 00235 00236 return sitter; 00237 00238 failed: 00239 _dbus_babysitter_unref (sitter); 00240 return NULL; 00241 } 00242 00249 DBusBabysitter * 00250 _dbus_babysitter_ref (DBusBabysitter *sitter) 00251 { 00252 _dbus_assert (sitter != NULL); 00253 _dbus_assert (sitter->refcount > 0); 00254 00255 sitter->refcount += 1; 00256 00257 return sitter; 00258 } 00259 00268 void 00269 _dbus_babysitter_unref (DBusBabysitter *sitter) 00270 { 00271 _dbus_assert (sitter != NULL); 00272 _dbus_assert (sitter->refcount > 0); 00273 00274 sitter->refcount -= 1; 00275 if (sitter->refcount == 0) 00276 { 00277 if (sitter->socket_to_babysitter >= 0) 00278 { 00279 /* If we haven't forked other babysitters 00280 * since this babysitter and socket were 00281 * created then this close will cause the 00282 * babysitter to wake up from poll with 00283 * a hangup and then the babysitter will 00284 * quit itself. 00285 */ 00286 _dbus_close_socket (sitter->socket_to_babysitter, NULL); 00287 sitter->socket_to_babysitter = -1; 00288 } 00289 00290 if (sitter->error_pipe_from_child >= 0) 00291 { 00292 _dbus_close_socket (sitter->error_pipe_from_child, NULL); 00293 sitter->error_pipe_from_child = -1; 00294 } 00295 00296 if (sitter->sitter_pid > 0) 00297 { 00298 int status; 00299 int ret; 00300 00301 /* It's possible the babysitter died on its own above 00302 * from the close, or was killed randomly 00303 * by some other process, so first try to reap it 00304 */ 00305 ret = waitpid (sitter->sitter_pid, &status, WNOHANG); 00306 00307 /* If we couldn't reap the child then kill it, and 00308 * try again 00309 */ 00310 if (ret == 0) 00311 kill (sitter->sitter_pid, SIGKILL); 00312 00313 again: 00314 if (ret == 0) 00315 ret = waitpid (sitter->sitter_pid, &status, 0); 00316 00317 if (ret < 0) 00318 { 00319 if (errno == EINTR) 00320 goto again; 00321 else if (errno == ECHILD) 00322 _dbus_warn ("Babysitter process not available to be reaped; should not happen\n"); 00323 else 00324 _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s\n", 00325 errno, _dbus_strerror (errno)); 00326 } 00327 else 00328 { 00329 _dbus_verbose ("Reaped %ld, waiting for babysitter %ld\n", 00330 (long) ret, (long) sitter->sitter_pid); 00331 00332 if (WIFEXITED (sitter->status)) 00333 _dbus_verbose ("Babysitter exited with status %d\n", 00334 WEXITSTATUS (sitter->status)); 00335 else if (WIFSIGNALED (sitter->status)) 00336 _dbus_verbose ("Babysitter received signal %d\n", 00337 WTERMSIG (sitter->status)); 00338 else 00339 _dbus_verbose ("Babysitter exited abnormally\n"); 00340 } 00341 00342 sitter->sitter_pid = -1; 00343 } 00344 00345 if (sitter->error_watch) 00346 { 00347 _dbus_watch_invalidate (sitter->error_watch); 00348 _dbus_watch_unref (sitter->error_watch); 00349 sitter->error_watch = NULL; 00350 } 00351 00352 if (sitter->sitter_watch) 00353 { 00354 _dbus_watch_invalidate (sitter->sitter_watch); 00355 _dbus_watch_unref (sitter->sitter_watch); 00356 sitter->sitter_watch = NULL; 00357 } 00358 00359 if (sitter->watches) 00360 _dbus_watch_list_free (sitter->watches); 00361 00362 dbus_free (sitter->executable); 00363 00364 dbus_free (sitter); 00365 } 00366 } 00367 00368 static ReadStatus 00369 read_data (DBusBabysitter *sitter, 00370 int fd) 00371 { 00372 int what; 00373 int got; 00374 DBusError error = DBUS_ERROR_INIT; 00375 ReadStatus r; 00376 00377 r = read_ints (fd, &what, 1, &got, &error); 00378 00379 switch (r) 00380 { 00381 case READ_STATUS_ERROR: 00382 _dbus_warn ("Failed to read data from fd %d: %s\n", fd, error.message); 00383 dbus_error_free (&error); 00384 return r; 00385 00386 case READ_STATUS_EOF: 00387 return r; 00388 00389 case READ_STATUS_OK: 00390 break; 00391 } 00392 00393 if (got == 1) 00394 { 00395 switch (what) 00396 { 00397 case CHILD_EXITED: 00398 case CHILD_FORK_FAILED: 00399 case CHILD_EXEC_FAILED: 00400 { 00401 int arg; 00402 00403 r = read_ints (fd, &arg, 1, &got, &error); 00404 00405 switch (r) 00406 { 00407 case READ_STATUS_ERROR: 00408 _dbus_warn ("Failed to read arg from fd %d: %s\n", fd, error.message); 00409 dbus_error_free (&error); 00410 return r; 00411 case READ_STATUS_EOF: 00412 return r; 00413 case READ_STATUS_OK: 00414 break; 00415 } 00416 00417 if (got == 1) 00418 { 00419 if (what == CHILD_EXITED) 00420 { 00421 sitter->have_child_status = TRUE; 00422 sitter->status = arg; 00423 sitter->errnum = 0; 00424 _dbus_verbose ("recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n", 00425 WIFEXITED (sitter->status), WIFSIGNALED (sitter->status), 00426 WEXITSTATUS (sitter->status), WTERMSIG (sitter->status)); 00427 } 00428 else if (what == CHILD_FORK_FAILED) 00429 { 00430 sitter->have_fork_errnum = TRUE; 00431 sitter->errnum = arg; 00432 _dbus_verbose ("recorded fork errnum %d\n", sitter->errnum); 00433 } 00434 else if (what == CHILD_EXEC_FAILED) 00435 { 00436 sitter->have_exec_errnum = TRUE; 00437 sitter->errnum = arg; 00438 _dbus_verbose ("recorded exec errnum %d\n", sitter->errnum); 00439 } 00440 } 00441 } 00442 break; 00443 case CHILD_PID: 00444 { 00445 pid_t pid = -1; 00446 00447 r = read_pid (fd, &pid, &error); 00448 00449 switch (r) 00450 { 00451 case READ_STATUS_ERROR: 00452 _dbus_warn ("Failed to read PID from fd %d: %s\n", fd, error.message); 00453 dbus_error_free (&error); 00454 return r; 00455 case READ_STATUS_EOF: 00456 return r; 00457 case READ_STATUS_OK: 00458 break; 00459 } 00460 00461 sitter->grandchild_pid = pid; 00462 00463 _dbus_verbose ("recorded grandchild pid %d\n", sitter->grandchild_pid); 00464 } 00465 break; 00466 default: 00467 _dbus_warn ("Unknown message received from babysitter process\n"); 00468 break; 00469 } 00470 } 00471 00472 return r; 00473 } 00474 00475 static void 00476 close_socket_to_babysitter (DBusBabysitter *sitter) 00477 { 00478 _dbus_verbose ("Closing babysitter\n"); 00479 _dbus_close_socket (sitter->socket_to_babysitter, NULL); 00480 sitter->socket_to_babysitter = -1; 00481 } 00482 00483 static void 00484 close_error_pipe_from_child (DBusBabysitter *sitter) 00485 { 00486 _dbus_verbose ("Closing child error\n"); 00487 _dbus_close_socket (sitter->error_pipe_from_child, NULL); 00488 sitter->error_pipe_from_child = -1; 00489 } 00490 00491 static void 00492 handle_babysitter_socket (DBusBabysitter *sitter, 00493 int revents) 00494 { 00495 /* Even if we have POLLHUP, we want to keep reading 00496 * data until POLLIN goes away; so this function only 00497 * looks at HUP/ERR if no IN is set. 00498 */ 00499 if (revents & _DBUS_POLLIN) 00500 { 00501 _dbus_verbose ("Reading data from babysitter\n"); 00502 if (read_data (sitter, sitter->socket_to_babysitter) != READ_STATUS_OK) 00503 close_socket_to_babysitter (sitter); 00504 } 00505 else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP)) 00506 { 00507 close_socket_to_babysitter (sitter); 00508 } 00509 } 00510 00511 static void 00512 handle_error_pipe (DBusBabysitter *sitter, 00513 int revents) 00514 { 00515 if (revents & _DBUS_POLLIN) 00516 { 00517 _dbus_verbose ("Reading data from child error\n"); 00518 if (read_data (sitter, sitter->error_pipe_from_child) != READ_STATUS_OK) 00519 close_error_pipe_from_child (sitter); 00520 } 00521 else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP)) 00522 { 00523 close_error_pipe_from_child (sitter); 00524 } 00525 } 00526 00527 /* returns whether there were any poll events handled */ 00528 static dbus_bool_t 00529 babysitter_iteration (DBusBabysitter *sitter, 00530 dbus_bool_t block) 00531 { 00532 DBusPollFD fds[2]; 00533 int i; 00534 dbus_bool_t descriptors_ready; 00535 00536 descriptors_ready = FALSE; 00537 00538 i = 0; 00539 00540 if (sitter->error_pipe_from_child >= 0) 00541 { 00542 fds[i].fd = sitter->error_pipe_from_child; 00543 fds[i].events = _DBUS_POLLIN; 00544 fds[i].revents = 0; 00545 ++i; 00546 } 00547 00548 if (sitter->socket_to_babysitter >= 0) 00549 { 00550 fds[i].fd = sitter->socket_to_babysitter; 00551 fds[i].events = _DBUS_POLLIN; 00552 fds[i].revents = 0; 00553 ++i; 00554 } 00555 00556 if (i > 0) 00557 { 00558 int ret; 00559 00560 do 00561 { 00562 ret = _dbus_poll (fds, i, 0); 00563 } 00564 while (ret < 0 && errno == EINTR); 00565 00566 if (ret == 0 && block) 00567 { 00568 do 00569 { 00570 ret = _dbus_poll (fds, i, -1); 00571 } 00572 while (ret < 0 && errno == EINTR); 00573 } 00574 00575 if (ret > 0) 00576 { 00577 descriptors_ready = TRUE; 00578 00579 while (i > 0) 00580 { 00581 --i; 00582 if (fds[i].fd == sitter->error_pipe_from_child) 00583 handle_error_pipe (sitter, fds[i].revents); 00584 else if (fds[i].fd == sitter->socket_to_babysitter) 00585 handle_babysitter_socket (sitter, fds[i].revents); 00586 } 00587 } 00588 } 00589 00590 return descriptors_ready; 00591 } 00592 00597 #define LIVE_CHILDREN(sitter) ((sitter)->socket_to_babysitter >= 0 || (sitter)->error_pipe_from_child >= 0) 00598 00605 void 00606 _dbus_babysitter_kill_child (DBusBabysitter *sitter) 00607 { 00608 /* be sure we have the PID of the child */ 00609 while (LIVE_CHILDREN (sitter) && 00610 sitter->grandchild_pid == -1) 00611 babysitter_iteration (sitter, TRUE); 00612 00613 _dbus_verbose ("Got child PID %ld for killing\n", 00614 (long) sitter->grandchild_pid); 00615 00616 if (sitter->grandchild_pid == -1) 00617 return; /* child is already dead, or we're so hosed we'll never recover */ 00618 00619 kill (sitter->grandchild_pid, SIGKILL); 00620 } 00621 00627 dbus_bool_t 00628 _dbus_babysitter_get_child_exited (DBusBabysitter *sitter) 00629 { 00630 00631 /* Be sure we're up-to-date */ 00632 while (LIVE_CHILDREN (sitter) && 00633 babysitter_iteration (sitter, FALSE)) 00634 ; 00635 00636 /* We will have exited the babysitter when the child has exited */ 00637 return sitter->socket_to_babysitter < 0; 00638 } 00639 00652 dbus_bool_t 00653 _dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter, 00654 int *status) 00655 { 00656 if (!_dbus_babysitter_get_child_exited (sitter)) 00657 _dbus_assert_not_reached ("Child has not exited"); 00658 00659 if (!sitter->have_child_status || 00660 !(WIFEXITED (sitter->status))) 00661 return FALSE; 00662 00663 *status = WEXITSTATUS (sitter->status); 00664 return TRUE; 00665 } 00666 00676 void 00677 _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter, 00678 DBusError *error) 00679 { 00680 if (!_dbus_babysitter_get_child_exited (sitter)) 00681 return; 00682 00683 /* Note that if exec fails, we will also get a child status 00684 * from the babysitter saying the child exited, 00685 * so we need to give priority to the exec error 00686 */ 00687 if (sitter->have_exec_errnum) 00688 { 00689 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 00690 "Failed to execute program %s: %s", 00691 sitter->executable, _dbus_strerror (sitter->errnum)); 00692 } 00693 else if (sitter->have_fork_errnum) 00694 { 00695 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, 00696 "Failed to fork a new process %s: %s", 00697 sitter->executable, _dbus_strerror (sitter->errnum)); 00698 } 00699 else if (sitter->have_child_status) 00700 { 00701 if (WIFEXITED (sitter->status)) 00702 dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED, 00703 "Process %s exited with status %d", 00704 sitter->executable, WEXITSTATUS (sitter->status)); 00705 else if (WIFSIGNALED (sitter->status)) 00706 dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED, 00707 "Process %s received signal %d", 00708 sitter->executable, WTERMSIG (sitter->status)); 00709 else 00710 dbus_set_error (error, DBUS_ERROR_FAILED, 00711 "Process %s exited abnormally", 00712 sitter->executable); 00713 } 00714 else 00715 { 00716 dbus_set_error (error, DBUS_ERROR_FAILED, 00717 "Process %s exited, reason unknown", 00718 sitter->executable); 00719 } 00720 } 00721 00734 dbus_bool_t 00735 _dbus_babysitter_set_watch_functions (DBusBabysitter *sitter, 00736 DBusAddWatchFunction add_function, 00737 DBusRemoveWatchFunction remove_function, 00738 DBusWatchToggledFunction toggled_function, 00739 void *data, 00740 DBusFreeFunction free_data_function) 00741 { 00742 return _dbus_watch_list_set_functions (sitter->watches, 00743 add_function, 00744 remove_function, 00745 toggled_function, 00746 data, 00747 free_data_function); 00748 } 00749 00750 static dbus_bool_t 00751 handle_watch (DBusWatch *watch, 00752 unsigned int condition, 00753 void *data) 00754 { 00755 DBusBabysitter *sitter = data; 00756 int revents; 00757 int fd; 00758 00759 revents = 0; 00760 if (condition & DBUS_WATCH_READABLE) 00761 revents |= _DBUS_POLLIN; 00762 if (condition & DBUS_WATCH_ERROR) 00763 revents |= _DBUS_POLLERR; 00764 if (condition & DBUS_WATCH_HANGUP) 00765 revents |= _DBUS_POLLHUP; 00766 00767 fd = dbus_watch_get_socket (watch); 00768 00769 if (fd == sitter->error_pipe_from_child) 00770 handle_error_pipe (sitter, revents); 00771 else if (fd == sitter->socket_to_babysitter) 00772 handle_babysitter_socket (sitter, revents); 00773 00774 while (LIVE_CHILDREN (sitter) && 00775 babysitter_iteration (sitter, FALSE)) 00776 ; 00777 00778 return TRUE; 00779 } 00780 00782 #define READ_END 0 00783 00784 #define WRITE_END 1 00785 00786 00787 /* Avoids a danger in threaded situations (calling close() 00788 * on a file descriptor twice, and another thread has 00789 * re-opened it since the first close) 00790 */ 00791 static int 00792 close_and_invalidate (int *fd) 00793 { 00794 int ret; 00795 00796 if (*fd < 0) 00797 return -1; 00798 else 00799 { 00800 ret = _dbus_close_socket (*fd, NULL); 00801 *fd = -1; 00802 } 00803 00804 return ret; 00805 } 00806 00807 static dbus_bool_t 00808 make_pipe (int p[2], 00809 DBusError *error) 00810 { 00811 int retval; 00812 00813 #ifdef HAVE_PIPE2 00814 dbus_bool_t cloexec_done; 00815 00816 retval = pipe2 (p, O_CLOEXEC); 00817 cloexec_done = retval >= 0; 00818 00819 /* Check if kernel seems to be too old to know pipe2(). We assume 00820 that if pipe2 is available, O_CLOEXEC is too. */ 00821 if (retval < 0 && errno == ENOSYS) 00822 #endif 00823 { 00824 retval = pipe(p); 00825 } 00826 00827 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00828 00829 if (retval < 0) 00830 { 00831 dbus_set_error (error, 00832 DBUS_ERROR_SPAWN_FAILED, 00833 "Failed to create pipe for communicating with child process (%s)", 00834 _dbus_strerror (errno)); 00835 return FALSE; 00836 } 00837 00838 #ifdef HAVE_PIPE2 00839 if (!cloexec_done) 00840 #endif 00841 { 00842 _dbus_fd_set_close_on_exec (p[0]); 00843 _dbus_fd_set_close_on_exec (p[1]); 00844 } 00845 00846 return TRUE; 00847 } 00848 00849 static void 00850 do_write (int fd, const void *buf, size_t count) 00851 { 00852 size_t bytes_written; 00853 int ret; 00854 00855 bytes_written = 0; 00856 00857 again: 00858 00859 ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written); 00860 00861 if (ret < 0) 00862 { 00863 if (errno == EINTR) 00864 goto again; 00865 else 00866 { 00867 _dbus_warn ("Failed to write data to pipe!\n"); 00868 exit (1); /* give up, we suck */ 00869 } 00870 } 00871 else 00872 bytes_written += ret; 00873 00874 if (bytes_written < count) 00875 goto again; 00876 } 00877 00878 static void 00879 write_err_and_exit (int fd, int msg) 00880 { 00881 int en = errno; 00882 00883 do_write (fd, &msg, sizeof (msg)); 00884 do_write (fd, &en, sizeof (en)); 00885 00886 exit (1); 00887 } 00888 00889 static void 00890 write_pid (int fd, pid_t pid) 00891 { 00892 int msg = CHILD_PID; 00893 00894 do_write (fd, &msg, sizeof (msg)); 00895 do_write (fd, &pid, sizeof (pid)); 00896 } 00897 00898 static void 00899 write_status_and_exit (int fd, int status) 00900 { 00901 int msg = CHILD_EXITED; 00902 00903 do_write (fd, &msg, sizeof (msg)); 00904 do_write (fd, &status, sizeof (status)); 00905 00906 exit (0); 00907 } 00908 00909 static void 00910 do_exec (int child_err_report_fd, 00911 char **argv, 00912 char **envp, 00913 DBusSpawnChildSetupFunc child_setup, 00914 void *user_data) 00915 { 00916 #ifdef DBUS_BUILD_TESTS 00917 int i, max_open; 00918 #endif 00919 00920 _dbus_verbose_reset (); 00921 _dbus_verbose ("Child process has PID " DBUS_PID_FORMAT "\n", 00922 _dbus_getpid ()); 00923 00924 if (child_setup) 00925 (* child_setup) (user_data); 00926 00927 #ifdef DBUS_BUILD_TESTS 00928 max_open = sysconf (_SC_OPEN_MAX); 00929 00930 for (i = 3; i < max_open; i++) 00931 { 00932 int retval; 00933 00934 if (i == child_err_report_fd) 00935 continue; 00936 00937 retval = fcntl (i, F_GETFD); 00938 00939 if (retval != -1 && !(retval & FD_CLOEXEC)) 00940 _dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i); 00941 } 00942 #endif 00943 00944 if (envp == NULL) 00945 { 00946 _dbus_assert (environ != NULL); 00947 00948 envp = environ; 00949 } 00950 00951 execve (argv[0], argv, envp); 00952 00953 /* Exec failed */ 00954 write_err_and_exit (child_err_report_fd, 00955 CHILD_EXEC_FAILED); 00956 } 00957 00958 static void 00959 check_babysit_events (pid_t grandchild_pid, 00960 int parent_pipe, 00961 int revents) 00962 { 00963 pid_t ret; 00964 int status; 00965 00966 do 00967 { 00968 ret = waitpid (grandchild_pid, &status, WNOHANG); 00969 /* The man page says EINTR can't happen with WNOHANG, 00970 * but there are reports of it (maybe only with valgrind?) 00971 */ 00972 } 00973 while (ret < 0 && errno == EINTR); 00974 00975 if (ret == 0) 00976 { 00977 _dbus_verbose ("no child exited\n"); 00978 00979 ; /* no child exited */ 00980 } 00981 else if (ret < 0) 00982 { 00983 /* This isn't supposed to happen. */ 00984 _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s\n", 00985 _dbus_strerror (errno)); 00986 exit (1); 00987 } 00988 else if (ret == grandchild_pid) 00989 { 00990 /* Child exited */ 00991 _dbus_verbose ("reaped child pid %ld\n", (long) ret); 00992 00993 write_status_and_exit (parent_pipe, status); 00994 } 00995 else 00996 { 00997 _dbus_warn ("waitpid() reaped pid %d that we've never heard of\n", 00998 (int) ret); 00999 exit (1); 01000 } 01001 01002 if (revents & _DBUS_POLLIN) 01003 { 01004 _dbus_verbose ("babysitter got POLLIN from parent pipe\n"); 01005 } 01006 01007 if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP)) 01008 { 01009 /* Parent is gone, so we just exit */ 01010 _dbus_verbose ("babysitter got POLLERR or POLLHUP from parent\n"); 01011 exit (0); 01012 } 01013 } 01014 01015 static int babysit_sigchld_pipe = -1; 01016 01017 static void 01018 babysit_signal_handler (int signo) 01019 { 01020 char b = '\0'; 01021 again: 01022 if (write (babysit_sigchld_pipe, &b, 1) <= 0) 01023 if (errno == EINTR) 01024 goto again; 01025 } 01026 01027 static void 01028 babysit (pid_t grandchild_pid, 01029 int parent_pipe) 01030 { 01031 int sigchld_pipe[2]; 01032 01033 /* We don't exec, so we keep parent state, such as the pid that 01034 * _dbus_verbose() uses. Reset the pid here. 01035 */ 01036 _dbus_verbose_reset (); 01037 01038 /* I thought SIGCHLD would just wake up the poll, but 01039 * that didn't seem to work, so added this pipe. 01040 * Probably the pipe is more likely to work on busted 01041 * operating systems anyhow. 01042 */ 01043 if (pipe (sigchld_pipe) < 0) 01044 { 01045 _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n"); 01046 exit (1); 01047 } 01048 01049 babysit_sigchld_pipe = sigchld_pipe[WRITE_END]; 01050 01051 _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler); 01052 01053 write_pid (parent_pipe, grandchild_pid); 01054 01055 check_babysit_events (grandchild_pid, parent_pipe, 0); 01056 01057 while (TRUE) 01058 { 01059 DBusPollFD pfds[2]; 01060 01061 pfds[0].fd = parent_pipe; 01062 pfds[0].events = _DBUS_POLLIN; 01063 pfds[0].revents = 0; 01064 01065 pfds[1].fd = sigchld_pipe[READ_END]; 01066 pfds[1].events = _DBUS_POLLIN; 01067 pfds[1].revents = 0; 01068 01069 if (_dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1) < 0 && errno != EINTR) 01070 { 01071 _dbus_warn ("_dbus_poll() error: %s\n", strerror (errno)); 01072 exit (1); 01073 } 01074 01075 if (pfds[0].revents != 0) 01076 { 01077 check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents); 01078 } 01079 else if (pfds[1].revents & _DBUS_POLLIN) 01080 { 01081 char b; 01082 if (read (sigchld_pipe[READ_END], &b, 1) == -1) 01083 /* ignore */; 01084 /* do waitpid check */ 01085 check_babysit_events (grandchild_pid, parent_pipe, 0); 01086 } 01087 } 01088 01089 exit (1); 01090 } 01091 01111 dbus_bool_t 01112 _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, 01113 char **argv, 01114 char **env, 01115 DBusSpawnChildSetupFunc child_setup, 01116 void *user_data, 01117 DBusError *error) 01118 { 01119 DBusBabysitter *sitter; 01120 int child_err_report_pipe[2] = { -1, -1 }; 01121 int babysitter_pipe[2] = { -1, -1 }; 01122 pid_t pid; 01123 01124 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01125 01126 if (sitter_p != NULL) 01127 *sitter_p = NULL; 01128 01129 sitter = NULL; 01130 01131 sitter = _dbus_babysitter_new (); 01132 if (sitter == NULL) 01133 { 01134 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01135 return FALSE; 01136 } 01137 01138 sitter->executable = _dbus_strdup (argv[0]); 01139 if (sitter->executable == NULL) 01140 { 01141 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01142 goto cleanup_and_fail; 01143 } 01144 01145 if (!make_pipe (child_err_report_pipe, error)) 01146 goto cleanup_and_fail; 01147 01148 if (!_dbus_full_duplex_pipe (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error)) 01149 goto cleanup_and_fail; 01150 01151 /* Setting up the babysitter is only useful in the parent, 01152 * but we don't want to run out of memory and fail 01153 * after we've already forked, since then we'd leak 01154 * child processes everywhere. 01155 */ 01156 sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END], 01157 DBUS_WATCH_READABLE, 01158 TRUE, handle_watch, sitter, NULL); 01159 if (sitter->error_watch == NULL) 01160 { 01161 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01162 goto cleanup_and_fail; 01163 } 01164 01165 if (!_dbus_watch_list_add_watch (sitter->watches, sitter->error_watch)) 01166 { 01167 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01168 goto cleanup_and_fail; 01169 } 01170 01171 sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0], 01172 DBUS_WATCH_READABLE, 01173 TRUE, handle_watch, sitter, NULL); 01174 if (sitter->sitter_watch == NULL) 01175 { 01176 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01177 goto cleanup_and_fail; 01178 } 01179 01180 if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch)) 01181 { 01182 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01183 goto cleanup_and_fail; 01184 } 01185 01186 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01187 01188 pid = fork (); 01189 01190 if (pid < 0) 01191 { 01192 dbus_set_error (error, 01193 DBUS_ERROR_SPAWN_FORK_FAILED, 01194 "Failed to fork (%s)", 01195 _dbus_strerror (errno)); 01196 goto cleanup_and_fail; 01197 } 01198 else if (pid == 0) 01199 { 01200 /* Immediate child, this is the babysitter process. */ 01201 int grandchild_pid; 01202 01203 /* Be sure we crash if the parent exits 01204 * and we write to the err_report_pipe 01205 */ 01206 signal (SIGPIPE, SIG_DFL); 01207 01208 /* Close the parent's end of the pipes. */ 01209 close_and_invalidate (&child_err_report_pipe[READ_END]); 01210 close_and_invalidate (&babysitter_pipe[0]); 01211 01212 /* Create the child that will exec () */ 01213 grandchild_pid = fork (); 01214 01215 if (grandchild_pid < 0) 01216 { 01217 write_err_and_exit (babysitter_pipe[1], 01218 CHILD_FORK_FAILED); 01219 _dbus_assert_not_reached ("Got to code after write_err_and_exit()"); 01220 } 01221 else if (grandchild_pid == 0) 01222 { 01223 do_exec (child_err_report_pipe[WRITE_END], 01224 argv, 01225 env, 01226 child_setup, user_data); 01227 _dbus_assert_not_reached ("Got to code after exec() - should have exited on error"); 01228 } 01229 else 01230 { 01231 babysit (grandchild_pid, babysitter_pipe[1]); 01232 _dbus_assert_not_reached ("Got to code after babysit()"); 01233 } 01234 } 01235 else 01236 { 01237 /* Close the uncared-about ends of the pipes */ 01238 close_and_invalidate (&child_err_report_pipe[WRITE_END]); 01239 close_and_invalidate (&babysitter_pipe[1]); 01240 01241 sitter->socket_to_babysitter = babysitter_pipe[0]; 01242 babysitter_pipe[0] = -1; 01243 01244 sitter->error_pipe_from_child = child_err_report_pipe[READ_END]; 01245 child_err_report_pipe[READ_END] = -1; 01246 01247 sitter->sitter_pid = pid; 01248 01249 if (sitter_p != NULL) 01250 *sitter_p = sitter; 01251 else 01252 _dbus_babysitter_unref (sitter); 01253 01254 dbus_free_string_array (env); 01255 01256 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01257 01258 return TRUE; 01259 } 01260 01261 cleanup_and_fail: 01262 01263 _DBUS_ASSERT_ERROR_IS_SET (error); 01264 01265 close_and_invalidate (&child_err_report_pipe[READ_END]); 01266 close_and_invalidate (&child_err_report_pipe[WRITE_END]); 01267 close_and_invalidate (&babysitter_pipe[0]); 01268 close_and_invalidate (&babysitter_pipe[1]); 01269 01270 if (sitter != NULL) 01271 _dbus_babysitter_unref (sitter); 01272 01273 return FALSE; 01274 } 01275 01278 #ifdef DBUS_BUILD_TESTS 01279 01280 static void 01281 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter) 01282 { 01283 while (LIVE_CHILDREN (sitter)) 01284 babysitter_iteration (sitter, TRUE); 01285 } 01286 01287 static dbus_bool_t 01288 check_spawn_nonexistent (void *data) 01289 { 01290 char *argv[4] = { NULL, NULL, NULL, NULL }; 01291 DBusBabysitter *sitter = NULL; 01292 DBusError error = DBUS_ERROR_INIT; 01293 01294 /*** Test launching nonexistent binary */ 01295 01296 argv[0] = "/this/does/not/exist/32542sdgafgafdg"; 01297 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01298 NULL, NULL, NULL, 01299 &error)) 01300 { 01301 _dbus_babysitter_block_for_child_exit (sitter); 01302 _dbus_babysitter_set_child_exit_error (sitter, &error); 01303 } 01304 01305 if (sitter) 01306 _dbus_babysitter_unref (sitter); 01307 01308 if (!dbus_error_is_set (&error)) 01309 { 01310 _dbus_warn ("Did not get an error launching nonexistent executable\n"); 01311 return FALSE; 01312 } 01313 01314 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01315 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED))) 01316 { 01317 _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n", 01318 error.name, error.message); 01319 dbus_error_free (&error); 01320 return FALSE; 01321 } 01322 01323 dbus_error_free (&error); 01324 01325 return TRUE; 01326 } 01327 01328 static dbus_bool_t 01329 check_spawn_segfault (void *data) 01330 { 01331 char *argv[4] = { NULL, NULL, NULL, NULL }; 01332 DBusBabysitter *sitter = NULL; 01333 DBusError error = DBUS_ERROR_INIT; 01334 01335 /*** Test launching segfault binary */ 01336 01337 argv[0] = TEST_SEGFAULT_BINARY; 01338 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01339 NULL, NULL, NULL, 01340 &error)) 01341 { 01342 _dbus_babysitter_block_for_child_exit (sitter); 01343 _dbus_babysitter_set_child_exit_error (sitter, &error); 01344 } 01345 01346 if (sitter) 01347 _dbus_babysitter_unref (sitter); 01348 01349 if (!dbus_error_is_set (&error)) 01350 { 01351 _dbus_warn ("Did not get an error launching segfaulting binary\n"); 01352 return FALSE; 01353 } 01354 01355 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01356 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED))) 01357 { 01358 _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n", 01359 error.name, error.message); 01360 dbus_error_free (&error); 01361 return FALSE; 01362 } 01363 01364 dbus_error_free (&error); 01365 01366 return TRUE; 01367 } 01368 01369 static dbus_bool_t 01370 check_spawn_exit (void *data) 01371 { 01372 char *argv[4] = { NULL, NULL, NULL, NULL }; 01373 DBusBabysitter *sitter = NULL; 01374 DBusError error = DBUS_ERROR_INIT; 01375 01376 /*** Test launching exit failure binary */ 01377 01378 argv[0] = TEST_EXIT_BINARY; 01379 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01380 NULL, NULL, NULL, 01381 &error)) 01382 { 01383 _dbus_babysitter_block_for_child_exit (sitter); 01384 _dbus_babysitter_set_child_exit_error (sitter, &error); 01385 } 01386 01387 if (sitter) 01388 _dbus_babysitter_unref (sitter); 01389 01390 if (!dbus_error_is_set (&error)) 01391 { 01392 _dbus_warn ("Did not get an error launching binary that exited with failure code\n"); 01393 return FALSE; 01394 } 01395 01396 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01397 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 01398 { 01399 _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n", 01400 error.name, error.message); 01401 dbus_error_free (&error); 01402 return FALSE; 01403 } 01404 01405 dbus_error_free (&error); 01406 01407 return TRUE; 01408 } 01409 01410 static dbus_bool_t 01411 check_spawn_and_kill (void *data) 01412 { 01413 char *argv[4] = { NULL, NULL, NULL, NULL }; 01414 DBusBabysitter *sitter = NULL; 01415 DBusError error = DBUS_ERROR_INIT; 01416 01417 /*** Test launching sleeping binary then killing it */ 01418 01419 argv[0] = TEST_SLEEP_FOREVER_BINARY; 01420 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01421 NULL, NULL, NULL, 01422 &error)) 01423 { 01424 _dbus_babysitter_kill_child (sitter); 01425 01426 _dbus_babysitter_block_for_child_exit (sitter); 01427 01428 _dbus_babysitter_set_child_exit_error (sitter, &error); 01429 } 01430 01431 if (sitter) 01432 _dbus_babysitter_unref (sitter); 01433 01434 if (!dbus_error_is_set (&error)) 01435 { 01436 _dbus_warn ("Did not get an error after killing spawned binary\n"); 01437 return FALSE; 01438 } 01439 01440 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01441 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED))) 01442 { 01443 _dbus_warn ("Not expecting error when killing executable: %s: %s\n", 01444 error.name, error.message); 01445 dbus_error_free (&error); 01446 return FALSE; 01447 } 01448 01449 dbus_error_free (&error); 01450 01451 return TRUE; 01452 } 01453 01454 dbus_bool_t 01455 _dbus_spawn_test (const char *test_data_dir) 01456 { 01457 if (!_dbus_test_oom_handling ("spawn_nonexistent", 01458 check_spawn_nonexistent, 01459 NULL)) 01460 return FALSE; 01461 01462 if (!_dbus_test_oom_handling ("spawn_segfault", 01463 check_spawn_segfault, 01464 NULL)) 01465 return FALSE; 01466 01467 if (!_dbus_test_oom_handling ("spawn_exit", 01468 check_spawn_exit, 01469 NULL)) 01470 return FALSE; 01471 01472 if (!_dbus_test_oom_handling ("spawn_and_kill", 01473 check_spawn_and_kill, 01474 NULL)) 01475 return FALSE; 01476 01477 return TRUE; 01478 } 01479 #endif