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; }
static unsigned __stdcall babysitter (void *parameter) { DBusBabysitter *sitter = (DBusBabysitter *) parameter; int fd; PING(); _dbus_babysitter_ref (sitter); if (sitter->child_setup) { PING(); (*sitter->child_setup) (sitter->user_data); } _dbus_verbose ("babysitter: spawning %s\n", sitter->executable); PING(); if (sitter->envp != NULL) sitter->child_handle = (HANDLE) spawnve (P_NOWAIT, sitter->executable, (const char * const *) sitter->argv, (const char * const *) sitter->envp); else sitter->child_handle = (HANDLE) spawnv (P_NOWAIT, sitter->executable, (const char * const *) sitter->argv); PING(); if (sitter->child_handle == (HANDLE) -1) { sitter->child_handle = NULL; sitter->have_spawn_errno = TRUE; sitter->spawn_errno = errno; } PING(); SetEvent (sitter->start_sync_event); if (sitter->child_handle != NULL) { int ret; DWORD status; PING(); WaitForSingleObject (sitter->child_handle, INFINITE); PING(); ret = GetExitCodeProcess (sitter->child_handle, &status); sitter->child_status = status; sitter->have_child_status = TRUE; CloseHandle (sitter->child_handle); sitter->child_handle = NULL; } #ifdef DBUS_BUILD_TESTS SetEvent (sitter->end_sync_event); #endif PING(); send (sitter->socket_to_main, " ", 1, 0); _dbus_babysitter_unref (sitter); return 0; }