1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
From: Christian Kastner <ckk@kvr.at>
Date: Wed, 23 Dec 2015 10:13:55 +0100
Subject: Signal handling issues
Move signal handling away from the obsolete API.
Fix provided by Justin Pryzby <justinpryzby@users.sourceforge.net>, as part of
a larger fix, so it has been split out.
Bug-Debian: https://bugs.debian.org/155109
Forwarded: no
Last-Update: 2015-12-22
---
cron.c | 8 ++++++++
popen.c | 17 +++++++++++------
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/cron.c b/cron.c
index 1db8569..f708bda 100644
--- a/cron.c
+++ b/cron.c
@@ -256,6 +256,7 @@ cron_sleep() {
#ifdef USE_SIGCHLD
static void
sigchld_handler(int x) {
+ int save_errno = errno;
WAIT_T waiter;
PID_T pid;
@@ -269,10 +270,12 @@ sigchld_handler(int x) {
case -1:
Debug(DPROC,
("[%d] sigchld...no children\n", getpid()))
+ errno = save_errno;
return;
case 0:
Debug(DPROC,
("[%d] sigchld...no dead kids\n", getpid()))
+ errno = save_errno;
return;
default:
Debug(DPROC,
@@ -280,6 +283,7 @@ sigchld_handler(int x) {
getpid(), pid, WEXITSTATUS(waiter)))
}
}
+ errno = save_errno;
}
#endif /*USE_SIGCHLD*/
@@ -287,6 +291,10 @@ sigchld_handler(int x) {
static void
sighup_handler(int x) {
log_close();
+
+ /* we should use sigaction for proper signal blocking as this
+ has a race, but... */
+ signal(SIGHUP, sighup_handler);
}
diff --git a/popen.c b/popen.c
index b5c3242..55fa64e 100644
--- a/popen.c
+++ b/popen.c
@@ -180,7 +180,7 @@ cron_pclose(iop)
FILE *iop;
{
register int fdes;
- int omask;
+ sigset_t omask, mask;
WAIT_T stat_loc;
PID_T pid;
@@ -191,10 +191,15 @@ cron_pclose(iop)
if (pids == 0 || pids[fdes = fileno(iop)] == 0)
return(-1);
(void)fclose(iop);
- omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
- while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1)
- ;
- (void)sigsetmask(omask);
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGQUIT);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGHUP);
+ sigprocmask(SIG_BLOCK, &mask, &omask);
+ pid = waitpid(pids[fdes], &stat_loc, 0);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
pids[fdes] = 0;
- return (pid == -1 ? -1 : WEXITSTATUS(stat_loc));
+ if (pid == -1 || !WIFEXITED(stat_loc))
+ return -1;
+ return WEXITSTATUS(stat_loc);
}
|