summaryrefslogtreecommitdiffstats
path: root/cmd-pipe-pane.c
diff options
context:
space:
mode:
authornicm <nicm>2017-07-12 10:04:51 +0000
committernicm <nicm>2017-07-12 10:04:51 +0000
commit51112221eeb31ced907f0dfcf077582996c20c07 (patch)
treea4920177e843248ced12e53de2777260191796ca /cmd-pipe-pane.c
parent0453ad01468460d5fca09457ed7c862685076931 (diff)
Block signals between forking and clearing signal handlers (or calling
event_reinit) - if the child gets a signal and fires the libevent signal handler during this period it could write a signal into the parent's signal pipe. GitHub issue 1001 from Aaron van Geffen.
Diffstat (limited to 'cmd-pipe-pane.c')
-rw-r--r--cmd-pipe-pane.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/cmd-pipe-pane.c b/cmd-pipe-pane.c
index bb7630c0..c2ec3ac3 100644
--- a/cmd-pipe-pane.c
+++ b/cmd-pipe-pane.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
+#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -62,6 +63,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item)
char *cmd;
int old_fd, pipe_fd[2], null_fd;
struct format_tree *ft;
+ sigset_t set, oldset;
/* Destroy the old pipe. */
old_fd = wp->pipe_fd;
@@ -102,16 +104,20 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item)
format_free(ft);
/* Fork the child. */
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, &oldset);
switch (fork()) {
case -1:
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
cmdq_error(item, "fork error: %s", strerror(errno));
free(cmd);
return (CMD_RETURN_ERROR);
case 0:
/* Child process. */
- close(pipe_fd[0]);
proc_clear_signals(server_proc);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ close(pipe_fd[0]);
if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
_exit(1);
@@ -132,6 +138,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item)
_exit(1);
default:
/* Parent process. */
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
close(pipe_fd[1]);
wp->pipe_fd = pipe_fd[0];