D-Bus
1.4.16
|
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 /* Those might have closed the sockets we're watching. Before returning 00779 * to the main loop, we must sort that out. */ 00780 00781 if (sitter->error_watch != NULL && sitter->error_pipe_from_child == -1) 00782 { 00783 _dbus_watch_invalidate (sitter->error_watch); 00784 00785 if (sitter->watches != NULL) 00786 _dbus_watch_list_remove_watch (sitter->watches, sitter->error_watch); 00787 00788 _dbus_watch_unref (sitter->error_watch); 00789 sitter->error_watch = NULL; 00790 } 00791 00792 if (sitter->sitter_watch != NULL && sitter->socket_to_babysitter == -1) 00793 { 00794 _dbus_watch_invalidate (sitter->sitter_watch); 00795 00796 if (sitter->watches != NULL) 00797 _dbus_watch_list_remove_watch (sitter->watches, sitter->sitter_watch); 00798 00799 _dbus_watch_unref (sitter->sitter_watch); 00800 sitter->sitter_watch = NULL; 00801 } 00802 00803 return TRUE; 00804 } 00805 00807 #define READ_END 0 00808 00809 #define WRITE_END 1 00810 00811 00812 /* Avoids a danger in threaded situations (calling close() 00813 * on a file descriptor twice, and another thread has 00814 * re-opened it since the first close) 00815 */ 00816 static int 00817 close_and_invalidate (int *fd) 00818 { 00819 int ret; 00820 00821 if (*fd < 0) 00822 return -1; 00823 else 00824 { 00825 ret = _dbus_close_socket (*fd, NULL); 00826 *fd = -1; 00827 } 00828 00829 return ret; 00830 } 00831 00832 static dbus_bool_t 00833 make_pipe (int p[2], 00834 DBusError *error) 00835 { 00836 int retval; 00837 00838 #ifdef HAVE_PIPE2 00839 dbus_bool_t cloexec_done; 00840 00841 retval = pipe2 (p, O_CLOEXEC); 00842 cloexec_done = retval >= 0; 00843 00844 /* Check if kernel seems to be too old to know pipe2(). We assume 00845 that if pipe2 is available, O_CLOEXEC is too. */ 00846 if (retval < 0 && errno == ENOSYS) 00847 #endif 00848 { 00849 retval = pipe(p); 00850 } 00851 00852 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00853 00854 if (retval < 0) 00855 { 00856 dbus_set_error (error, 00857 DBUS_ERROR_SPAWN_FAILED, 00858 "Failed to create pipe for communicating with child process (%s)", 00859 _dbus_strerror (errno)); 00860 return FALSE; 00861 } 00862 00863 #ifdef HAVE_PIPE2 00864 if (!cloexec_done) 00865 #endif 00866 { 00867 _dbus_fd_set_close_on_exec (p[0]); 00868 _dbus_fd_set_close_on_exec (p[1]); 00869 } 00870 00871 return TRUE; 00872 } 00873 00874 static void 00875 do_write (int fd, const void *buf, size_t count) 00876 { 00877 size_t bytes_written; 00878 int ret; 00879 00880 bytes_written = 0; 00881 00882 again: 00883 00884 ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written); 00885 00886 if (ret < 0) 00887 { 00888 if (errno == EINTR) 00889 goto again; 00890 else 00891 { 00892 _dbus_warn ("Failed to write data to pipe!\n"); 00893 exit (1); /* give up, we suck */ 00894 } 00895 } 00896 else 00897 bytes_written += ret; 00898 00899 if (bytes_written < count) 00900 goto again; 00901 } 00902 00903 static void 00904 write_err_and_exit (int fd, int msg) 00905 { 00906 int en = errno; 00907 00908 do_write (fd, &msg, sizeof (msg)); 00909 do_write (fd, &en, sizeof (en)); 00910 00911 exit (1); 00912 } 00913 00914 static void 00915 write_pid (int fd, pid_t pid) 00916 { 00917 int msg = CHILD_PID; 00918 00919 do_write (fd, &msg, sizeof (msg)); 00920 do_write (fd, &pid, sizeof (pid)); 00921 } 00922 00923 static void 00924 write_status_and_exit (int fd, int status) 00925 { 00926 int msg = CHILD_EXITED; 00927 00928 do_write (fd, &msg, sizeof (msg)); 00929 do_write (fd, &status, sizeof (status)); 00930 00931 exit (0); 00932 } 00933 00934 static void 00935 do_exec (int child_err_report_fd, 00936 char **argv, 00937 char **envp, 00938 DBusSpawnChildSetupFunc child_setup, 00939 void *user_data) 00940 { 00941 #ifdef DBUS_BUILD_TESTS 00942 int i, max_open; 00943 #endif 00944 00945 _dbus_verbose_reset (); 00946 _dbus_verbose ("Child process has PID " DBUS_PID_FORMAT "\n", 00947 _dbus_getpid ()); 00948 00949 if (child_setup) 00950 (* child_setup) (user_data); 00951 00952 #ifdef DBUS_BUILD_TESTS 00953 max_open = sysconf (_SC_OPEN_MAX); 00954 00955 for (i = 3; i < max_open; i++) 00956 { 00957 int retval; 00958 00959 if (i == child_err_report_fd) 00960 continue; 00961 00962 retval = fcntl (i, F_GETFD); 00963 00964 if (retval != -1 && !(retval & FD_CLOEXEC)) 00965 _dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i); 00966 } 00967 #endif 00968 00969 if (envp == NULL) 00970 { 00971 _dbus_assert (environ != NULL); 00972 00973 envp = environ; 00974 } 00975 00976 execve (argv[0], argv, envp); 00977 00978 /* Exec failed */ 00979 write_err_and_exit (child_err_report_fd, 00980 CHILD_EXEC_FAILED); 00981 } 00982 00983 static void 00984 check_babysit_events (pid_t grandchild_pid, 00985 int parent_pipe, 00986 int revents) 00987 { 00988 pid_t ret; 00989 int status; 00990 00991 do 00992 { 00993 ret = waitpid (grandchild_pid, &status, WNOHANG); 00994 /* The man page says EINTR can't happen with WNOHANG, 00995 * but there are reports of it (maybe only with valgrind?) 00996 */ 00997 } 00998 while (ret < 0 && errno == EINTR); 00999 01000 if (ret == 0) 01001 { 01002 _dbus_verbose ("no child exited\n"); 01003 01004 ; /* no child exited */ 01005 } 01006 else if (ret < 0) 01007 { 01008 /* This isn't supposed to happen. */ 01009 _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s\n", 01010 _dbus_strerror (errno)); 01011 exit (1); 01012 } 01013 else if (ret == grandchild_pid) 01014 { 01015 /* Child exited */ 01016 _dbus_verbose ("reaped child pid %ld\n", (long) ret); 01017 01018 write_status_and_exit (parent_pipe, status); 01019 } 01020 else 01021 { 01022 _dbus_warn ("waitpid() reaped pid %d that we've never heard of\n", 01023 (int) ret); 01024 exit (1); 01025 } 01026 01027 if (revents & _DBUS_POLLIN) 01028 { 01029 _dbus_verbose ("babysitter got POLLIN from parent pipe\n"); 01030 } 01031 01032 if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP)) 01033 { 01034 /* Parent is gone, so we just exit */ 01035 _dbus_verbose ("babysitter got POLLERR or POLLHUP from parent\n"); 01036 exit (0); 01037 } 01038 } 01039 01040 static int babysit_sigchld_pipe = -1; 01041 01042 static void 01043 babysit_signal_handler (int signo) 01044 { 01045 char b = '\0'; 01046 again: 01047 if (write (babysit_sigchld_pipe, &b, 1) <= 0) 01048 if (errno == EINTR) 01049 goto again; 01050 } 01051 01052 static void 01053 babysit (pid_t grandchild_pid, 01054 int parent_pipe) 01055 { 01056 int sigchld_pipe[2]; 01057 01058 /* We don't exec, so we keep parent state, such as the pid that 01059 * _dbus_verbose() uses. Reset the pid here. 01060 */ 01061 _dbus_verbose_reset (); 01062 01063 /* I thought SIGCHLD would just wake up the poll, but 01064 * that didn't seem to work, so added this pipe. 01065 * Probably the pipe is more likely to work on busted 01066 * operating systems anyhow. 01067 */ 01068 if (pipe (sigchld_pipe) < 0) 01069 { 01070 _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n"); 01071 exit (1); 01072 } 01073 01074 babysit_sigchld_pipe = sigchld_pipe[WRITE_END]; 01075 01076 _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler); 01077 01078 write_pid (parent_pipe, grandchild_pid); 01079 01080 check_babysit_events (grandchild_pid, parent_pipe, 0); 01081 01082 while (TRUE) 01083 { 01084 DBusPollFD pfds[2]; 01085 01086 pfds[0].fd = parent_pipe; 01087 pfds[0].events = _DBUS_POLLIN; 01088 pfds[0].revents = 0; 01089 01090 pfds[1].fd = sigchld_pipe[READ_END]; 01091 pfds[1].events = _DBUS_POLLIN; 01092 pfds[1].revents = 0; 01093 01094 if (_dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1) < 0 && errno != EINTR) 01095 { 01096 _dbus_warn ("_dbus_poll() error: %s\n", strerror (errno)); 01097 exit (1); 01098 } 01099 01100 if (pfds[0].revents != 0) 01101 { 01102 check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents); 01103 } 01104 else if (pfds[1].revents & _DBUS_POLLIN) 01105 { 01106 char b; 01107 if (read (sigchld_pipe[READ_END], &b, 1) == -1) 01108 /* ignore */; 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 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01193 goto cleanup_and_fail; 01194 } 01195 01196 sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0], 01197 DBUS_WATCH_READABLE, 01198 TRUE, handle_watch, sitter, NULL); 01199 if (sitter->sitter_watch == NULL) 01200 { 01201 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01202 goto cleanup_and_fail; 01203 } 01204 01205 if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch)) 01206 { 01207 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01208 goto cleanup_and_fail; 01209 } 01210 01211 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01212 01213 pid = fork (); 01214 01215 if (pid < 0) 01216 { 01217 dbus_set_error (error, 01218 DBUS_ERROR_SPAWN_FORK_FAILED, 01219 "Failed to fork (%s)", 01220 _dbus_strerror (errno)); 01221 goto cleanup_and_fail; 01222 } 01223 else if (pid == 0) 01224 { 01225 /* Immediate child, this is the babysitter process. */ 01226 int grandchild_pid; 01227 01228 /* Be sure we crash if the parent exits 01229 * and we write to the err_report_pipe 01230 */ 01231 signal (SIGPIPE, SIG_DFL); 01232 01233 /* Close the parent's end of the pipes. */ 01234 close_and_invalidate (&child_err_report_pipe[READ_END]); 01235 close_and_invalidate (&babysitter_pipe[0]); 01236 01237 /* Create the child that will exec () */ 01238 grandchild_pid = fork (); 01239 01240 if (grandchild_pid < 0) 01241 { 01242 write_err_and_exit (babysitter_pipe[1], 01243 CHILD_FORK_FAILED); 01244 _dbus_assert_not_reached ("Got to code after write_err_and_exit()"); 01245 } 01246 else if (grandchild_pid == 0) 01247 { 01248 do_exec (child_err_report_pipe[WRITE_END], 01249 argv, 01250 env, 01251 child_setup, user_data); 01252 _dbus_assert_not_reached ("Got to code after exec() - should have exited on error"); 01253 } 01254 else 01255 { 01256 babysit (grandchild_pid, babysitter_pipe[1]); 01257 _dbus_assert_not_reached ("Got to code after babysit()"); 01258 } 01259 } 01260 else 01261 { 01262 /* Close the uncared-about ends of the pipes */ 01263 close_and_invalidate (&child_err_report_pipe[WRITE_END]); 01264 close_and_invalidate (&babysitter_pipe[1]); 01265 01266 sitter->socket_to_babysitter = babysitter_pipe[0]; 01267 babysitter_pipe[0] = -1; 01268 01269 sitter->error_pipe_from_child = child_err_report_pipe[READ_END]; 01270 child_err_report_pipe[READ_END] = -1; 01271 01272 sitter->sitter_pid = pid; 01273 01274 if (sitter_p != NULL) 01275 *sitter_p = sitter; 01276 else 01277 _dbus_babysitter_unref (sitter); 01278 01279 dbus_free_string_array (env); 01280 01281 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01282 01283 return TRUE; 01284 } 01285 01286 cleanup_and_fail: 01287 01288 _DBUS_ASSERT_ERROR_IS_SET (error); 01289 01290 close_and_invalidate (&child_err_report_pipe[READ_END]); 01291 close_and_invalidate (&child_err_report_pipe[WRITE_END]); 01292 close_and_invalidate (&babysitter_pipe[0]); 01293 close_and_invalidate (&babysitter_pipe[1]); 01294 01295 if (sitter != NULL) 01296 _dbus_babysitter_unref (sitter); 01297 01298 return FALSE; 01299 } 01300 01303 #ifdef DBUS_BUILD_TESTS 01304 01305 static void 01306 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter) 01307 { 01308 while (LIVE_CHILDREN (sitter)) 01309 babysitter_iteration (sitter, TRUE); 01310 } 01311 01312 static dbus_bool_t 01313 check_spawn_nonexistent (void *data) 01314 { 01315 char *argv[4] = { NULL, NULL, NULL, NULL }; 01316 DBusBabysitter *sitter = NULL; 01317 DBusError error = DBUS_ERROR_INIT; 01318 01319 /*** Test launching nonexistent binary */ 01320 01321 argv[0] = "/this/does/not/exist/32542sdgafgafdg"; 01322 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01323 NULL, NULL, NULL, 01324 &error)) 01325 { 01326 _dbus_babysitter_block_for_child_exit (sitter); 01327 _dbus_babysitter_set_child_exit_error (sitter, &error); 01328 } 01329 01330 if (sitter) 01331 _dbus_babysitter_unref (sitter); 01332 01333 if (!dbus_error_is_set (&error)) 01334 { 01335 _dbus_warn ("Did not get an error launching nonexistent executable\n"); 01336 return FALSE; 01337 } 01338 01339 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01340 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED))) 01341 { 01342 _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n", 01343 error.name, error.message); 01344 dbus_error_free (&error); 01345 return FALSE; 01346 } 01347 01348 dbus_error_free (&error); 01349 01350 return TRUE; 01351 } 01352 01353 static dbus_bool_t 01354 check_spawn_segfault (void *data) 01355 { 01356 char *argv[4] = { NULL, NULL, NULL, NULL }; 01357 DBusBabysitter *sitter = NULL; 01358 DBusError error = DBUS_ERROR_INIT; 01359 01360 /*** Test launching segfault binary */ 01361 01362 argv[0] = TEST_SEGFAULT_BINARY; 01363 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01364 NULL, NULL, NULL, 01365 &error)) 01366 { 01367 _dbus_babysitter_block_for_child_exit (sitter); 01368 _dbus_babysitter_set_child_exit_error (sitter, &error); 01369 } 01370 01371 if (sitter) 01372 _dbus_babysitter_unref (sitter); 01373 01374 if (!dbus_error_is_set (&error)) 01375 { 01376 _dbus_warn ("Did not get an error launching segfaulting binary\n"); 01377 return FALSE; 01378 } 01379 01380 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01381 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED))) 01382 { 01383 _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n", 01384 error.name, error.message); 01385 dbus_error_free (&error); 01386 return FALSE; 01387 } 01388 01389 dbus_error_free (&error); 01390 01391 return TRUE; 01392 } 01393 01394 static dbus_bool_t 01395 check_spawn_exit (void *data) 01396 { 01397 char *argv[4] = { NULL, NULL, NULL, NULL }; 01398 DBusBabysitter *sitter = NULL; 01399 DBusError error = DBUS_ERROR_INIT; 01400 01401 /*** Test launching exit failure binary */ 01402 01403 argv[0] = TEST_EXIT_BINARY; 01404 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01405 NULL, NULL, NULL, 01406 &error)) 01407 { 01408 _dbus_babysitter_block_for_child_exit (sitter); 01409 _dbus_babysitter_set_child_exit_error (sitter, &error); 01410 } 01411 01412 if (sitter) 01413 _dbus_babysitter_unref (sitter); 01414 01415 if (!dbus_error_is_set (&error)) 01416 { 01417 _dbus_warn ("Did not get an error launching binary that exited with failure code\n"); 01418 return FALSE; 01419 } 01420 01421 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01422 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 01423 { 01424 _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n", 01425 error.name, error.message); 01426 dbus_error_free (&error); 01427 return FALSE; 01428 } 01429 01430 dbus_error_free (&error); 01431 01432 return TRUE; 01433 } 01434 01435 static dbus_bool_t 01436 check_spawn_and_kill (void *data) 01437 { 01438 char *argv[4] = { NULL, NULL, NULL, NULL }; 01439 DBusBabysitter *sitter = NULL; 01440 DBusError error = DBUS_ERROR_INIT; 01441 01442 /*** Test launching sleeping binary then killing it */ 01443 01444 argv[0] = TEST_SLEEP_FOREVER_BINARY; 01445 if (_dbus_spawn_async_with_babysitter (&sitter, argv, 01446 NULL, NULL, NULL, 01447 &error)) 01448 { 01449 _dbus_babysitter_kill_child (sitter); 01450 01451 _dbus_babysitter_block_for_child_exit (sitter); 01452 01453 _dbus_babysitter_set_child_exit_error (sitter, &error); 01454 } 01455 01456 if (sitter) 01457 _dbus_babysitter_unref (sitter); 01458 01459 if (!dbus_error_is_set (&error)) 01460 { 01461 _dbus_warn ("Did not get an error after killing spawned binary\n"); 01462 return FALSE; 01463 } 01464 01465 if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 01466 dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED))) 01467 { 01468 _dbus_warn ("Not expecting error when killing executable: %s: %s\n", 01469 error.name, error.message); 01470 dbus_error_free (&error); 01471 return FALSE; 01472 } 01473 01474 dbus_error_free (&error); 01475 01476 return TRUE; 01477 } 01478 01479 dbus_bool_t 01480 _dbus_spawn_test (const char *test_data_dir) 01481 { 01482 if (!_dbus_test_oom_handling ("spawn_nonexistent", 01483 check_spawn_nonexistent, 01484 NULL)) 01485 return FALSE; 01486 01487 if (!_dbus_test_oom_handling ("spawn_segfault", 01488 check_spawn_segfault, 01489 NULL)) 01490 return FALSE; 01491 01492 if (!_dbus_test_oom_handling ("spawn_exit", 01493 check_spawn_exit, 01494 NULL)) 01495 return FALSE; 01496 01497 if (!_dbus_test_oom_handling ("spawn_and_kill", 01498 check_spawn_and_kill, 01499 NULL)) 01500 return FALSE; 01501 01502 return TRUE; 01503 } 01504 #endif