summaryrefslogtreecommitdiff
path: root/lang/modula-3-lib/files/patch-bp
blob: 84e7eeebb67937cd365db8506c8ce62f7f3f9c04 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
This patch uses the sigaction interface to gain access to the PC value
so that it can be printed out when a fatal signal occurs.

--- m3/m3core/src/runtime/FreeBSD2/RTSignal.m3.orig	Mon Nov 21 10:31:19 1994
+++ m3/m3core/src/runtime/FreeBSD2/RTSignal.m3	Thu Jul 10 14:24:59 1997
@@ -7,18 +7,21 @@
 
 UNSAFE MODULE RTSignal;
 
-IMPORT RTMisc, RTProcess, Csignal, Usignal, Uprocess;
+IMPORT RTMisc, RTProcess, Usignal, Uprocess;
 FROM Ctypes IMPORT int;
 
+TYPE
+  SigInfo = UNTRACED REF Usignal.struct_sigcontext;
+
 VAR
-  DefaultHandler   : Csignal.Handler;
-  IgnoreSignal     : Csignal.Handler;
-  initial_handlers : ARRAY [0..5] OF Csignal.Handler;
+  DefaultHandler   : Usignal.SignalHandler;
+  IgnoreSignal     : Usignal.SignalHandler;
+  initial_handlers : ARRAY [0..5] OF Usignal.struct_sigaction;
 
 PROCEDURE InstallHandlers () =
   BEGIN
-    DefaultHandler := LOOPHOLE (0, Csignal.Handler);
-    IgnoreSignal   := LOOPHOLE (1, Csignal.Handler);
+    DefaultHandler := LOOPHOLE (0, Usignal.SignalHandler);
+    IgnoreSignal   := LOOPHOLE (1, Usignal.SignalHandler);
 
     SetHandler (0, Usignal.SIGHUP,  Shutdown);
     SetHandler (1, Usignal.SIGINT,  Interrupt);
@@ -28,13 +31,18 @@
     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
+PROCEDURE SetHandler (id: INTEGER; sig: int;  handler: Usignal.SignalHandler) =
+  (* Note: we use the LOOPHOLE to prevent the runtime check for
+     nested procedure.  The runtime check crashes when
+     handler = IgnoreSignal = 1. *)
+  VAR new: Usignal.struct_sigaction;
+  BEGIN
+    new.sa_handler := LOOPHOLE (handler, Usignal.SignalHandler);
+    new.sa_flags   := 0;
+    EVAL Usignal.sigaction (sig, ADR(new), ADR(initial_handlers[id]));
+    IF (initial_handlers[id].sa_handler # DefaultHandler) THEN
       (* don't override inherited, non-default handlers *)
-      EVAL Csignal.signal (sig, old);
+      EVAL Usignal.sigaction (sig, ADR(initial_handlers[id]), ADR(new));
     END;
   END SetHandler;
 
@@ -50,36 +58,43 @@
 
 PROCEDURE RestoreHandler (id: INTEGER;  sig: int) =
   BEGIN
-    EVAL Csignal.signal (sig, initial_handlers[id]);
+    EVAL Usignal.sigaction (sig, ADR(initial_handlers[id]), NIL);
   END RestoreHandler;
 
-PROCEDURE Shutdown (sig: int) =
+PROCEDURE Shutdown (sig: int; <*UNUSED*> code: int; <*UNUSED*> scp: SigInfo) =
+  VAR new, old: Usignal.struct_sigaction;
   BEGIN
+    new.sa_handler := DefaultHandler;
+    new.sa_flags   := 0;
     RTProcess.InvokeExitors ();                   (* flush stdio... *)
-    EVAL Csignal.signal (sig, DefaultHandler);    (* restore default handler *)
+    EVAL Usignal.sigaction (sig, ADR(new), ADR(old));       (* restore default handler *)
     EVAL Usignal.kill (Uprocess.getpid (), sig);  (* and resend the signal *)
   END Shutdown;
 
-PROCEDURE Interrupt (sig: int) =
+PROCEDURE Interrupt (sig: int;  code: int;  scp: SigInfo) =
   VAR h := RTProcess.OnInterrupt (NIL);
   BEGIN
     IF (h = NIL) THEN
-      Shutdown (sig);
+      Shutdown (sig, code, scp);
     ELSE
       EVAL RTProcess.OnInterrupt (h); (* reinstall the handler *)
       h ();
     END;
   END Interrupt;
 
-PROCEDURE Quit (<*UNUSED*> sig: int) =
+PROCEDURE Quit (<*UNUSED*> sig, code: int; scp: SigInfo) =
+  VAR pc := 0;
   BEGIN
-    RTMisc.FatalErrorI ("aborted", 0);
+    IF (scp # NIL) THEN pc := scp.sc_eip END;
+    RTMisc.FatalErrorPC (pc, "aborted");
   END Quit;
 
-PROCEDURE SegV (<*UNUSED*> sig: int) =
+PROCEDURE SegV (<*UNUSED*> sig, code: int; scp: SigInfo) =
+  VAR pc := 0;
   BEGIN
-    RTMisc.FatalErrorI (
-      "Segmentation violation - possible attempt to dereference NIL", 0);
+    IF (scp # NIL) THEN pc := scp.sc_eip END;
+    RTMisc.FatalErrorPC (pc,
+      "Segmentation violation - possible attempt to dereference NIL");
   END SegV;
 
 BEGIN