Sig-handler support
This commit is contained in:
parent
0716fc06cd
commit
b48e4874c5
|
@ -5,3 +5,31 @@
|
|||
#define Malloc(type,n) ((type *) malloc(sizeof(type)*(n)))
|
||||
#define Free(p) (free((char *)(p)))
|
||||
#define Realloc(type,p,n) ((type *) realloc(p, (n)*sizeof(type)))
|
||||
|
||||
|
||||
/* These are the interrupt numbers used by the S48/scsh VM.
|
||||
** The first three are S48 interrupts. The rest were added for
|
||||
** scsh to support Unix signals. Note that not all Unixes support
|
||||
** all these signals.
|
||||
*/
|
||||
#define scshint_alarm (0) /* S48 Unix SIGALRM signal */
|
||||
#define scshint_keyboard (1) /* S48 Unix SIGINT signal */
|
||||
#define scshint_memory_shortage (2)
|
||||
#define scshint_chld (3) /* Interrupts from here down are */
|
||||
#define scshint_cont (4) /* Unix signals. The last ten are */
|
||||
#define scshint_hup (5) /* non-Posix, hence not necessarily */
|
||||
#define scshint_quit (6) /* found on all Unixes. */
|
||||
#define scshint_term (7)
|
||||
#define scshint_tstp (8)
|
||||
#define scshint_usr1 (9)
|
||||
#define scshint_usr2 (10)
|
||||
#define scshint_info (11) /* BSD */
|
||||
#define scshint_io (12) /* BSD + SVR4 */
|
||||
#define scshint_poll (13) /* SVR4 */
|
||||
#define scshint_prof (14) /* BSD + SVR4 */
|
||||
#define scshint_pwr (15) /* SVR4 */
|
||||
#define scshint_urg (16) /* BSD + SVR4 */
|
||||
#define scshint_vtalrm (17) /* BSD + SVR4 */
|
||||
#define scshint_winch (18) /* BSD + SVR4 */
|
||||
#define scshint_xcpu (19) /* BSD + SVR4 */
|
||||
#define scshint_xfsz (20) /* BSD + SVR4 */
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
;;; *through* an intermediate interface, the S48 vm's idea of interrupts.
|
||||
;;; So there is a difference between delivering a signal to the underlying
|
||||
;;; Unix process and delivering it to the program that runs on the VM.
|
||||
;;;
|
||||
;;; One effect is that we have two separate codes for the same thing -- the
|
||||
;;; Unix signal code, and the S48 interrupt value. E.g., SIGNAL/TSTP and
|
||||
;;; INTERRUPT/TSTP.
|
||||
|
||||
;;; These system calls can return EINTR or restart. In order for the S48 vm's
|
||||
;;; interrupt system to detect a signal and invoke the handler, they *must*
|
||||
|
@ -20,6 +24,11 @@
|
|||
;;; HP-UX, but I don't use: poll lockf msem_lock msgsnd msgrcv semop
|
||||
;;;
|
||||
;;; * Only during a F_SETLKW
|
||||
;;;
|
||||
;;; From rts/interrupt.scm (package interrupts, interface interrupts-interface)
|
||||
;;; WITH-INTERRUPTS INTERRUPT-HANDLERS SET-ENABLED-INTERRUPTS!
|
||||
;;; ENABLED-INTERRUPTS
|
||||
;;; Must define WITH-INTERRUPTS* and WITH-INTERRUPTS.
|
||||
|
||||
(foreign-source
|
||||
"extern int errno;"
|
||||
|
@ -28,10 +37,16 @@
|
|||
"#include \"sighandlers1.h\""
|
||||
"" "")
|
||||
|
||||
;;; Blocking interrupts
|
||||
;;; I think all of this code (and associated C code) has been obsoleted by
|
||||
;;; the new system that uses S48's sigblocking machinery.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Map a Unix async signal to its S48 interrupt value.
|
||||
;;; -1 => Not defined.
|
||||
(define-foreign %signal->interrupt (sig2interrupt (integer sig))
|
||||
integer)
|
||||
|
||||
(define (signal->interrupt sig)
|
||||
(let ((int (%signal->interrupt sig)))
|
||||
(if (>= int 0) int
|
||||
(error "Unix signal has no Scheme 48 interrupt." sig))))
|
||||
|
||||
|
||||
(define (interrupt-set . interrupts)
|
||||
(let lp ((ints interrupts) (ans 0))
|
||||
|
@ -39,33 +54,10 @@
|
|||
(lp (cdr ints) (bitwise-ior ans (arithmetic-shift 1 (- (car ints) 1))))
|
||||
ans)))
|
||||
|
||||
(define-simple-syntax (with-blocked-interrupts mask body ...)
|
||||
(with-blocked-interrupts* mask (lambda () body ...)))
|
||||
(define-simple-syntax (with-enabled-interrupts mask body ...)
|
||||
(with-interrupts mask (lambda () body ...)))
|
||||
|
||||
(define (with-blocked-interrupts* mask thunk)
|
||||
(let ((old-mask #f))
|
||||
(dynamic-wind
|
||||
(lambda () (set! old-mask (set-blocked-interrupts! mask)))
|
||||
thunk
|
||||
(lambda () (set-blocked-interrupts! old-mask)))))
|
||||
|
||||
(define (set-blocked-interrupts! mask)
|
||||
(receive (hi-out lo-out)
|
||||
(%set-blocked-interrupts! (hi8 mask) (lo24 mask))
|
||||
(compose-8/24 hi-out lo-out)))
|
||||
|
||||
|
||||
(define (blocked-interrupts)
|
||||
(call-with-values %blocked-interrupts compose-8/24))
|
||||
|
||||
(define-foreign %set-blocked-interrupts! (set_procmask (fixnum hi)
|
||||
(fixnum lo))
|
||||
fixnum ; hi
|
||||
fixnum) ; lo
|
||||
|
||||
(define-foreign %blocked-interrupts (get_procmask)
|
||||
fixnum ; hi
|
||||
fixnum) ; lo
|
||||
(define with-enabled-interrupts* with-interrupts)
|
||||
|
||||
|
||||
;;; Get/Set signal handlers
|
||||
|
@ -81,62 +73,90 @@
|
|||
;;; to our waiting parent proc correctly reflects how we died, and also
|
||||
;;; makes the core dump happen if it should. Details, details.
|
||||
|
||||
(define (default-handler sig)
|
||||
(lambda (enabled-interrupts) (%do-default-sigaction sig)))
|
||||
|
||||
(define-foreign %do-default-sigaction (do_default_sigaction (fixnum signal))
|
||||
ignore)
|
||||
|
||||
;;; This gives the default handler for each signal.
|
||||
(define default-handler-vec
|
||||
(initialize-vector 32 (lambda (sig)
|
||||
;; This is the guy to call when you want signal
|
||||
;; SIG handled in the default manner.
|
||||
(if (memv sig signals-ignored-by-default)
|
||||
(lambda (enabled-interrupts) #f)
|
||||
(lambda (enabled-interrupts)
|
||||
(%do-default-sigaction sig))))))
|
||||
|
||||
;;; HANDLER is #f (ignore), #t (default), or an integer procedure.
|
||||
;;; The interrupt is delivered to a procedure by (1) setting the
|
||||
;;; ENABLED-INTERRUPTS register to 0 (i.e., blocking all interrupts),
|
||||
;;; and (2) applying the procedure to the previous value of the
|
||||
;;; ENABLED-INTERRUPTS register. If the procedure returns normally
|
||||
;;; (i.e., it doesn't throw to a continuation), the ENABLED-INTERRUPTS
|
||||
;;; register will be restored to its previous value.
|
||||
|
||||
;;; Should have extra args, MASK & FLAGS.
|
||||
(define (set-signal-handler sig handler)
|
||||
(let ((handler (if (eq? handler #t) ; Hack the default handler.
|
||||
(default-handler sig)
|
||||
handler)))
|
||||
(receive (handler flags) ; Should be (handler mask flags).
|
||||
(%set-signal-handler! sig handler 0)
|
||||
handler)))
|
||||
;;; HANDLER is #f (ignore), #t (default), or a procedure taking an integer
|
||||
;;; argument. The interrupt is delivered to a procedure by (1) setting the
|
||||
;;; ENABLED-INTERRUPTS register to 0 (i.e., blocking all interrupts), and (2)
|
||||
;;; applying the procedure to the previous value of the ENABLED-INTERRUPTS
|
||||
;;; register. If the procedure returns normally (i.e., it doesn't throw to a
|
||||
;;; continuation), the ENABLED-INTERRUPTS register will be restored to its
|
||||
;;; previous value.
|
||||
|
||||
(define (set-signal-handler! sig handler)
|
||||
(let ((nhandler (if (eq? handler #t) ; Get SIG's default handler.
|
||||
(vector-ref default-handler-vec sig)
|
||||
handler))
|
||||
(int (signal->interrupt sig)))
|
||||
(with-enabled-interrupts 0
|
||||
(let ((ohandler (vector-ref interrupt-handlers int)))
|
||||
(vector-set! interrupt-handlers int nhandler)
|
||||
ohandler))))
|
||||
|
||||
(define (signal-handler sig)
|
||||
(receive (handler flags) (%signal-handler sig)
|
||||
handler))
|
||||
(vector-ref interrupt-handlers (signal->interrupt sig)))
|
||||
|
||||
(define (%signal-handler sig)
|
||||
(receive (err handler flags) (%%signal-handler sig)
|
||||
(if err (errno-error err %signal-handler sig)
|
||||
(values handler flags))))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Set the Unix signal handler. One doesn't usually use this; one usually
|
||||
;;; uses the S48 VM's interrupt system.
|
||||
;;; HANDLER-CODE: 0 => ignore, 1 => default, 2 => S48 VM
|
||||
;;; Returns equivalent code, additionally 3 => other handler.
|
||||
;;; Raises an error exception if there's a problem.
|
||||
|
||||
;;; (%set-signal-handler! sig handler [mask flags]) -> [handler mask flags]
|
||||
;;; Except no MASK for now.
|
||||
(define (%set-unix-signal-handler! sig handler-code)
|
||||
(check-arg (lambda (x) (and (integer? sig) (< 0 sig 32)))
|
||||
sig
|
||||
%set-unix-signal-handler!)
|
||||
(check-arg (lambda (x) (and (integer? handler-code) (<= 0 handler-code 2)))
|
||||
handler-code
|
||||
%set-unix-signal-handler!)
|
||||
(let retry ()
|
||||
(receive (err old-hc) (%%set-unix-signal-handler! sig handler-code)
|
||||
(cond ((not err) old-hc)
|
||||
((= err errno/intr) (retry))
|
||||
(else (errno-error err %set-unix-signal-handler! sig handler-code))))))
|
||||
|
||||
(define (%set-signal-handler! sig handler . args)
|
||||
(let-optionals args ((flags 0))
|
||||
(receive (err handler flags)
|
||||
(%%set-signal-handler! sig handler flags)
|
||||
(if err
|
||||
(errno-error err %set-signal-handler! sig handler flags)
|
||||
(values handler flags)))))
|
||||
|
||||
(define-foreign %%set-signal-handler! (set_sig_handler (fixnum signal)
|
||||
(desc handler)
|
||||
(fixnum flags))
|
||||
(define-foreign %%set-unix-signal-handler!
|
||||
(scsh_set_sig (fixnum sig) (fixnum hc) (fixnum flags))
|
||||
desc ; #f or errno
|
||||
desc ; handler
|
||||
fixnum) ; flags
|
||||
integer ; previous handler-code
|
||||
integer) ; previous handler flags
|
||||
|
||||
(define-foreign %%signal-handler (get_sig_handler (fixnum signal))
|
||||
(define (%unix-signal-handler sig)
|
||||
(check-arg (lambda (x) (and (integer? sig) (< 0 sig 32)))
|
||||
sig
|
||||
%unix-signal-handler)
|
||||
(let retry ()
|
||||
(receive (err hc flags) (%%unix-signal-handler sig)
|
||||
(cond ((not err) hc)
|
||||
((= err errno/intr) (retry))
|
||||
(else (errno-error err %unix-signal-handler sig))))))
|
||||
|
||||
(define-foreign %%unix-signal-handler (scsh_get_sig (fixnum sig))
|
||||
desc ; #f or errno
|
||||
desc ; handler
|
||||
fixnum) ; flags
|
||||
integer ; previous handler-code
|
||||
integer) ; previous handler flags
|
||||
|
||||
(define-foreign %%install-new-handler-vec
|
||||
(install_new_handler_vector (vector-desc vec))
|
||||
ignore)
|
||||
(define-foreign %install-unix-scsh-handlers (install_scsh_handlers) ignore)
|
||||
|
||||
(define-foreign %%get-int-handlers (get_int_handlers) desc)
|
||||
|
||||
(define (%install-scsh-handlers)
|
||||
(do ((sig 32 (- sig 1)))
|
||||
((< sig 0))
|
||||
(let ((i (%signal->interrupt sig)))
|
||||
(if (not (or (= i -1) (= sig signal/int) (= sig signal/alrm)))
|
||||
(vector-set! interrupt-handlers i
|
||||
(vector-ref default-handler-vec sig))))))
|
||||
|
|
|
@ -6,66 +6,25 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include "cstuff.h"
|
||||
|
||||
/* Make sure our exports match up w/the implementation: */
|
||||
#include "sighandlers1.h"
|
||||
|
||||
#include "machine/signals1.h"
|
||||
|
||||
extern int errno;
|
||||
|
||||
extern scheme_value Spending_interruptsS, Sinterrupt_handlersS;
|
||||
|
||||
/* Translate Unix signal numbers to S48 interrupt numbers.
|
||||
** alarm, keyboard (^C, SIGINT), and memory shortage are 0, 1, and 2.
|
||||
*/
|
||||
/* Translate Unix signal numbers to S48 interrupt numbers. */
|
||||
|
||||
static int sig2interrupt(int signal)
|
||||
int sig2interrupt(int signal)
|
||||
{
|
||||
switch (signal) {
|
||||
case SIGALRM: return 0; /* Already defined by S48. */
|
||||
case SIGCHLD: return 3;
|
||||
case SIGCONT: return 4;
|
||||
case SIGHUP: return 5;
|
||||
case SIGINT: return 1; /* Already defined by S48. */
|
||||
case SIGQUIT: return 6;
|
||||
case SIGTERM: return 7;
|
||||
case SIGTSTP: return 8;
|
||||
case SIGUSR1: return 9;
|
||||
case SIGUSR2: return 10;
|
||||
|
||||
#ifdef SIGINFO
|
||||
case SIGINFO: return 11;
|
||||
#endif
|
||||
#ifdef SIGIO
|
||||
case SIGIO: return 12;
|
||||
#endif
|
||||
#ifdef SIGPOLL
|
||||
case SIGPOLL: return 13;
|
||||
#endif
|
||||
#ifdef SIGPROF
|
||||
case SIGPROF: return 14;
|
||||
#endif
|
||||
#ifdef SIGPWR
|
||||
case SIGPWR: return 15;
|
||||
#endif
|
||||
#ifdef SIGURG
|
||||
case SIGURG: return 16;
|
||||
#endif
|
||||
#ifdef SIGVTALRM
|
||||
case SIGVTALRM: return 17;
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
case SIGWINCH: return 18;
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
case SIGXCPU: return 19;
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
case SIGXFSZ: return 20;
|
||||
#endif
|
||||
default: return -1;
|
||||
return ( signal < 0 || signal > max_sig ) ? -1 : sig2int[signal];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Hack the blocked-signal mask.
|
||||
*******************************************************************************
|
||||
|
@ -104,138 +63,63 @@ int get_procmask(int *old_lo_p)
|
|||
|
||||
static void scm_handle_sig(int sig)
|
||||
{
|
||||
Spending_interruptsS |= (1<<sig2interrupt(sig));
|
||||
fprintf(stderr, "scm_handle_sig(%d)\n", sig);
|
||||
Spending_interruptsS |= (1<<sig2int[sig]);
|
||||
}
|
||||
|
||||
|
||||
scheme_value set_sig_handler(int sig, scheme_value handler, int flags,
|
||||
scheme_value *ohandler, int *oflags)
|
||||
/* handler_code: 0 => ignore, 1 => default, 2 => S48 VM */
|
||||
|
||||
/* Common code for two functions above. */
|
||||
static scheme_value scsh_ret_sig(int retval, struct sigaction *oldsa,
|
||||
int *old_hc, int *oflags)
|
||||
{
|
||||
if( retval ) {
|
||||
*old_hc = -1;
|
||||
*oflags = -1;
|
||||
return ENTER_FIXNUM(errno);
|
||||
}
|
||||
if( oldsa->sa_handler == SIG_IGN ) *old_hc = 0;
|
||||
else if( oldsa->sa_handler == SIG_DFL ) *old_hc = 1;
|
||||
else if( oldsa->sa_handler == scm_handle_sig ) *old_hc = 2;
|
||||
else *old_hc = ENTER_FIXNUM(3); /* Unknown signal handler. */
|
||||
|
||||
*oflags = oldsa->sa_flags;
|
||||
return SCHFALSE;
|
||||
}
|
||||
|
||||
|
||||
scheme_value scsh_set_sig(int sig, int handler_code, int flags,
|
||||
int *old_hc, int *oflags)
|
||||
{
|
||||
struct sigaction new, old;
|
||||
int intnum = sig2interrupt(sig);
|
||||
scheme_value old_scsh_handler;
|
||||
|
||||
/* intnum in range? */
|
||||
if( intnum >= VECTOR_LENGTH(Sinterrupt_handlersS) ) {
|
||||
*ohandler = SCHFALSE;
|
||||
return ENTER_FIXNUM(-1);
|
||||
}
|
||||
|
||||
/* We may need this for ohandler later, but it may get clobbered
|
||||
** when we set the new handler, so stash it away for now.
|
||||
*/
|
||||
old_scsh_handler = VECTOR_REF(Sinterrupt_handlersS, intnum);
|
||||
|
||||
sigemptyset(&new.sa_mask); /* WTF */
|
||||
new.sa_flags = flags;
|
||||
|
||||
if( handler == SCHFALSE ) {
|
||||
new.sa_handler = SIG_IGN;
|
||||
VECTOR_REF(Sinterrupt_handlersS, intnum) = SCHFALSE;
|
||||
}
|
||||
switch( handler_code ) {
|
||||
case 0: new.sa_handler = SIG_IGN; break;
|
||||
case 1: new.sa_handler = SIG_DFL; break;
|
||||
case 2: new.sa_handler = scm_handle_sig; break;
|
||||
default:
|
||||
fprintf(stderr, "Impossible handler_code in set_sig_handler: %d\n",
|
||||
handler_code);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* This *really* sets the Unix signal handler to SIG_DFL.
|
||||
** What usually happens isn't this -- what usually happens is that
|
||||
** we establish a special Scheme handler that does the default, so
|
||||
** that it is subject to S48's blocking machinery.
|
||||
*/
|
||||
else if( handler == SCHTRUE ) {
|
||||
new.sa_handler = SIG_DFL;
|
||||
VECTOR_REF(Sinterrupt_handlersS, intnum) = SCHFALSE;
|
||||
}
|
||||
|
||||
else {
|
||||
new.sa_handler = scm_handle_sig;
|
||||
|
||||
VECTOR_REF(Sinterrupt_handlersS, intnum) = handler;
|
||||
/* Do other stuff. */
|
||||
}
|
||||
|
||||
if( sigaction(sig, &new, &old) ) {
|
||||
*ohandler = SCHFALSE;
|
||||
return ENTER_FIXNUM(errno);
|
||||
}
|
||||
|
||||
*oflags = old.sa_flags;
|
||||
if( old.sa_handler == SIG_IGN ) *ohandler = SCHFALSE;
|
||||
else if( old.sa_handler == SIG_DFL ) *ohandler = SCHTRUE;
|
||||
else if( old.sa_handler == scm_handle_sig ) *ohandler = old_scsh_handler;
|
||||
else *ohandler = ENTER_FIXNUM(-1); /* Unknown signal handler. */
|
||||
return SCHFALSE;
|
||||
return scsh_ret_sig(sigaction(sig, &new, &old),
|
||||
&old, old_hc, oflags);
|
||||
}
|
||||
|
||||
|
||||
scheme_value get_sig_handler(int signal, scheme_value *handler, int *flags)
|
||||
scheme_value scsh_get_sig(int signal, int *old_hc, int *oflags)
|
||||
{
|
||||
struct sigaction old;
|
||||
|
||||
if( sigaction(signal, NULL, &old) ) {
|
||||
*handler = SCHFALSE;
|
||||
return ENTER_FIXNUM(errno);
|
||||
}
|
||||
|
||||
*flags = old.sa_flags;
|
||||
|
||||
if( old.sa_handler == SIG_IGN ) *handler = SCHFALSE;
|
||||
|
||||
else if( old.sa_handler == SIG_DFL ) *handler = SCHTRUE;
|
||||
|
||||
else if( old.sa_handler == scm_handle_sig ) {
|
||||
int intnum = sig2interrupt(signal);
|
||||
|
||||
/* intnum in range? */
|
||||
if( intnum >= VECTOR_LENGTH(Sinterrupt_handlersS) ) {
|
||||
*handler = SCHFALSE;
|
||||
return ENTER_FIXNUM(-1);
|
||||
}
|
||||
|
||||
*handler = VECTOR_REF(Sinterrupt_handlersS, intnum);
|
||||
}
|
||||
|
||||
else *handler = ENTER_FIXNUM(-1); /* Unknown signal handler. */
|
||||
|
||||
return SCHFALSE;
|
||||
return scsh_ret_sig(sigaction(signal, NULL, &old),
|
||||
&old, old_hc, oflags);
|
||||
}
|
||||
|
||||
|
||||
/* Return true if SIGNAL's default action is definitely to be ignored. */
|
||||
/* This should be inlined by a good compiler. */
|
||||
|
||||
static int sig_def_is_ignored(int signal)
|
||||
{
|
||||
return
|
||||
/* Posix signals */
|
||||
signal == SIGALRM || signal == SIGHUP ||
|
||||
signal == SIGINT || signal == SIGQUIT ||
|
||||
signal == SIGTERM || signal == SIGUSR1 ||
|
||||
signal == SIGUSR2
|
||||
|
||||
/* Non-Posix signals, when present. */
|
||||
#ifdef SIGINFO
|
||||
|| signal == SIGINFO
|
||||
#endif
|
||||
#ifdef SIGPOLL
|
||||
|| signal == SIGPOLL
|
||||
#endif
|
||||
#ifdef SIGPROF
|
||||
|| signal == SIGPROF
|
||||
#endif
|
||||
#ifdef SIGVTALRM
|
||||
|| signal == SIGVTALRM
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
|| signal == SIGXCPU
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
|| signal == SIGXFSZ
|
||||
#endif
|
||||
#ifdef SIGIO
|
||||
|| signal == SIGIO /* BSD => ignore; SVR4 => terminate */
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/* This guy is responsible for making the default action for a
|
||||
** Unix signal happen. Because S48's signal handler system is
|
||||
** interposed between delivery-to-the-process and
|
||||
|
@ -254,39 +138,56 @@ void do_default_sigaction(int signal)
|
|||
sigset_t ss, old_ss;
|
||||
struct sigaction default_action, old_action;
|
||||
|
||||
if( !sig_def_is_ignored(signal) ) {
|
||||
fprintf(stderr, "Doing default for signal %d\n", signal);
|
||||
|
||||
/* OK -- signal's default *isn't* "ignore," so we have to do it. */
|
||||
sigfillset(&ss); /* Block everyone. */
|
||||
sigprocmask(SIG_SETMASK, &ss, &old_ss);
|
||||
sigfillset(&ss); /* Block everyone. */
|
||||
sigprocmask(SIG_SETMASK, &ss, &old_ss);
|
||||
|
||||
default_action.sa_handler = SIG_DFL; /* Set for default. */
|
||||
sigemptyset(&default_action.sa_mask);
|
||||
default_action.sa_flags = 0;
|
||||
sigaction(signal, &default_action, &old_action);
|
||||
default_action.sa_handler = SIG_DFL; /* Set for default. */
|
||||
sigemptyset(&default_action.sa_mask);
|
||||
default_action.sa_flags = 0;
|
||||
sigaction(signal, &default_action, &old_action);
|
||||
|
||||
raise(signal); /* Raise the signal. */
|
||||
sigdelset(&ss, signal);
|
||||
sigprocmask(SIG_SETMASK, &ss, 0); /* Handle it. */
|
||||
raise(signal); /* Raise the signal. */
|
||||
sigdelset(&ss, signal);
|
||||
sigprocmask(SIG_SETMASK, &ss, 0); /* Handle it. */
|
||||
|
||||
/* Most likely, we'll never get to here, as the default for
|
||||
** the signals we're handling is "terminate," but we'll play it safe.
|
||||
*/
|
||||
sigaction(signal, &old_action, 0); /* Restore old handler, */
|
||||
sigprocmask(SIG_SETMASK, &old_ss, 0); /* and mask. */
|
||||
}
|
||||
/* Most likely, we'll never get to here, as the default for
|
||||
** the signals we're handling is "terminate," but we'll play it safe.
|
||||
*/
|
||||
sigaction(signal, &old_action, 0); /* Restore old handler, */
|
||||
sigprocmask(SIG_SETMASK, &old_ss, 0); /* and mask. */
|
||||
}
|
||||
|
||||
|
||||
/* Install a new signal-handler vector.
|
||||
** I use this because the default one is only 3 entries long, and I
|
||||
** don't want to modify the S48 source. So I'll just install my own
|
||||
** at run-time.
|
||||
** It's not a hack, it's a kluge.
|
||||
*/
|
||||
/* Set up the Unix signal system the way we want it for scsh. */
|
||||
|
||||
void install_new_handler_vector(scheme_value handlers)
|
||||
void install_scsh_handlers(void)
|
||||
{
|
||||
extern scheme_value Sinterrupt_handlersS;
|
||||
Sinterrupt_handlersS = handlers;
|
||||
struct sigaction new;
|
||||
int i;
|
||||
|
||||
sigemptyset(&new.sa_mask); /* WTF */
|
||||
new.sa_handler = scm_handle_sig;
|
||||
|
||||
for(i=max_sig; i>=0; i--)
|
||||
if( sig2int[i] ) {
|
||||
/* This is a signal we want the S48 interrupt system to handle. */
|
||||
sigaction(i, &new, 0);
|
||||
}
|
||||
|
||||
/* Turn off SIGPIPE and SIGSYS -- they are handled by synchronous exceptions
|
||||
** triggered by errno returns.
|
||||
*/
|
||||
new.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &new, 0);
|
||||
#ifdef SIGSYS
|
||||
sigaction(SIGSYS, &new, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Sneak me the S48 interrupt handlers vector. */
|
||||
scheme_value get_int_handlers(void)
|
||||
{
|
||||
return Sinterrupt_handlersS;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
/* Exports from sighandlers1.c */
|
||||
|
||||
int sig2interrupt(int signal);
|
||||
|
||||
int set_procmask(int hi, int lo, int *old_lo_p);
|
||||
int get_procmask(int *old_lo_p);
|
||||
|
||||
scheme_value set_int_handler(int sig, scheme_value handler, int flags,
|
||||
scheme_value *ohandler, int *oflags);
|
||||
scheme_value get_int_handler(int signal, scheme_value *handler, int *flags);
|
||||
scheme_value scsh_set_sig(int sig, int handler_code, int flags,
|
||||
int *ohc, int *oflags);
|
||||
scheme_value scsh_get_sig(int signal, int *handler_code, int *flags);
|
||||
|
||||
void do_default_sigaction(int signal);
|
||||
|
||||
void install_new_handler_vector(scheme_value handlers);
|
||||
void install_scsh_handlers(void);
|
||||
|
||||
scheme_value get_int_handlers(void);
|
||||
|
|
Loading…
Reference in New Issue