From 9e0b6e599e0d942db6c1acebdaf683615b180571 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 28 Aug 2016 23:45:29 +0100 Subject: [PATCH] signal: fix handling of pending signals whose default behaviour is ignore Also noted by David Flamand. We make chksigs() a generally callable helper so that anyone who needs to check if a signal is pending can just ask it. This cleans up the (broken) poking around we were doing as well. This also cleans up some other freaky corner cases where signals delivered at the wrong time could be lost. --- Kernel/devio.c | 2 +- Kernel/include/kernel.h | 2 +- Kernel/process.c | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Kernel/devio.c b/Kernel/devio.c index e7dd5312..77d7371e 100644 --- a/Kernel/devio.c +++ b/Kernel/devio.c @@ -480,7 +480,7 @@ int psleep_flags_io(void *p, unsigned char flags, usize_t *n) return -1; } psleep(p); - if (udata.u_cursig || udata.u_ptab->p_pending) { /* messy */ + if (chksigs()) { if (!*n) { *n = (usize_t)-1; udata.u_error = EINTR; diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 01e5e000..3ecf6eac 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -828,7 +828,7 @@ extern ptptr getproc(void); extern void newproc(ptptr p); extern ptptr ptab_alloc(void); extern void ssig(ptptr proc, uint8_t sig); -extern void chksigs(void); +extern uint8_t chksigs(void); extern void program_vectors(uint16_t *pageptr); extern void sgrpsig(uint16_t pgrp, uint8_t sig); extern void unix_syscall(void); diff --git a/Kernel/process.c b/Kernel/process.c index 819a65e9..a5c0053f 100644 --- a/Kernel/process.c +++ b/Kernel/process.c @@ -448,18 +448,19 @@ static uint8_t dump_core(uint8_t sig) /* This sees if the current process has any signals set, and handles them. */ -void chksigs(void) +uint8_t chksigs(void) { uint8_t j; uint32_t pending = udata.u_ptab->p_pending & ~udata.u_ptab->p_held; int (**svec)(int) = &udata.u_sigvec[0]; uint32_t m; - /* Fast path - no signals pending means no work + /* Fast path - no signals pending means no work. + Cursig being set means we've already worked out what to do. Also don't do signal processing if we are in P_STOPPED. This isn't quite right but will paper over the holes for the moment FIXME */ - if (!pending || udata.u_ptab->p_status == P_STOPPED) + if (udata.u_cursig || !pending || udata.u_ptab->p_status == P_STOPPED) return; /* Dispatch the lowest numbered signal */ @@ -504,6 +505,7 @@ void chksigs(void) break; } } + return udata.u_cursig; } /* -- 2.34.1