Pristine Ack-5.5
[Ack-5.5.git] / util / int / m_sigtrp.c
1 /*
2         Dedicated treatment of the sigtrp system call, MON 48.
3 */
4
5 /* $Id: m_sigtrp.c,v 2.5 1994/06/24 10:48:02 ceriel Exp $ */
6
7 #include        <signal.h>
8
9 #include        "global.h"
10 #include        "log.h"
11 #include        "warn.h"
12 #include        "trap.h"
13
14 /*************************** SIGTRP *************************************
15  *  The monitor call "sigtrp()" is handled by "do_sigtrp()".  The first *
16  *  argument is a EM-trap number (0<=tn<=252), the second a UNIX signal *
17  *  number.  The user wants trap "tn" to be generated, in case signal   *
18  *  "sn" occurs.  The report about this interpreter has a section,      *
19  *  giving all details about signal handling.  Do_sigtrp() returns the  *
20  *  previous trap-number "sn" was mapped onto.  A return value of -1    *
21  *  indicates an error.                                                 *
22  ************************************************************************/
23
24 #define UNIX_trap(sn)   (SIGILL <= sn && sn <= SIGSYS)
25
26 #ifndef NSIG
27 #define NSIG _NSIG
28 #endif
29 PRIVATE int sig_map[NSIG+1];            /* maps signals onto trap numbers */
30
31 PRIVATE void HndlIntSig();              /* handle signal to interpreter */
32 PRIVATE void HndlEmSig();               /* handle signal to user program */
33
34 init_signals() {
35         int sn;
36
37         for (sn = 0; sn < NSIG+1; sn++) {
38                 sig_map[sn] = -2;       /* Default EM trap number */
39         }
40
41         for (sn = 0; sn < NSIG+1; sn++) {
42                 /* for all signals that would cause termination */
43                 if (!UNIX_trap(sn)) {
44 #ifdef SIGCHLD
45                         if (sn == SIGCHLD) continue;
46 #endif
47 #ifdef SIGIO
48                         if (sn == SIGIO) continue;
49 #endif
50 #ifdef SIGWINCH
51                         if (sn == SIGWINCH) continue;
52 #endif
53                         if (signal(sn, SIG_IGN) != SIG_IGN) {
54                                 /* we take our fate in our own hand */
55                                 signal(sn, HndlIntSig);
56                         }
57                 }
58         }
59 }
60
61 int do_sigtrp(tn, sn)
62         int tn;                         /* EM trap number */
63         int sn;                         /* UNIX signal number */
64 {
65         register int old_tn;
66
67         if (sn <= 0 || sn > NSIG) {
68                 einval(WILLSN);
69                 return (-1);
70         }
71
72         if (UNIX_trap(sn)) {
73                 einval(WUNIXTR);
74                 return (-1);
75         }
76
77         old_tn = sig_map[sn];
78         sig_map[sn] = tn;
79         if (tn == -2) {                 /* reset default for signal sn */
80                 signal(sn, SIG_DFL);
81         }
82         else if (tn == -3) {            /* ignore signal sn */
83                 signal(sn, SIG_IGN);
84         }
85         else if (tn >= 0 && tn <= 252) {/* legal tn */
86                 if ((int)signal(sn, HndlEmSig) == -1) {
87                         sig_map[sn] = old_tn;
88                         return (-1);
89                 }
90         }
91         else {
92                 /* illegal trap number */
93                 einval(WILLTN);
94                 sig_map[sn] = old_tn;   /* restore sig_map */
95                 return (-1);
96         }
97         return (old_tn);
98 }
99
100 trap_signal()
101 {
102         /*      execute the trap belonging to the signal that came in during
103                 the last instruction
104         */
105         register int old_sig = signalled;
106
107         signalled = 0;
108         trap(sig_map[old_sig]);
109 }
110
111 /* The handling functions for the UNIX signals */
112
113 PRIVATE void HndlIntSig(sn)
114         int sn;
115 {
116         /* The interpreter got the signal */
117         signal(sn, SIG_IGN);            /* peace and quiet for close_down() */
118         LOG(("@t1 signal %d caught by interpreter", sn));
119         message("interpreter received signal %d, which was not caught by the interpreted program",
120                 sn);
121         close_down(1);
122 }
123
124 PRIVATE void HndlEmSig(sn)
125         int sn;
126 {
127         /* The EM machine got the signal */
128         signal(sn, HndlIntSig);         /* Revert to old situation */
129         signalled = sn;
130 }
131