Minimal changes to get m6502 to compile (won't work)
[Apout.git] / bsd_signal.c
1 /*
2  * Much of this file comes from 2.11BSD's /usr/include/signal.h and is
3  * Copyright (c) 1986 Regents of the University of California.
4  * All rights reserved.  The Berkeley software License Agreement
5  * specifies the terms and conditions for redistribution.
6  *
7  *      Code to deal with 2.11BSD signals
8  */
9 #include "defines.h"
10 #include <signal.h>
11 #include "bsdtrap.h"
12
13
14 #define NBSDSIG 32
15
16 #define BSDSIGHUP       1       /* hangup */
17 #define BSDSIGINT       2       /* interrupt */
18 #define BSDSIGQUIT      3       /* quit */
19 #define BSDSIGILL       4       /* illegal instruct (not reset when caught) */
20 #define BSDSIGTRAP      5       /* trace trap (not reset when caught) */
21 #define BSDSIGIOT       6       /* IOT instruction */
22 #define BSDSIGEMT       7       /* EMT instruction */
23 #define BSDSIGFPE       8       /* floating point exception */
24 #define BSDSIGKILL      9       /* kill (cannot be caught or ignored) */
25 #define BSDSIGBUS       10      /* bus error */
26 #define BSDSIGSEGV      11      /* segmentation violation */
27 #define BSDSIGSYS       12      /* bad argument to system call */
28 #define BSDSIGPIPE      13      /* write on a pipe with no one to read it */
29 #define BSDSIGALRM      14      /* alarm clock */
30 #define BSDSIGTERM      15      /* software termination signal from kill */
31 #define BSDSIGURG       16      /* urgent condition on IO channel */
32 #define BSDSIGSTOP      17      /* sendable stop signal not from tty */
33 #define BSDSIGTSTP      18      /* stop signal from tty */
34 #define BSDSIGCONT      19      /* continue a stopped process */
35 #define BSDSIGCHLD      20      /* to parent on child stop or exit */
36 #define BSDSIGTTIN      21      /* to readers pgrp upon background tty read */
37 #define BSDSIGTTOU      22      /* like TTIN for output if (tp->t_local&LTOSTOP) */
38 #define BSDSIGIO        23      /* input/output possible signal */
39 #define BSDSIGXCPU      24      /* exceeded CPU time limit */
40 #define BSDSIGXFSZ      25      /* exceeded file size limit */
41 #define BSDSIGVTALRM    26      /* virtual time alarm */
42 #define BSDSIGPROF      27      /* profiling time alarm */
43 #define BSDSIGWINCH     28      /* window size changes */
44 #define BSDSIGUSR1      30      /* user defined signal 1 */
45 #define BSDSIGUSR2      31      /* user defined signal 2 */
46 #define bsdsigismember(set, signo) ((*(set) & (1L << ((signo) - 1))) != 0)
47
48 #define BSDSIG_ERR      -1
49 #define BSDSIG_DFL       0
50 #define BSDSIG_IGN       1
51
52 /*
53  * Signal vector "template" used in sigaction call.
54  */
55 struct bsd_sigaction {
56     int16_t sig_handler;        /* signal handler */
57     u_int32_t sa_mask;          /* signal mask to apply */
58     int16_t sa_flags;           /* see signal options below */
59 };
60
61 #define BSD_ONSTACK     0x0001  /* take signal on signal stack */
62 #define BSD_RESTART     0x0002  /* restart system on signal return */
63 #define BSD_DISABLE     0x0004  /* disable taking signals on alternate stack */
64 #define BSD_NOCLDSTOP   0x0008  /* do not generate SIGCHLD on child stop */
65
66
67 /* Translate 2.11BSD signal value to our value */
68
69 static int bsdsig[] = {
70     0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGIOT, SIGEMT,
71     SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM,
72     SIGTERM, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, SIGCHLD, SIGTTIN,
73     SIGTTOU, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
74     SIGUSR1, SIGUSR2
75 };
76
77 /* We keep a set of struct sigactions
78  * for each 2.11BSD signal
79  */
80 struct bsd_sigaction Sigact[NBSDSIG];
81
82
83 /* Set all signals to their default value */
84 void set_bsdsig_dfl(void)
85 {
86     int i;
87
88     for (i = 0; i < NBSDSIG; i++) {
89         if (bsdsig[i])
90             signal(bsdsig[i], SIG_DFL);
91         Sigact[i].sig_handler = BSDSIG_DFL;
92         Sigact[i].sa_mask = Sigact[i].sa_flags = 0;
93     }
94 }
95
96 int do_sigaction(int sig, int a, int oa)
97 {
98     int i;
99     struct bsd_sigaction *act, *oact;
100     struct sigaction ouraction;
101
102     if ((sig < 0) || (sig >= NBSDSIG))
103         return (EINVAL);
104
105     if (oa) {
106         oact = (struct bsd_sigaction *) &dspace[oa];
107         memcpy(oact, &Sigact[sig], sizeof(struct bsd_sigaction));
108     }
109
110     if (a) {
111         act = (struct bsd_sigaction *) &dspace[a];
112
113         /* If required, map mask here */
114         /* Currently, the assumption is a 1-1 match */
115         sigemptyset(&(ouraction.sa_mask));
116         for (i = 1; i < NBSDSIG; i++) {
117             if bsdsigismember
118             (&(act->sa_mask), i)
119                 sigaddset(&(ouraction.sa_mask), i);
120         }
121         /* If required, map flags here */
122         ouraction.sa_flags = act->sa_flags;
123         ouraction.sa_handler = sigcatcher;
124     }
125
126     i = sigaction(bsdsig[sig], &ouraction, NULL);
127     if (i == -1)
128         return (i);
129
130     /* Else save the new sigaction */
131     act = (struct bsd_sigaction *) &dspace[a];
132     memcpy(&Sigact[sig], act, sizeof(struct bsd_sigaction));
133     return (i);
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 /* For now, the rest commented out. One day I might
155  * get around to implementing 2.11BSD signals properly
156  */
157
158 #if 0
159 int (*signal()) ();
160
161 typedef unsigned long sigset_t;
162
163
164 /*
165  * Flags for sigprocmask:
166  */
167 #define BSDSIG_BLOCK    1       /* block specified signal set */
168 #define BSDSIG_UNBLOCK  2       /* unblock specified signal set */
169 #define BSDSIG_SETMASK  3       /* set specified signal set */
170
171 typedef int (*sig_t) ();        /* type of signal function */
172
173 /*
174  * Structure used in sigaltstack call.
175  */
176 struct sigaltstack {
177     char *ss_base;              /* signal stack base */
178     int ss_size;                /* signal stack length */
179     int ss_flags;               /* SA_DISABLE and/or SA_ONSTACK */
180 };
181 #define MINBSDSIGSTKSZ  128     /* minimum allowable stack */
182 #define BSDSIGSTKSZ     (MINBSDSIGSTKSZ + 384)  /* recommended stack size */
183
184 /*
185  * 4.3 compatibility:
186  * Signal vector "template" used in sigvec call.
187  */
188 struct sigvec {
189     int (*sv_handler) ();       /* signal handler */
190     long sv_mask;               /* signal mask to apply */
191     int sv_flags;               /* see signal options below */
192 };
193 #define SV_ONSTACK      SA_ONSTACK      /* take signal on signal stack */
194 #define SV_INTERRUPT    SA_RESTART      /* same bit, opposite sense */
195 #define sv_onstack sv_flags     /* isn't compatibility wonderful! */
196
197 /*
198  * 4.3 compatibility:
199  * Structure used in sigstack call.
200  */
201 struct sigstack {
202     char *ss_sp;                /* signal stack pointer */
203     int ss_onstack;             /* current status */
204 };
205
206 /*
207  * Information pushed on stack when a signal is delivered.
208  * This is used by the kernel to restore state following
209  * execution of the signal handler.  It is also made available
210  * to the handler to allow it to properly restore state if
211  * a non-standard exit is performed.
212  */
213 struct sigcontext {
214     int sc_onstack;             /* sigstack state to restore */
215     long sc_mask;               /* signal mask to restore */
216     int sc_sp;                  /* sp to restore */
217     int sc_fp;                  /* fp to restore */
218     int sc_r1;                  /* r1 to restore */
219     int sc_r0;                  /* r0 to restore */
220     int sc_pc;                  /* pc to restore */
221     int sc_ps;                  /* psl to restore */
222     int sc_ovno                 /* overlay to restore */
223 };
224
225 /*
226  * Macro for converting signal number to a mask suitable for
227  * sigblock().
228  */
229 #define sigmask(m)              (1L << ((m)-1))
230 #define sigaddset(set, signo)   (*(set) |= 1L << ((signo) - 1), 0)
231 #define sigdelset(set, signo)   (*(set) &= ~(1L << ((signo) - 1)), 0)
232 #define sigemptyset(set)        (*(set) = (sigset_t)0, (int)0)
233 #define sigfillset(set)         (*(set) = ~(sigset_t)0, (int)0)
234 #define sigismember(set, signo) ((*(set) & (1L << ((signo) - 1))) != 0)
235
236 #endif                          /* 0 */
237
238 /* the following used to be in pdp11/cpu.c but moved here as it's generic */
239
240 struct our_siglist *Sighead = NULL;     /* List of pending signals */
241 struct our_siglist *Sigtail = NULL;     /* List of pending signals */
242 void (*sigrunner) (void) = NULL;        /* F'n that will run the signal */
243
244 /* This is the generic function which catches
245  * a signal, and appends it to the queue.
246  */
247 void sigcatcher(int sig)
248 {
249     struct our_siglist *this;
250
251     this = (struct our_siglist *) malloc(sizeof(struct our_siglist));
252     if (this == NULL)
253         return;
254
255     TrapDebug((dbg_file, "Caught signal %d\n", sig));
256
257     this->sig = sig;
258     this->next = NULL;
259     if (Sighead == NULL) {
260         Sighead = Sigtail = this;
261     } else {
262         Sigtail->next = this;
263         Sigtail = this;
264     }
265 }