diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2003-06-07 03:35:20 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2003-06-07 03:35:20 +0000 |
commit | 912020678b6f45f900b66e637e5848d9fa3b92b7 (patch) | |
tree | fed315ea71f42adc5b7f91b77e54ce06be52220c /usr.bin/less/signal.c | |
parent | ca740922f63b8d6806ffacd67092fc0f20e90976 (diff) |
Use interruptible syscalls instead of setjmp/longjmp. This makes
less's signal handlers safe. No one has reported problems so far...
Diffstat (limited to 'usr.bin/less/signal.c')
-rw-r--r-- | usr.bin/less/signal.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/usr.bin/less/signal.c b/usr.bin/less/signal.c index a641d99ee9d..01b510f73e8 100644 --- a/usr.bin/less/signal.c +++ b/usr.bin/less/signal.c @@ -15,8 +15,6 @@ * A signal usually merely causes a bit to be set in the "signals" word. * At some convenient time, the mainline code checks to see if any * signals need processing by calling psignal(). - * If we happen to be reading from a file [in iread()] at the time - * the signal is received, we call intread to interrupt the iread. */ #include "less.h" @@ -32,7 +30,6 @@ extern int screen_trashed; extern int lnloop; extern int linenums; extern int wscroll; -extern int reading; /* * Interrupt signal handler. @@ -45,7 +42,6 @@ u_interrupt(type) #if OS2 LSIGNAL(SIGINT, SIG_ACK); #endif - LSIGNAL(SIGINT, u_interrupt); sigs |= S_INTERRUPT; #if MSDOS_COMPILER==DJGPPC /* @@ -56,8 +52,6 @@ u_interrupt(type) if (kbhit()) getkey(); #endif - if (reading) - intread(); } #ifdef SIGTSTP @@ -69,10 +63,7 @@ u_interrupt(type) stop(type) int type; { - LSIGNAL(SIGTSTP, stop); sigs |= S_STOP; - if (reading) - intread(); } #endif @@ -85,10 +76,7 @@ stop(type) winch(type) int type; { - LSIGNAL(SIGWINCH, winch); sigs |= S_WINCH; - if (reading) - intread(); } #else #ifdef SIGWIND @@ -100,10 +88,7 @@ winch(type) winch(type) int type; { - LSIGNAL(SIGWIND, winch); sigs |= S_WINCH; - if (reading) - intread(); } #endif #endif @@ -268,3 +253,21 @@ psignals() } } + +/* + * Custom version of signal() that causes syscalls to be interrupted. + */ + public void +(*lsignal(s, a))() + int s; + void (*a) (); +{ + struct sigaction sa, osa; + + sa.sa_handler = a; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; /* don't restart system calls */ + if (sigaction(s, &sa, &osa) != 0) + return (SIG_ERR); + return (osa.sa_handler); +} |