summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2005-06-28 15:14:21 +0000
committerRay Strode <rstrode@redhat.com>2005-06-28 15:14:21 +0000
commitc17dc995ce22d873c7e2410b71cf96833d9bb58a (patch)
tree1b809abf8779a1a4d4ecf34608ee798278bb8cb4
parent0c6f2bbff503c10212589c1540d06b29395587aa (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--ChangeLog5
-rw-r--r--dbus/dbus-spawn.c29
2 files changed, 31 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 6253b8f4..7445f929 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)