diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/openrc/rc.c | 16 | 
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  | 
