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 #include #include +#include #include #include #include @@ -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]; diff --git a/job.c b/job.c index ebf44595..9c6bba6e 100644 --- a/job.c +++ b/job.c @@ -51,6 +51,7 @@ job_run(const char *cmd, struct session *s, const char *cwd, pid_t pid; int nullfd, out[2]; const char *home; + sigset_t set, oldset; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0) return (NULL); @@ -61,14 +62,18 @@ job_run(const char *cmd, struct session *s, const char *cwd, */ env = environ_for_session(s, !cfg_finished); + sigfillset(&set); + sigprocmask(SIG_BLOCK, &set, &oldset); switch (pid = fork()) { case -1: + sigprocmask(SIG_SETMASK, &oldset, NULL); environ_free(env); close(out[0]); close(out[1]); return (NULL); - case 0: /* child */ + case 0: proc_clear_signals(server_proc); + sigprocmask(SIG_SETMASK, &oldset, NULL); if (cwd == NULL || chdir(cwd) != 0) { if ((home = find_home()) == NULL || chdir(home) != 0) @@ -100,7 +105,7 @@ job_run(const char *cmd, struct session *s, const char *cwd, fatal("execl failed"); } - /* parent */ + sigprocmask(SIG_SETMASK, &oldset, NULL); environ_free(env); close(out[1]); diff --git a/server.c b/server.c index aa2afb1d..3bb5f56b 100644 --- a/server.c +++ b/server.c @@ -141,21 +141,24 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd, { int pair[2]; struct job *job; + sigset_t set, oldset; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) fatal("socketpair failed"); + sigfillset(&set); + sigprocmask(SIG_BLOCK, &set, &oldset); switch (fork()) { case -1: fatal("fork failed"); case 0: break; default: + sigprocmask(SIG_SETMASK, &oldset, NULL); close(pair[1]); return (pair[0]); } close(pair[0]); - if (daemon(1, 0) != 0) fatal("daemon failed"); proc_clear_signals(client); @@ -163,6 +166,7 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd, fatalx("event_reinit failed"); server_proc = proc_start("server"); proc_set_signals(server_proc, server_signal); + sigprocmask(SIG_SETMASK, &oldset, NULL); if (log_get_level() > 1) tty_create_log(); diff --git a/window.c b/window.c index 5c0cf01d..08d2c6e5 100644 --- a/window.c +++ b/window.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -886,6 +887,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, const char *ptr, *first, *home; struct termios tio2; int i; + sigset_t set, oldset; if (wp->fd != -1) { bufferevent_free(wp->event); @@ -915,14 +917,21 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, ws.ws_col = screen_size_x(&wp->base); ws.ws_row = screen_size_y(&wp->base); - wp->pid = fdforkpty(ptm_fd, &wp->fd, wp->tty, NULL, &ws); - switch (wp->pid) { + sigfillset(&set); + sigprocmask(SIG_BLOCK, &set, &oldset); + switch (wp->pid = fdforkpty(ptm_fd, &wp->fd, wp->tty, NULL, &ws)) { case -1: wp->fd = -1; + xasprintf(cause, "%s: %s", cmd, strerror(errno)); free(cmd); + + sigprocmask(SIG_SETMASK, &oldset, NULL); return (-1); case 0: + proc_clear_signals(server_proc); + sigprocmask(SIG_SETMASK, &oldset, NULL); + if (chdir(wp->cwd) != 0) { if ((home = find_home()) == NULL || chdir(home) != 0) chdir("/"); @@ -936,6 +945,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, if (tcsetattr(STDIN_FILENO, TCSANOW, &tio2) != 0) fatal("tcgetattr failed"); + log_close(); closefrom(STDERR_FILENO + 1); if (path != NULL) @@ -943,9 +953,6 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, environ_set(env, "TMUX_PANE", "%%%u", wp->id); environ_push(env); - proc_clear_signals(server_proc); - log_close(); - setenv("SHELL", wp->shell, 1); ptr = strrchr(wp->shell, '/'); @@ -978,6 +985,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, fatal("execl failed"); } + sigprocmask(SIG_SETMASK, &oldset, NULL); setblocking(wp->fd, 0); wp->event = bufferevent_new(wp->fd, window_pane_read_callback, NULL,