aboutsummaryrefslogtreecommitdiff
path: root/src/openrc/rc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openrc/rc.c')
-rw-r--r--src/openrc/rc.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/openrc/rc.c b/src/openrc/rc.c
index d162b514..b6bb811b 100644
--- a/src/openrc/rc.c
+++ b/src/openrc/rc.c
@@ -351,16 +351,31 @@ static char *get_krunlevel(void)
static void
add_pid(pid_t pid)
{
+ sigset_t sset, old;
RC_PID *p = xmalloc(sizeof(*p));
p->pid = pid;
+
+ /* this list will be accessed inside the SIGCHLD signal handler.
+ * so we need to ensure that the SIGCHLD handler doesn't get invoked
+ * while the list is at an inconsistent state.
+ */
+ sigemptyset(&sset);
+ sigaddset(&sset, SIGCHLD);
+ sigprocmask(SIG_SETMASK, &sset, &old);
LIST_INSERT_HEAD(&service_pids, p, entries);
+ sigprocmask(SIG_SETMASK, &old, NULL);
}
static void
remove_pid(pid_t pid, bool inside_signal)
{
+ sigset_t sset, old;
RC_PID *p, *tmp;
+ /* same rationale for blocking SIGCHLD as add_pid() */
+ sigemptyset(&sset);
+ sigaddset(&sset, SIGCHLD);
+ sigprocmask(SIG_SETMASK, &sset, &old);
LIST_FOREACH(p, &service_pids, entries) {
if (p->pid == pid) {
LIST_REMOVE(p, entries);
@@ -375,6 +390,7 @@ remove_pid(pid_t pid, bool inside_signal)
free(p);
}
}
+ sigprocmask(SIG_SETMASK, &old, NULL);
}
static void