summaryrefslogtreecommitdiff
path: root/signal.c
diff options
context:
space:
mode:
authorToby Goodwin <tjg@star.le.ac.uk>1999-01-11 10:55:18 +0000
committerToby Goodwin <toby@paccrat.org>2015-05-16 21:22:09 +0100
commite11c7df86144bed383ac6bbeaecc3017d18b37db (patch)
tree6fad44921723eab2f2eb1c76b7214b4e79b818f3 /signal.c
parent671e1e2d1599aa8c5f1010b3fe75c151c56a7403 (diff)
beta: rc-1.5b4
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/signal.c b/signal.c
index 1c3f812..1c59746 100644
--- a/signal.c
+++ b/signal.c
@@ -2,32 +2,51 @@
#include <signal.h>
#include <setjmp.h>
+
#include "rc.h"
#include "sigmsgs.h"
#include "jbwrap.h"
-Jbwrap slowbuf;
-volatile SIG_ATOMIC_T slow, interrupt_happened;
+#if HAVE_SA_INTERRUPT
+static void (*sys_signal(int signum, void (*handler)(int)))(int) {
+ struct sigaction new, old;
+
+ new.sa_handler = handler;
+ new.sa_flags = SA_INTERRUPT;
+ sigaction(signum, &new, &old);
+ return old.sa_handler;
+}
+#else
+#define sys_signal signal
+#endif
+
void (*sighandlers[NUMOFSIGNALS])(int);
-static volatile SIG_ATOMIC_T sigcount, caught[NUMOFSIGNALS];
+static volatile sig_atomic_t sigcount, caught[NUMOFSIGNALS];
extern void catcher(int s) {
if (caught[s] == 0) {
sigcount++;
caught[s] = 1;
}
- signal(s, catcher);
- interrupt_happened = TRUE;
-#ifndef HAVE_RESTARTABLE_SYSCALLS
- if (slow)
- longjmp(slowbuf.j, 1);
+ sys_signal(s, catcher);
+
+#if READLINE
+ if (rl_active)
+ siglongjmp(rl_buf.j, s);
+#endif /* READLINE */
+
+#if HAVE_RESTARTABLE_SYSCALLS
+ if (slow) {
+ siglongjmp(slowbuf.j, s);
+}
#endif
}
extern void sigchk() {
void (*h)(int);
int s, i;
+
if (sigcount == 0)
return; /* ho hum; life as usual */
if (forked)
@@ -53,11 +72,11 @@ extern void (*rc_signal(int s, void (*h)(int)))(int) {
sigchk();
old = sighandlers[s];
if (h == SIG_DFL || h == SIG_IGN) {
- signal(s, h);
sighandlers[s] = h;
+ sys_signal(s, h);
} else {
sighandlers[s] = h;
- signal(s, catcher);
+ sys_signal(s, catcher);
}
return old;
}
@@ -65,16 +84,18 @@ extern void (*rc_signal(int s, void (*h)(int)))(int) {
extern void initsignal() {
void (*h)(int);
int i;
+
for (i = 1; i < NUMOFSIGNALS; i++) {
- if ((h = signal(i, SIG_DFL)) != SIG_DFL)
- signal(i, h);
+ h = sys_signal(i, SIG_DFL);
+ if (h != SIG_DFL && h != SIG_ERR)
+ sys_signal(i, h);
sighandlers[i] = h;
}
-#ifdef SIGCLD
+#if HAVE_SYSV_SIGCLD
/* Ensure that SIGCLD is not SIG_IGN. Solaris's rshd does this. :-( */
- h = signal(SIGCLD, SIG_DFL);
- if (h != SIG_IGN)
- signal(SIGCLD, h);
+ h = sys_signal(SIGCLD, SIG_DFL);
+ if (h != SIG_IGN && h != SIG_ERR)
+ sys_signal(SIGCLD, h);
#endif
}