diff options
author | Ray Strode <rstrode@redhat.com> | 2005-06-28 15:14:21 +0000 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2005-06-28 15:14:21 +0000 |
commit | c17dc995ce22d873c7e2410b71cf96833d9bb58a (patch) | |
tree | 1b809abf8779a1a4d4ecf34608ee798278bb8cb4 | |
parent | 0c6f2bbff503c10212589c1540d06b29395587aa (diff) |
2005-06-28 Ray Strode <rstrode@redhat.com>
* dbus/dbus-spawn.c (_dbus_babysitter_unref): kill
babysitter helper process on last unref, bug #2813.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | dbus/dbus-spawn.c | 29 |
2 files changed, 31 insertions, 3 deletions
@@ -1,3 +1,8 @@ +2005-06-28 Ray Strode <rstrode@redhat.com> + + * dbus/dbus-spawn.c (_dbus_babysitter_unref): kill + babysitter helper process on last unref, bug #2813. + 2005-06-27 Colin Walters <walters@verbum.org> * test/glib/test-dbus-glib.c: diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c index db8192fa..1ab16b97 100644 --- a/dbus/dbus-spawn.c +++ b/dbus/dbus-spawn.c @@ -252,6 +252,9 @@ _dbus_babysitter_ref (DBusBabysitter *sitter) /** * Decrement the reference count on the babysitter object. + * When the reference count of the babysitter object reaches + * zero, the babysitter is killed and the child that was being + * babysat gets emancipated. * * @param sitter the babysitter */ @@ -266,6 +269,13 @@ _dbus_babysitter_unref (DBusBabysitter *sitter) { if (sitter->socket_to_babysitter >= 0) { + /* If we haven't forked other babysitters + * since this babysitter and socket were + * created then this close will cause the + * babysitter to wake up from poll with + * a hangup and then the babysitter will + * quit itself. + */ close (sitter->socket_to_babysitter); sitter->socket_to_babysitter = -1; } @@ -276,14 +286,27 @@ _dbus_babysitter_unref (DBusBabysitter *sitter) sitter->error_pipe_from_child = -1; } - if (sitter->sitter_pid != -1) + if (sitter->sitter_pid > 0) { int status; int ret; - /* Reap the babysitter */ + /* It's possible the babysitter died on its own above + * from the close, or was killed randomly + * by some other process, so first try to reap it + */ + ret = waitpid (sitter->sitter_pid, &status, WNOHANG); + + /* If we couldn't reap the child then kill it, and + * try again + */ + if (ret == 0) + kill (sitter->sitter_pid, SIGKILL); + again: - ret = waitpid (sitter->sitter_pid, &status, 0); + if (ret == 0) + ret = waitpid (sitter->sitter_pid, &status, 0); + if (ret < 0) { if (errno == EINTR) |