Rename handle_signals() to dispatch_signals().
Block other signals in handler() so we don't have to worry about the write() being interrupted.
This commit is contained in:
16
src/exec.c
16
src/exec.c
@@ -73,7 +73,7 @@ static pid_t ppgrp = -1;
|
|||||||
|
|
||||||
volatile pid_t cmnd_pid = -1;
|
volatile pid_t cmnd_pid = -1;
|
||||||
|
|
||||||
static int handle_signals(int sv[2], pid_t child, int log_io,
|
static int dispatch_signals(int sv[2], pid_t child, int log_io,
|
||||||
struct command_status *cstat);
|
struct command_status *cstat);
|
||||||
static void forward_signals(int fd);
|
static void forward_signals(int fd);
|
||||||
static void schedule_signal(int signo);
|
static void schedule_signal(int signo);
|
||||||
@@ -107,7 +107,7 @@ static int fork_cmnd(struct command_details *details, int sv[2])
|
|||||||
* we don't need to (e.g. command pgrp == parent pgrp).
|
* we don't need to (e.g. command pgrp == parent pgrp).
|
||||||
*/
|
*/
|
||||||
zero_bytes(&sa, sizeof(sa));
|
zero_bytes(&sa, sizeof(sa));
|
||||||
sigemptyset(&sa.sa_mask);
|
sigfillset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
|
sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
|
||||||
#ifdef SA_SIGINFO
|
#ifdef SA_SIGINFO
|
||||||
sa.sa_flags |= SA_SIGINFO;
|
sa.sa_flags |= SA_SIGINFO;
|
||||||
@@ -290,13 +290,13 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
|
|||||||
if (pipe_nonblock(signal_pipe) != 0)
|
if (pipe_nonblock(signal_pipe) != 0)
|
||||||
error(1, _("unable to create pipe"));
|
error(1, _("unable to create pipe"));
|
||||||
|
|
||||||
zero_bytes(&sa, sizeof(sa));
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Signals to forward to the child process (excluding SIGALRM and SIGCHLD).
|
* Signals to forward to the child process (excluding SIGALRM and SIGCHLD).
|
||||||
|
* We block all other signals while running the signal handler.
|
||||||
* Note: HP-UX select() will not be interrupted if SA_RESTART set.
|
* Note: HP-UX select() will not be interrupted if SA_RESTART set.
|
||||||
*/
|
*/
|
||||||
|
zero_bytes(&sa, sizeof(sa));
|
||||||
|
sigfillset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
|
sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
|
||||||
#ifdef SA_SIGINFO
|
#ifdef SA_SIGINFO
|
||||||
sa.sa_flags |= SA_SIGINFO;
|
sa.sa_flags |= SA_SIGINFO;
|
||||||
@@ -387,7 +387,7 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
|
|||||||
forward_signals(sv[0]);
|
forward_signals(sv[0]);
|
||||||
}
|
}
|
||||||
if (FD_ISSET(signal_pipe[0], fdsr)) {
|
if (FD_ISSET(signal_pipe[0], fdsr)) {
|
||||||
n = handle_signals(sv, child, log_io, cstat);
|
n = dispatch_signals(sv, child, log_io, cstat);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* Child has exited, cstat is set, we are done. */
|
/* Child has exited, cstat is set, we are done. */
|
||||||
break;
|
break;
|
||||||
@@ -498,14 +498,14 @@ do_tty_io:
|
|||||||
* Returns -1 on error, 0 on child exit, else 1.
|
* Returns -1 on error, 0 on child exit, else 1.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
handle_signals(int sv[2], pid_t child, int log_io, struct command_status *cstat)
|
dispatch_signals(int sv[2], pid_t child, int log_io, struct command_status *cstat)
|
||||||
{
|
{
|
||||||
char signame[SIG2STR_MAX];
|
char signame[SIG2STR_MAX];
|
||||||
unsigned char signo;
|
unsigned char signo;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
int status;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
debug_decl(handle_signals, SUDO_DEBUG_EXEC)
|
debug_decl(dispatch_signals, SUDO_DEBUG_EXEC)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* read signal pipe */
|
/* read signal pipe */
|
||||||
|
@@ -642,7 +642,13 @@ fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask)
|
|||||||
io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
|
io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We don't want to receive SIGTTIN/SIGTTOU, getting EIO is preferable. */
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
|
sigaction(SIGTTIN, &sa, NULL);
|
||||||
|
sigaction(SIGTTOU, &sa, NULL);
|
||||||
|
|
||||||
/* Job control signals to relay from parent to child. */
|
/* Job control signals to relay from parent to child. */
|
||||||
|
sigfillset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
|
sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
|
||||||
#ifdef SA_SIGINFO
|
#ifdef SA_SIGINFO
|
||||||
sa.sa_flags |= SA_SIGINFO;
|
sa.sa_flags |= SA_SIGINFO;
|
||||||
@@ -652,11 +658,6 @@ fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask)
|
|||||||
#endif
|
#endif
|
||||||
sigaction(SIGTSTP, &sa, NULL);
|
sigaction(SIGTSTP, &sa, NULL);
|
||||||
|
|
||||||
/* We don't want to receive SIGTTIN/SIGTTOU, getting EIO is preferable. */
|
|
||||||
sa.sa_handler = SIG_IGN;
|
|
||||||
sigaction(SIGTTIN, &sa, NULL);
|
|
||||||
sigaction(SIGTTOU, &sa, NULL);
|
|
||||||
|
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
/* Copy terminal attrs from user tty -> pty slave. */
|
/* Copy terminal attrs from user tty -> pty slave. */
|
||||||
if (term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
|
if (term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
|
||||||
@@ -998,6 +999,9 @@ exec_monitor(struct command_details *details, int backchannel)
|
|||||||
sigaction(SIGTTIN, &sa, NULL);
|
sigaction(SIGTTIN, &sa, NULL);
|
||||||
sigaction(SIGTTOU, &sa, NULL);
|
sigaction(SIGTTOU, &sa, NULL);
|
||||||
|
|
||||||
|
/* Block all signals in mon_handler(). */
|
||||||
|
sigfillset(&sa.sa_mask);
|
||||||
|
|
||||||
/* Note: HP-UX select() will not be interrupted if SA_RESTART set */
|
/* Note: HP-UX select() will not be interrupted if SA_RESTART set */
|
||||||
sa.sa_flags = SA_INTERRUPT;
|
sa.sa_flags = SA_INTERRUPT;
|
||||||
#ifdef SA_SIGINFO
|
#ifdef SA_SIGINFO
|
||||||
|
Reference in New Issue
Block a user