summaryrefslogtreecommitdiff
path: root/dbus/dbus-spawn.c
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2013-11-01 11:43:57 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2013-11-01 11:43:57 +0000
commitc3f20a67e623f7277a9ca5610fa8416d6ed5c04d (patch)
tree286eb4e90846f6db08ff00a0a67505133defcb19 /dbus/dbus-spawn.c
parentaa4b9d39bd04d18b57af9b247a326f6b7c328254 (diff)
downloaddbus-c3f20a67e623f7277a9ca5610fa8416d6ed5c04d.tar.gz
dbus-spawn: draw a diagram
There are enough pipes, fds and processes here that it's important to keep track of them. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=60859
Diffstat (limited to 'dbus/dbus-spawn.c')
-rw-r--r--dbus/dbus-spawn.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c
index 7c46935a..3d8ed2e8 100644
--- a/dbus/dbus-spawn.c
+++ b/dbus/dbus-spawn.c
@@ -174,6 +174,48 @@ read_pid (int fd,
* and the grandchild. The grandchild is our spawned process. The intermediate
* child is a babysitter process; it keeps track of when the grandchild
* exits/crashes, and reaps the grandchild.
+ *
+ * We automatically reap the babysitter process, killing it if necessary,
+ * when the DBusBabysitter's refcount goes to zero.
+ *
+ * Processes:
+ *
+ * main process
+ * | fork() A
+ * \- babysitter
+ * | fork () B
+ * \- grandchild --> exec --> spawned process
+ *
+ * IPC:
+ * child_err_report_pipe
+ * /-----------<---------<--------------\
+ * | ^
+ * v |
+ * main process babysitter grandchild
+ * ^ ^
+ * v v
+ * \-------<->-------/
+ * babysitter_pipe
+ *
+ * child_err_report_pipe is genuinely a pipe.
+ * The READ_END (also called error_pipe_from_child) is used in the main
+ * process. The WRITE_END (also called child_err_report_fd) is used in
+ * the grandchild process.
+ *
+ * On failure, the grandchild process sends CHILD_EXEC_FAILED + errno.
+ * On success, the pipe just closes (because it's close-on-exec) without
+ * sending any bytes.
+ *
+ * babysitter_pipe is mis-named: it's really a bidirectional socketpair.
+ * The [0] end (also called socket_to_babysitter) is used in the main
+ * process, the [1] end (also called parent_pipe) is used in the babysitter.
+ *
+ * If the fork() labelled B in the diagram above fails, the babysitter sends
+ * CHILD_FORK_FAILED + errno.
+ * On success, the babysitter sends CHILD_PID + the grandchild's pid.
+ * On SIGCHLD, the babysitter sends CHILD_EXITED + the exit status.
+ * The main process doesn't explicitly send anything, but when it exits,
+ * the babysitter gets POLLHUP or POLLERR.
*/
/* Messages from children to parents */