runtime/src/FreeBSD/RTSignal.m3


Copyright (C) 1994, Digital Equipment Corp.

UNSAFE MODULE RTSignal;

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 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;

PROCEDURE SetHandler (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;

PROCEDURE RestoreHandlers () =
  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;

PROCEDURE RestoreHandler (id: INTEGER;  sig: int) =
  BEGIN
    EVAL Csignal.signal (sig, initial_handlers[id]);
  END RestoreHandler;

PROCEDURE Shutdown (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;

PROCEDURE Interrupt (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;

PROCEDURE Quit (<*UNUSED*> sig: int) =
  BEGIN
    RTMisc.FatalErrorI ("aborted", 0);
  END Quit;

PROCEDURE SegV (<*UNUSED*> sig: int) =
  BEGIN
    RTMisc.FatalErrorI (
      "Segmentation violation - possible attempt to dereference NIL", 0);
  END SegV;

BEGIN
END RTSignal.

interface Csignal is in:


interface Usignal is in:


interface Uprocess is in: