From 2dcdf14334aa9a5b4a53cbb1abebb0544b3710f9 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Sat, 9 Jan 2021 11:55:39 +0700 Subject: [PATCH] Migrate to POSIX signals. (#190) This removes SYSVSIGNALS as we're always and only using POSIX signals now. Some platform differences have been papered over. We used to only ignore SIGPIPE when using BSD signals, but we now ignore it all the time. While the SIGFPE code will now compile, it hasn't been updated to work on modern OSes fully yet as it will need to enable the correct FP exceptions. --- bin/compile-flags | 2 - bin/makefile-cygwin.x86_64-x | 2 +- bin/makefile-init.sparc | 2 +- bin/makefile-linux.386-x | 2 +- bin/makefile-linux.armv7l-x | 2 +- bin/makefile-linux.x86_64-x | 2 +- bin/makefile-sunos5.386-x | 4 +- bin/makefile-sunos5.i386-x | 2 +- bin/makefile-sunos5.sparc-x | 2 +- bin/makefile-sunos5.x86_64-x | 4 +- inc/keyeventdefs.h | 2 +- inc/timerdefs.h | 1 - inc/version.h | 2 - src/ether.c | 25 ++- src/inet.c | 24 +-- src/keyevent.c | 2 +- src/timer.c | 325 +++++++++++------------------------ src/unixfork.c | 21 +-- src/uraid.c | 13 +- src/xc.c | 15 +- 20 files changed, 161 insertions(+), 293 deletions(-) diff --git a/bin/compile-flags b/bin/compile-flags index 3a0cfb9..bb72fdd 100755 --- a/bin/compile-flags +++ b/bin/compile-flags @@ -11,8 +11,6 @@ Flag Name Meaning/Usage _________ ________________________________________________________ BYTESWAP Used when compiling for a hardware architecture that has byte-swapped words and word-swapped 32-bit cells, e.g. 80386. -SYSVSIGNALS True when compiling on a system that requires the use of - SYSV (rather than BSD) signal-handling code. I386 True if compiling for the Sun386i (not just any 80386); used because the 386i's display controller is odd. OS4 True if compiling for SunOS 4.x diff --git a/bin/makefile-cygwin.x86_64-x b/bin/makefile-cygwin.x86_64-x index 2c9acb0..7329117 100644 --- a/bin/makefile-cygwin.x86_64-x +++ b/bin/makefile-cygwin.x86_64-x @@ -24,7 +24,7 @@ DISPOPTFLAGS = -O2 -g3 FPFLAGS = DFLAGS = -DLINUX -DAIX -DOLD_CURSOR \ -DBYTESWAP -DFORKCOMM -DNOFORN -DLOGINT $(XFLAGS) \ - -DRELEASE=351 -DSYSVSIGNALS + -DRELEASE=351 LDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt LDELDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt diff --git a/bin/makefile-init.sparc b/bin/makefile-init.sparc index 220b06e..fda1910 100644 --- a/bin/makefile-init.sparc +++ b/bin/makefile-init.sparc @@ -49,7 +49,7 @@ MAIN = main DEBUGFLAGS = # -DSTACKCHECK -DFNSTKCHECK MACHINEFLAGS = -DOS5 -DAIX -DUSE_DLPI -DNOPIXRECT \ - -I$(OPENWINHOME)/include -DSYSVSIGNALS \ + -I$(OPENWINHOME)/include \ -DOLD_CURSOR -DLOGINT -DFORKCOMM -DLOCK_X_UPDATES INLINEFLAGS = diff --git a/bin/makefile-linux.386-x b/bin/makefile-linux.386-x index ce82bd8..25552e5 100644 --- a/bin/makefile-linux.386-x +++ b/bin/makefile-linux.386-x @@ -23,7 +23,7 @@ DISPOPTFLAGS = -O2 -g3 FPFLAGS = DFLAGS = -DLINUX -DAIX -DOLD_CURSOR \ -DBYTESWAP -DFORKCOMM -DNOFORN -DLOGINT $(XFLAGS) \ - -DRELEASE=351 -DSYSVSIGNALS + -DRELEASE=351 LDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt LDELDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt diff --git a/bin/makefile-linux.armv7l-x b/bin/makefile-linux.armv7l-x index 4959d81..6d6732d 100644 --- a/bin/makefile-linux.armv7l-x +++ b/bin/makefile-linux.armv7l-x @@ -23,7 +23,7 @@ DISPOPTFLAGS = -O2 -g3 FPFLAGS = DFLAGS = -DLINUX -DAIX -DOLD_CURSOR \ -DBYTESWAP -DFORKCOMM -DNOFORN -DLOGINT $(XFLAGS) \ - -DRELEASE=351 -DSYSVSIGNALS + -DRELEASE=351 LDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt LDELDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt diff --git a/bin/makefile-linux.x86_64-x b/bin/makefile-linux.x86_64-x index 2c9acb0..7329117 100644 --- a/bin/makefile-linux.x86_64-x +++ b/bin/makefile-linux.x86_64-x @@ -24,7 +24,7 @@ DISPOPTFLAGS = -O2 -g3 FPFLAGS = DFLAGS = -DLINUX -DAIX -DOLD_CURSOR \ -DBYTESWAP -DFORKCOMM -DNOFORN -DLOGINT $(XFLAGS) \ - -DRELEASE=351 -DSYSVSIGNALS + -DRELEASE=351 LDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt LDELDFLAGS = -L/usr/X11/lib -lX11 -lc -lm -lcrypt diff --git a/bin/makefile-sunos5.386-x b/bin/makefile-sunos5.386-x index 52b1c41..673bd4e 100644 --- a/bin/makefile-sunos5.386-x +++ b/bin/makefile-sunos5.386-x @@ -42,9 +42,7 @@ FPFLAGS = DFLAGS = $(XFLAGS) \ $(DEBUGFLAGS) \ - -DOS5 \ - -DBYTESWAP -DSYSVSIGNALS \ - -DOLD_CURSOR -DLOGINT \ + -DOS5 -DBYTESWAP -DOLD_CURSOR -DLOGINT \ -DNOPIXRECT -DFORKCOMM -DLOCK_X_UPDATES \ -DRELEASE=351 diff --git a/bin/makefile-sunos5.i386-x b/bin/makefile-sunos5.i386-x index 6de4e62..8ff3217 100644 --- a/bin/makefile-sunos5.i386-x +++ b/bin/makefile-sunos5.i386-x @@ -46,7 +46,7 @@ DFLAGS = $(XFLAGS) \ -DBYTESWAP \ -DOLD_CURSOR -DLOGINT \ -DNOPIXRECT -DFORKCOMM -DLOCK_X_UPDATES \ - -I$(OPENWINHOME)/include -DSYSVSIGNALS \ + -I$(OPENWINHOME)/include \ -DRELEASE=210 LDFLAGS = -R$(OPENWINHOME)/lib -L$(OPENWINHOME)/lib -lX11 -lc -lm -lsocket -lnsl diff --git a/bin/makefile-sunos5.sparc-x b/bin/makefile-sunos5.sparc-x index 85e4b1f..10dabee 100644 --- a/bin/makefile-sunos5.sparc-x +++ b/bin/makefile-sunos5.sparc-x @@ -45,7 +45,7 @@ MAIN = main DEBUGFLAGS = # -DSTACKCHECK -DFNSTKCHECK -MACHINEFLAGS = -DOS5 -DUSE_DLPI -DNOPIXRECT -DSYSVSIGNALS \ +MACHINEFLAGS = -DOS5 -DUSE_DLPI -DNOPIXRECT \ -DOLD_CURSOR -DLOGINT -DFORKCOMM -DLOCK_X_UPDATES INLINEFLAGS = diff --git a/bin/makefile-sunos5.x86_64-x b/bin/makefile-sunos5.x86_64-x index e21e33a..7075e95 100644 --- a/bin/makefile-sunos5.x86_64-x +++ b/bin/makefile-sunos5.x86_64-x @@ -42,9 +42,7 @@ FPFLAGS = DFLAGS = $(XFLAGS) \ $(DEBUGFLAGS) \ - -DOS5 \ - -DBYTESWAP -DSYSVSIGNALS \ - -DOLD_CURSOR -DLOGINT \ + -DOS5 -DBYTESWAP -DOLD_CURSOR -DLOGINT \ -DNOPIXRECT -DFORKCOMM -DLOCK_X_UPDATES \ -DUSE_DLPI \ -DRELEASE=351 diff --git a/inc/keyeventdefs.h b/inc/keyeventdefs.h index c0ec1fb..d296321 100644 --- a/inc/keyeventdefs.h +++ b/inc/keyeventdefs.h @@ -1,6 +1,6 @@ #ifndef KEYEVENTDEFS_H #define KEYEVENTDEFS_H 1 -void getsignaldata(int sig, int code, void *scp); +void getsignaldata(int sig); void kb_trans(u_short keycode, u_short upflg); void taking_mouse_down(void); void copy_cursor(int newx, int newy); diff --git a/inc/timerdefs.h b/inc/timerdefs.h index 27339d0..2c884c9 100644 --- a/inc/timerdefs.h +++ b/inc/timerdefs.h @@ -13,6 +13,5 @@ void int_block(void); void int_unblock(void); void int_timer_off(void); void int_timer_on(void); -void panicuraid(int sig, int code, void *scp, void *addr); void int_init(void); #endif diff --git a/inc/version.h b/inc/version.h index 3228e86..f918099 100644 --- a/inc/version.h +++ b/inc/version.h @@ -240,7 +240,6 @@ typedef signed char s_char; #ifdef OS5 /* Solaris, sort of SYSV-ish, but not really */ #undef NOETHER -#define SYSVSIGNALS 1 #define NOFORN #define LOCK_X_UPDATES 1 #endif /* OS5 */ @@ -288,7 +287,6 @@ typedef signed char s_char; typedef unsigned short u_short; #undef UNALIGNED_FETCH_OK #undef HAS_GETHOSTID -#define SYSVSIGNALS 1 #define USHORT unsigned #else #define USHORT unsigned short diff --git a/src/ether.c b/src/ether.c index 8ca8992..e25bb9d 100644 --- a/src/ether.c +++ b/src/ether.c @@ -366,29 +366,28 @@ LispPTR ether_get(LispPTR args[]) LispPTR result = NIL; #ifndef NOETHER LispPTR MaxByteCount; -#ifndef SYSVSIGNALS - int interrupt_mask; -#endif + sigset_t signals; + MaxByteCount = 2 * (0xFFFF & args[0]); /* words to bytes */ DBPRINT(("Ether Get. ")); -#ifdef SYSVSIGNALS - sighold(SIGIO); -#else - interrupt_mask = sigblock(sigmask(SIGIO)); /* turn off ENET interrupts */ -#endif /* SYSVSIGNALS */ + sigemptyset(&signals); + sigaddset(&signals, SIGIO); + + /* turn off ENET interrupts */ + sigprocmask(SIG_BLOCK, &signals, NULL); + if (ether_fd > 0 && (MaxByteCount > 0)) { ether_buf = (u_char *)Addr68k_from_LADDR(args[1]); ether_bsize = MaxByteCount; /* do this LAST; it enables reads */ result = get_packet(); /* check_ether(); for old behavior, move comment to above line */ } -#ifdef SYSVSIGNALS - sigrelse(SIGIO); -#else - sigsetmask(interrupt_mask); /* interrupts back on */ -#endif /* SYSVISGNALS */ + + /* enable interrupts */ + sigprocmask(SIG_UNBLOCK, &signals, NULL); + #endif /* NOETHER */ return (result); diff --git a/src/inet.c b/src/inet.c index 40b3c2c..e400b87 100644 --- a/src/inet.c +++ b/src/inet.c @@ -202,11 +202,12 @@ LispPTR subr_TCP_ops(int op, LispPTR nameConn, LispPTR proto, LispPTR length, Li return (NIL); } { /* Do this without taking IO interrupts */ -#ifdef SYSVSIGNALS - sighold(SIGIO); -#else - int oldmask = sigblock(sigmask(SIGIO)); -#endif /* SYSVSIGNALS */ + sigset_t signals; + + sigemptyset(&signals); + sigaddset(&signals, SIGIO); + + sigprocmask(SIG_BLOCK, &signals, NULL); fcntl(result, F_SETFL, fcntl(result, F_GETFL, 0) | O_ASYNC | O_NONBLOCK); fcntl(result, F_SETOWN, getpid()); @@ -214,19 +215,10 @@ LispPTR subr_TCP_ops(int op, LispPTR nameConn, LispPTR proto, LispPTR length, Li if (listen(result, 5) == -1) { perror("TCP Listen"); close(result); -#ifdef SYSVSIGNALS - sigrelse(SIGIO); -#else - sigsetmask(oldmask); -#endif /* SYSVSIGNALS */ - + sigprocmask(SIG_UNBLOCK, &signals, NULL); return (NIL); } -#ifdef SYSVSIGNALS - sigrelse(SIGIO); -#else - sigsetmask(oldmask); -#endif /* SYSVSIGNALS */ + sigprocmask(SIG_UNBLOCK, &signals, NULL); } FD_SET(result, &LispIOFds); /* so we get interrupts */ FD_SET(result, &LispReadFds); diff --git a/src/keyevent.c b/src/keyevent.c index 2e72609..4d46cdc 100644 --- a/src/keyevent.c +++ b/src/keyevent.c @@ -277,7 +277,7 @@ DLword ColorCursor_savebitmap[CURSORWIDTH / COLORPIXELS_IN_DLWORD * CURSORHEIGHT /* */ /************************************************************************/ -void getsignaldata(int sig, int code, void *scp) +void getsignaldata(int sig) { #ifndef DOS #ifndef XWINDOW diff --git a/src/timer.c b/src/timer.c index cf65497..91a60ff 100644 --- a/src/timer.c +++ b/src/timer.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -30,8 +31,6 @@ #ifdef DOS #include #include /* "#pragma interrupt" & '_chain_intr'*/ -#define SIGVTALRM SIGUSR1 -#define SIGIO SIGREAD /****************************************************************************** * Global variables ******************************************************************************/ @@ -64,6 +63,7 @@ extern int ether_fd; #include "timerdefs.h" #include "commondefs.h" #include "mkcelldefs.h" +#include "keyeventdefs.h" #ifdef XWINDOW #include "devif.h" @@ -93,12 +93,6 @@ int TIMEOUT_TIME; /* For file system timeout */ int Event_Req = FALSE; #endif /* XWINDOW */ -#define ERRCHK(expr, str) \ - if (expr == -1) perror(str) - -#define SIGERRCHK(set, str) \ - if (set == SIG_ERR) perror(str) - static int gettime(int casep); /************************************************************************/ @@ -431,11 +425,7 @@ extern int LispWindowFd; /* */ /************************************************************************/ -#ifndef SYSVSIGNALS -static struct sigvec timerv; -#endif /* SYSVSIGNALS */ - -static void int_timer_service(int sig, int code, void *scp) +static void int_timer_service(int sig) { /* this may have to do more in the future, like check for nested interrupts, etc... */ @@ -447,10 +437,6 @@ static void int_timer_service(int sig, int code, void *scp) #ifdef XWINDOW Event_Req = TRUE; #endif - -#ifdef SYSVSIGNALS -/* sigset(SIGVTALRM, int_timer_service); */ -#endif /* SYSVSIGNALS */ } /************************************************************************/ @@ -485,19 +471,19 @@ static void int_timer_init() /* if any*/ _dos_setvect(0x1c, DOStimer); /* hook our int handler to timer int */ -#elif SIGVTALRM - struct itimerval timert, tmpt; - -#ifdef SYSVSIGNALS - SIGERRCHK(sigset(SIGVTALRM, int_timer_service), "sigset vtalrm"); #else - /* first set up the signal handler */ - timerv.sv_handler = int_timer_service; - timerv.sv_mask = timerv.sv_flags = 0; - sigvec(SIGVTALRM, &timerv, 0); -#endif /* SYSVSIGNALS */ + struct itimerval timert, tmpt; + struct sigaction timer_action; -/* then attach a timer to it and turn it loose */ + timer_action.sa_handler = int_timer_service; + sigemptyset(&timer_action.sa_mask); + timer_action.sa_flags = 0; + + if (sigaction(SIGVTALRM, &timer_action, NULL) == -1) { + perror("sigaction: SIGVTALRM"); + } + + /* then attach a timer to it and turn it loose */ timert.it_interval.tv_sec = timert.it_value.tv_sec = 0; timert.it_interval.tv_usec = timert.it_value.tv_usec = TIMER_INTERVAL; @@ -507,7 +493,7 @@ static void int_timer_init() getitimer(ITIMER_VIRTUAL, &tmpt); DBPRINT(("Timer interval set to %d usec\n", timert.it_value.tv_usec)); -#endif /* DOS or SIGVTALRM */ +#endif /* DOS */ } /************************************************************************/ @@ -550,7 +536,7 @@ void int_io_close(int fd) /* */ /* i n t _ i o _ i n i t */ /* */ -/* Set up handling for the SIGIO and SIGPOLL signals, in */ +/* Set up handling for the SIGIO signals, in */ /* support of keyboard event handling and ethernet incoming- */ /* packet handling. */ /* */ @@ -558,25 +544,18 @@ void int_io_close(int fd) /************************************************************************/ static void int_io_init() { -#ifndef SYSVSIGNALS - static struct sigvec timerv; - static struct sigvec poll_timerv; -#endif /* SYSVSIGNALS */ - extern void getsignaldata(); - -/* first set up the signal handler */ - -#ifndef SYSVSIGNALS -#ifdef KBINT - timerv.sv_handler = getsignaldata; - timerv.sv_mask = timerv.sv_flags = 0; - sigvec(SIGIO, &timerv, 0); - - DBPRINT(("I/O interrupts enabled\n")); -#endif /* KBINT */ -#else /* SYSVSIGNALS in effect... */ #ifndef DOS - SIGERRCHK(sigset(SIGIO, getsignaldata), "sigset io"); + struct sigaction io_action; + io_action.sa_handler = getsignaldata; + sigemptyset(&io_action.sa_mask); + io_action.sa_flags = 0; + + if (sigaction(SIGIO, &io_action, NULL) == -1) { + perror("sigaction: SIGIO"); + } else { + DBPRINT(("I/O interrupts enabled\n")); + } + #if defined(XWINDOW) && defined(I_SETSIG) if (ioctl(ConnectionNumber(currentdsp->display_id), I_SETSIG, S_INPUT) < 0) perror("ioctl on X fd - SETSIG for input handling failed"); @@ -592,13 +571,9 @@ static void int_io_init() { return; } #endif /* USE_DLPI */ - #endif /* DOS */ -#endif /* SYSVSIGNALS */ } -int oldmask = 0; - /************************************************************************/ /* */ /* i n t _ b l o c k */ @@ -615,23 +590,16 @@ void int_block() { #ifdef DOS _dos_setvect(0x1c, prev_int_1c); #else /* DOS */ -#ifdef SYSVSIGNALS -#ifdef SIGVTALRM - sighold(SIGVTALRM); -#endif /* SIGVTALRM */ - sighold(SIGIO); - sighold(SIGALRM); -#ifdef SIGXFSZ - sighold(SIGXFSZ); -#endif /* SIGXFSZ */ -#else - oldmask = sigblock(sigmask(SIGVTALRM) | sigmask(SIGIO) | sigmask(SIGALRM) - | sigmask(SIGXFSZ) + sigset_t signals; + sigemptyset(&signals); + sigaddset(&signals, SIGVTALRM); + sigaddset(&signals, SIGIO); + sigaddset(&signals, SIGALRM); + sigaddset(&signals, SIGXFSZ); #ifdef FLTINT - | sigmask(SIGFPE) + sigaddset(&signals, SIGFPE); #endif - ); -#endif /* SYSVSIGNALS */ + sigprocmask(SIG_BLOCK, &signals, NULL); #endif /* DOS */ } @@ -650,18 +618,16 @@ void int_unblock() { #ifdef DOS _dos_setvect(0x1c, DOStimer); #else /* DOS */ -#ifdef SYSVSIGNALS -#ifdef SIGVTALRM - ERRCHK(sigrelse(SIGVTALRM), "sigrelse vtalrm"); -#endif /* SIGVTALRM */ - ERRCHK(sigrelse(SIGIO), "sigrelse io"); - ERRCHK(sigrelse(SIGALRM), "sigrelse alrm"); -#ifdef SIGXFSZ - ERRCHK(sigrelse(SIGXFSZ), "sigrelse XFSZ"); -#endif /* SIGXFSZ */ -#else - sigsetmask(oldmask); -#endif /* SYSVSIGNALS */ + sigset_t signals; + sigemptyset(&signals); + sigaddset(&signals, SIGVTALRM); + sigaddset(&signals, SIGIO); + sigaddset(&signals, SIGALRM); + sigaddset(&signals, SIGXFSZ); +#ifdef FLTINT + sigaddset(&signals, SIGFPE); +#endif + sigprocmask(SIG_UNBLOCK, &signals, NULL); #endif /* DOS */ } @@ -681,38 +647,42 @@ void int_timer_off() { int_block(); } /************************************************************************/ /* The global used to signal floating-point errors */ -int FP_error = 0; +volatile int FP_error = 0; -void int_fp_service(int sig, int code, struct sigcontext *scp) +void int_fp_service(int sig, siginfo_t *info, void *context) { - switch (code) { - case FPE_FLTDIV_TRAP: - case FPE_FLTUND_TRAP: - case FPE_FLTOVF_TRAP: - case FPE_FLTOPERR_TRAP: + switch (info->si_code) { + case FPE_FLTDIV: + case FPE_FLTUND: + case FPE_FLTOVF: + case FPE_FLTINV: - FP_error = code; + FP_error = info->si_code; break; default: { #ifdef DEBUG char stuff[100]; - sprintf(stuff, "Unexpected FP error signal code: %d", code); + snprintf(stuff, sizeof(stuff), "Unexpected FP error signal code: %d", info->si_code); perror(stuff); #else - FP_error = code; + FP_error = info->si_code; #endif } } -#ifdef SYSVSIGNALS - sigset(SIGFPE, int_fp_service); -#endif /* SYSVSIGNALS */ } -void int_fp_init() { /* first set up the signal handler */ - if (sigset(SIGFPE, int_fp_service)) +void int_fp_init() { + struct sigaction fpe_action; - perror("Sigset for FPE failed"); - DBPRINT(("FP interrupts enabled\n")); + fpe_action.sa_handler = int_fp_service; + sigemptyset(&fpe_action.sa_mask); + fpe_action.sa_flags = SA_SIGINFO; + + if (sigaction(SIGFPE, &fpe_action, NULL) == -1) { + perror("Sigset for FPE failed"); + } else { + DBPRINT(("FP interrupts enabled\n")); + } } #endif /* FLTINT */ @@ -729,18 +699,7 @@ void int_fp_init() { /* first set up the signal handler */ /************************************************************************/ jmp_buf jmpbuf; -static void timeout_error() { -/* - * Following printf changes the contents of jmpbuf! - * This would lead to horrible segmentation violation. - */ -/* printf("File access timed out.\n"); */ -#ifdef SYSVSIGNALS -#ifdef SIGALRM - sigset(SIGALRM, timeout_error); -#endif -#endif /* SYSVSIGNALS */ - +static void timeout_error(int sig) { longjmp(jmpbuf, 1); } @@ -756,23 +715,17 @@ static void timeout_error() { /************************************************************************/ static void int_file_init() { -#ifndef SYSVSIGNALS - static struct sigvec timerv; -#endif /* SYSVSIGNALS */ - char *envtime; int timeout_time; + struct sigaction timer_action; -/* first set up the signal handler */ -#ifndef SYSVSIGNALS - timerv.sv_handler = timeout_error; - timerv.sv_mask = timerv.sv_flags = 0; - sigvec(SIGALRM, &timerv, 0); -#else -#ifdef SIGALRM - sigset(SIGALRM, timeout_error); -#endif /* SIGALRM */ -#endif /* SYSVSIGNALS */ + timer_action.sa_handler = timeout_error; + sigemptyset(&timer_action.sa_mask); + timer_action.sa_flags = 0; + + if (sigaction(SIGALRM, &timer_action, NULL) == -1) { + perror("sigaction: SIGALRM"); + } /* Set Timeout period */ if ((envtime = getenv("LDEFILETIMEOUT")) == NULL) { @@ -796,70 +749,32 @@ static void int_file_init() { /* about what killed you. */ /* */ /************************************************************************/ - -/* 2017-06-22 NBriggs -- it's not clear that this definition has the correct - parameters for any known signal handler - - Superceded by sigaction on FreeBSD, Solaris 11, Linux - Unavailable on macOS - SVr4, POSIX.1-2001, POSIX.1-2008 (marked obsolete; use sigaction) - - void (*)(int) sigset(int, void (*disp)(int)); - - - OK on FreeBSD, Solaris 11, macOS, Linux - - struct sigaction { - void (*sa_handler)(int); - void (*sa_sigaction)(int, siginfo_t *, void *); - int sa_flags; see signal options below - sigset_t sa_mask; signal mask to apply - }; - - int - sigaction(int sig, const struct sigaction * restrict act, - struct sigaction * restrict oact); - */ - -void panicuraid(int sig, int code, void *scp, void *addr) +void panicuraid(int sig, siginfo_t *info, void *context) { static char errormsg[200]; static char *stdmsg = "Please record the signal and code information\n\ and do a 'v' before trying anything else."; - int i; - - for (i = 0; i < 200; i++) errormsg[i] = 0; switch (sig) { -#ifdef SIGBUS case SIGBUS: - sprintf(errormsg, "BUS error (code %d) at address %p.\n%s", code, addr, stdmsg); - break; -#endif /* SIGBUS */ - case SIGSEGV: - sprintf(errormsg, "SEGV error (code %d) at address %p.\n%s", code, addr, stdmsg); - break; case SIGILL: - sprintf(errormsg, "Illegal instruction (code %d) at address %p.\n%s", code, addr, stdmsg); + case SIGSEGV: + snprintf(errormsg, sizeof(errormsg), "%s at address %p.\n%s", strsignal(sig), info->si_addr, stdmsg); break; -#ifdef SIGPIPE case SIGPIPE: - sprintf(errormsg, "Broken PIPE (code %d) at address %p.\n%s", code, addr, stdmsg); + snprintf(errormsg, sizeof(errormsg), "Broken PIPE.\n%s", stdmsg); break; -#endif /* SGPIPE */ -#ifdef SIGHUP case SIGHUP: - sprintf(errormsg, "HANGUP signalled (code %d) at address %p.\n%s", code, addr, stdmsg); -/* Assume that a user tried to exit UNIX shell */ + snprintf(errormsg, sizeof(errormsg), "HANGUP signalled.\n%s", stdmsg); + /* Assume that a user tried to exit UNIX shell */ killpg(getpgrp(), SIGKILL); exit(0); break; -#endif /* SIGHUP */ case SIGFPE: - sprintf(errormsg, "FP error (code %d) at address %p.\n%s", code, addr, stdmsg); + snprintf(errormsg, sizeof(errormsg), "%s (%d) at address %p.\n%s", strsignal(sig), info->si_code, info->si_addr, stdmsg); break; - default: sprintf(errormsg, "Uncaught SIGNAL %d (code %d).\n%s", sig, code, stdmsg); + default: snprintf(errormsg, sizeof(errormsg), "Uncaught SIGNAL %s (%d).\n%s", strsignal(sig), sig, stdmsg); } error(errormsg); @@ -876,61 +791,31 @@ and do a 'v' before trying anything else."; /* */ /************************************************************************/ static void int_panic_init() { -#ifdef SYSVSIGNALS #ifndef DOS - sigset(SIGHUP, panicuraid); - sigset(SIGQUIT, panicuraid); - sigset(SIGILL, panicuraid); + struct sigaction panic_action, ignore_action; + + panic_action.sa_sigaction = panicuraid; + sigemptyset(&panic_action.sa_mask); + panic_action.sa_flags = SA_SIGINFO; + + ignore_action.sa_handler = SIG_IGN; + sigemptyset(&panic_action.sa_mask); + panic_action.sa_flags = 0; + + sigaction(SIGHUP, &panic_action, NULL); + sigaction(SIGQUIT, &panic_action, NULL); + sigaction(SIGILL, &panic_action, NULL); #ifdef SIGEMT - sigset(SIGEMT, panicuraid); + sigaction(SIGEMT, &panic_action, NULL); #endif - sigset(SIGBUS, panicuraid); - sigset(SIGSEGV, panicuraid); -#ifdef SIGSYS - sigset(SIGSYS, panicuraid); + sigaction(SIGBUS, &panic_action, NULL); + sigaction(SIGSEGV, &panic_action, NULL); + sigaction(SIGSYS, &panic_action, NULL); + sigaction(SIGTERM, &panic_action, NULL); + + /* Ignore SIGPIPE */ + sigaction(SIGPIPE, &ignore_action, NULL); #endif - sigset(SIGTERM, panicuraid); -#endif -#else - static struct sigvec panicv; - static struct sigvec ignorev; - - /* first set up the signal handlers: */ - - panicv.sv_handler = panicuraid; - panicv.sv_mask = panicv.sv_flags = 0; - ignorev.sv_handler = SIG_IGN; - ignorev.sv_mask = ignorev.sv_flags = 0; - - /* Now arrange for signals to be handled properly: */ - - sigvec(SIGHUP, &panicv, 0); - /* sigvec(SIGINT, &panicv, 0); */ - sigvec(SIGQUIT, &panicv, 0); - sigvec(SIGILL, &panicv, 0); -/* sigvec(SIGTRAP, &panicv, 0); */ -#ifdef OS4 - sigvec(SIGABRT, &panicv, 0); -#endif /* OS4 */ -#ifdef SIGEMT - sigvec(SIGEMT, &panicv, 0); -#endif - sigvec(SIGBUS, &panicv, 0); - sigvec(SIGSEGV, &panicv, 0); -#ifdef SIGSYS - sigvec(SIGSYS, &panicv, 0); -#endif - /* sigvec(SIGPIPE, &panicv, 0); Caused trouble with TCP; now ignored: */ - sigvec(SIGPIPE, &ignorev, 0); - sigvec(SIGTERM, &panicv, 0); -#ifdef OS4 - sigvec(SIGXCPU, &panicv, 0); - sigvec(SIGLOST, &panicv, 0); -#endif /* OS4 */ - - sigvec(SIGUSR1, &panicv, 0); - sigvec(SIGUSR2, &panicv, 0); -#endif /* SYSVSIGNALS */ DBPRINT(("Panic interrupts enabled\n")); } @@ -945,7 +830,7 @@ static void int_panic_init() { void int_init() { int_timer_init(); /* periodic interrupt timer */ - int_io_init(); /* SIGIO and SIGPOLL async I/O handlers */ + int_io_init(); /* SIGIO async I/O handlers */ int_file_init(); /* file-io TIMEOUT support */ int_panic_init(); /* catch for all other dangerous interrupts */ diff --git a/src/unixfork.c b/src/unixfork.c index 0060a1c..329c65d 100644 --- a/src/unixfork.c +++ b/src/unixfork.c @@ -203,6 +203,7 @@ int fork_Unix() { UnixToLisp[2], /* Outgoing pipe to LISP */ UnixPID, LispPipeIn, LispPipeOut, slot; pid_t pid; + sigset_t signals; char IOBuf[4]; unsigned short tmp; @@ -221,18 +222,14 @@ int fork_Unix() { StartTime = time(0); /* Save the time, to create filenames with */ StartTime &= 0xFFFFFF; /* as a positive number! */ -/* interrupts need to be blocked here so subprocess won't see them */ -#ifdef SYSVSIGNALS - sighold(SIGVTALRM); - sighold(SIGIO); - sighold(SIGALRM); - sighold(SIGXFSZ); - sighold(SIGFPE); -#else - sigblock(sigmask(SIGVTALRM) | sigmask(SIGIO) | sigmask(SIGALRM) - | sigmask(SIGXFSZ) - | sigmask(SIGFPE)); -#endif /* SYSVSIGNALS */ + /* interrupts need to be blocked here so subprocess won't see them */ + sigemptyset(&signals); + sigaddset(&signals, SIGVTALRM); + sigaddset(&signals, SIGIO); + sigaddset(&signals, SIGALRM); + sigaddset(&signals, SIGXFSZ); + sigaddset(&signals, SIGFPE); + sigprocmask(SIG_BLOCK, &signals, NULL); if ((UnixPID = fork()) == -1) { /* Fork off small version of the emulator */ perror("fork"); diff --git a/src/uraid.c b/src/uraid.c index 483bb7b..7a2c2a0 100644 --- a/src/uraid.c +++ b/src/uraid.c @@ -20,6 +20,7 @@ /************************************************************************/ #include +#include #include #include #include @@ -873,12 +874,18 @@ int device_before_raid() { int keytrans; union wait status; #endif /* SUNDISPLAY */ +#ifdef XWINDOW + sigset_t signals; +#endif int_timer_off(); -#if (defined(XWINDOW) && defined(SYSVSIGNALS) && defined(SIGIO)) - sigrelse(SIGIO); /* So X events still get recognized. */ -#endif /* XWINDOW + SYSVSIGNALS + SIGIO */ +#ifdef XWINDOW + /* So X events still get recognized. */ + sigemptyset(&signals); + sigaddset(&signals, SIGIO); + sigprocmask(SIG_UNBLOCK, &signals, NULL); +#endif #ifdef SUNDISPLAY win_setcursor(LispWindowFd, &InvisibleCursor); diff --git a/src/xc.c b/src/xc.c index caa7438..12f7efc 100644 --- a/src/xc.c +++ b/src/xc.c @@ -1328,15 +1328,12 @@ check_interrupt: if ((Irq_Stk_End <= 0) || (Irq_Stk_Check <= 0) || need_irq) { if (StkOffset_from_68K(CSTKPTR) > InterfacePage->stackbase) { -/* Interrupts not Disabled */ -/* XXX: what on earth is this code trying to accomplish by calling - getsignaldata -- it used to have no arguments, but that's an error -*/ -#ifndef KBINT - getsignaldata(0, 0, NULL); -#endif -#ifdef OS4 - getsignaldata(0, 0, NULL); + /* Interrupts not Disabled */ + /* XXX: what on earth is this code trying to accomplish by calling + getsignaldata + */ +#if !defined(KBINT) || defined(OS4) + getsignaldata(0); #endif EXT; update_timer();