static dbus_bool_t handle_watch (DBusWatch *watch, unsigned int condition, void *data) { DBusBabysitter *sitter = data; int revents; int fd; revents = 0; if (condition & DBUS_WATCH_READABLE) revents |= _DBUS_POLLIN; if (condition & DBUS_WATCH_ERROR) revents |= _DBUS_POLLERR; if (condition & DBUS_WATCH_HANGUP) revents |= _DBUS_POLLHUP; fd = dbus_watch_get_fd (watch); if (fd == sitter->error_pipe_from_child) handle_error_pipe (sitter, revents); else if (fd == sitter->socket_to_babysitter) handle_babysitter_socket (sitter, revents); while (LIVE_CHILDREN (sitter) && babysitter_iteration (sitter, FALSE)) ; return TRUE; }
static dbus_bool_t handle_watch (DBusWatch *watch, unsigned int condition, void *data) { DBusBabysitter *sitter = data; int revents; int fd; revents = 0; if (condition & DBUS_WATCH_READABLE) revents |= _DBUS_POLLIN; if (condition & DBUS_WATCH_ERROR) revents |= _DBUS_POLLERR; if (condition & DBUS_WATCH_HANGUP) revents |= _DBUS_POLLHUP; fd = dbus_watch_get_socket (watch); if (fd == sitter->error_pipe_from_child) handle_error_pipe (sitter, revents); else if (fd == sitter->socket_to_babysitter) handle_babysitter_socket (sitter, revents); while (LIVE_CHILDREN (sitter) && babysitter_iteration (sitter, FALSE)) ; /* Those might have closed the sockets we're watching. Before returning * to the main loop, we must sort that out. */ if (sitter->error_watch != NULL && sitter->error_pipe_from_child == -1) { _dbus_watch_invalidate (sitter->error_watch); if (sitter->watches != NULL) _dbus_watch_list_remove_watch (sitter->watches, sitter->error_watch); _dbus_watch_unref (sitter->error_watch); sitter->error_watch = NULL; } if (sitter->sitter_watch != NULL && sitter->socket_to_babysitter == -1) { _dbus_watch_invalidate (sitter->sitter_watch); if (sitter->watches != NULL) _dbus_watch_list_remove_watch (sitter->watches, sitter->sitter_watch); _dbus_watch_unref (sitter->sitter_watch); sitter->sitter_watch = NULL; } return TRUE; }
/** * Checks whether the child has exited, without blocking. * * @param sitter the babysitter */ dbus_bool_t _dbus_babysitter_get_child_exited (DBusBabysitter *sitter) { /* Be sure we're up-to-date */ while (LIVE_CHILDREN (sitter) && babysitter_iteration (sitter, FALSE)) ; /* We will have exited the babysitter when the child has exited */ return sitter->socket_to_babysitter.fd < 0; }
/** * Blocks until the babysitter process gives us the PID of the spawned grandchild, * then kills the spawned grandchild. * * @param sitter the babysitter object */ void _dbus_babysitter_kill_child (DBusBabysitter *sitter) { /* be sure we have the PID of the child */ while (LIVE_CHILDREN (sitter) && sitter->grandchild_pid == -1) babysitter_iteration (sitter, TRUE); _dbus_verbose ("Got child PID %ld for killing\n", (long) sitter->grandchild_pid); if (sitter->grandchild_pid == -1) return; /* child is already dead, or we're so hosed we'll never recover */ kill (sitter->grandchild_pid, SIGKILL); }
static dbus_bool_t handle_watch (DBusWatch *watch, unsigned int condition, void *data) { DBusBabysitter *sitter = _dbus_babysitter_ref (data); int revents; int fd; revents = 0; if (condition & DBUS_WATCH_READABLE) revents |= _DBUS_POLLIN; if (condition & DBUS_WATCH_ERROR) revents |= _DBUS_POLLERR; if (condition & DBUS_WATCH_HANGUP) revents |= _DBUS_POLLHUP; fd = dbus_watch_get_socket (watch); if (fd == sitter->error_pipe_from_child) handle_error_pipe (sitter, revents); else if (fd == sitter->socket_to_babysitter.fd) handle_babysitter_socket (sitter, revents); while (LIVE_CHILDREN (sitter) && babysitter_iteration (sitter, FALSE)) ; /* fd.o #32992: if the handle_* methods closed their sockets, they previously * didn't always remove the watches. Check that we don't regress. */ _dbus_assert (sitter->socket_to_babysitter.fd != -1 || sitter->sitter_watch == NULL); _dbus_assert (sitter->error_pipe_from_child != -1 || sitter->error_watch == NULL); if (_dbus_babysitter_get_child_exited (sitter) && sitter->finished_cb != NULL) { sitter->finished_cb (sitter, sitter->finished_data); sitter->finished_cb = NULL; } _dbus_babysitter_unref (sitter); return TRUE; }
void _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter) { while (LIVE_CHILDREN (sitter)) babysitter_iteration (sitter, TRUE); }