Copyright (C) 1994, Digital Equipment Corp.
UNSAFE MODULE; IMPORT RTMisc, RTProcess, Csignal, Usignal, Uprocess; FROM Ctypes IMPORT int; VAR DefaultHandler : Csignal.Handler; IgnoreSignal : Csignal.Handler; initial_handlers : ARRAY [0..5] OF Csignal.Handler; PROCEDURE RTSignal InstallHandlers () = BEGIN DefaultHandler := LOOPHOLE (0, Csignal.Handler); IgnoreSignal := LOOPHOLE (1, Csignal.Handler); SetHandler (0, Usignal.SIGHUP, Shutdown); SetHandler (1, Usignal.SIGINT, Interrupt); SetHandler (2, Usignal.SIGQUIT, Quit); SetHandler (3, Usignal.SIGSEGV, SegV); SetHandler (4, Usignal.SIGPIPE, IgnoreSignal); SetHandler (5, Usignal.SIGTERM, Shutdown); END InstallHandlers; PROCEDURESetHandler (id: INTEGER; sig: int; handler: Csignal.Handler) = VAR old := Csignal.signal (sig, handler); BEGIN initial_handlers[id] := old; IF (old # DefaultHandler) THEN (* don't override inherited, non-default handlers *) EVAL Csignal.signal (sig, old); END; END SetHandler; PROCEDURERestoreHandlers () = BEGIN RestoreHandler (0, Usignal.SIGHUP); RestoreHandler (1, Usignal.SIGINT); RestoreHandler (2, Usignal.SIGQUIT); RestoreHandler (3, Usignal.SIGSEGV); RestoreHandler (4, Usignal.SIGPIPE); RestoreHandler (5, Usignal.SIGTERM); END RestoreHandlers; PROCEDURERestoreHandler (id: INTEGER; sig: int) = BEGIN EVAL Csignal.signal (sig, initial_handlers[id]); END RestoreHandler; PROCEDUREShutdown (sig: int) = BEGIN RTProcess.InvokeExitors (); (* flush stdio... *) EVAL Csignal.signal (sig, DefaultHandler); (* restore default handler *) EVAL Usignal.kill (Uprocess.getpid (), sig); (* and resend the signal *) END Shutdown; PROCEDUREInterrupt (sig: int) = VAR h := RTProcess.OnInterrupt (NIL); BEGIN IF (h = NIL) THEN Shutdown (sig); ELSE EVAL RTProcess.OnInterrupt (h); (* reinstall the handler *) h (); END; END Interrupt; PROCEDUREQuit (<*UNUSED*> sig: int) = BEGIN RTMisc.FatalErrorI ("aborted", 0); END Quit; PROCEDURESegV (<*UNUSED*> sig: int) = BEGIN RTMisc.FatalErrorI ( "Segmentation violation - possible attempt to dereference NIL", 0); END SegV; BEGIN END RTSignal.