/*
* Activate all signal events for which the corresponding signal_pending[]
* flag is set.
- * Returns true if at least one sigevent has been activated.
*/
-static bool
+static void
sudo_ev_activate_sigevents(struct sudo_event_base *base)
{
struct sudo_event *ev;
sigset_t set, oset;
- bool ret = false;
int i;
debug_decl(sudo_ev_activate_sigevents, SUDO_DEBUG_EVENT)
- if (base->signal_caught == 0)
- debug_return_bool(false);
-
/*
* We treat this as a critical section since the signal handler
* could modify the siginfo[] entry.
ev->revents = ev->events & (SUDO_EV_SIGNAL|SUDO_EV_SIGINFO);
TAILQ_INSERT_TAIL(&base->active, ev, active_entries);
SET(ev->flags, SUDO_EVQ_ACTIVE);
- ret = true;
}
}
sigprocmask(SIG_SETMASK, &oset, NULL);
- debug_return_bool(ret);
+ debug_return;
}
/*
static void
signal_pipe_cb(int fd, int what, void *v)
{
+ struct sudo_event_base *base = v;
unsigned char ch;
+ ssize_t nread;
+ debug_decl(signal_pipe_cb, SUDO_DEBUG_EVENT)
/*
* Drain signal_pipe, the signal handler updated base->signals_pending.
* Actual processing of signal events is done when poll/select is
* interrupted by a signal.
*/
- while (read(fd, &ch, 1) > 0)
- continue;
+ while ((nread = read(fd, &ch, 1)) > 0) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: received signal %d", __func__, (int)ch);
+ }
+ if (nread == -1 && errno != EAGAIN) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "%s: error reading from signal pipe", __func__);
+ }
+
+ /* Activate signal events. */
+ sudo_ev_activate_sigevents(base);
+
+ debug_return;
}
struct sudo_event_base *
goto bad;
}
sudo_ev_init(&base->signal_event, base->signal_pipe[1],
- SUDO_EV_READ|SUDO_EV_PERSIST, signal_pipe_cb, NULL);
+ SUDO_EV_READ|SUDO_EV_PERSIST, signal_pipe_cb, base);
debug_return_ptr(base);
bad:
signal_base->signal_caught = 1;
/* Wake up the other end of the pipe. */
- while (write(signal_base->signal_pipe[0], &ch, 1) == -1) {
- if (errno != EINTR)
- break;
- }
+ ignore_result(write(signal_base->signal_pipe[0], &ch, 1));
}
}
continue;
if (errno == EINTR) {
/* Interrupted by signal, check for sigevents. */
- if (sudo_ev_activate_sigevents(base))
+ if (base->signal_caught) {
+ signal_pipe_cb(base->signal_pipe[1], SUDO_EV_READ, base);
break;
+ }
continue;
}
rc = -1;
break;
}
- /* Activate signal events, if any. */
- sudo_ev_activate_sigevents(base);
-
/*
* Service each event in the active queue.
* We store the current event pointer in the base so that