summaryrefslogtreecommitdiffstats
path: root/dbus
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 /dbus
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.
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-spawn.c29
1 files changed, 26 insertions, 3 deletions
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)