xref: /haiku/headers/posix/signal.h (revision d5cd5d63ff0ad395989db6cf4841a64d5b545d1d)
1 #ifndef _SIGNAL_H_
2 #define _SIGNAL_H_
3 
4 /*
5 ** Distributed under the terms of the OpenBeOS License.
6 */
7 
8 #include <sys/types.h>
9 
10 
11 typedef int	 sig_atomic_t;
12 typedef long sigset_t;
13 
14 typedef void (*sig_func_t)(int);
15 typedef void (*__signal_func_ptr)(int);  /* deprecated, for compatibility with BeOS only */
16 
17 
18 /*
19  * macros defining the standard signal handling behavior
20  */
21 #define SIG_DFL	((sig_func_t) 0)   /* the signal was treated in the "default" manner */
22 #define SIG_IGN	((sig_func_t) 1)   /* the signal was ignored */
23 #define SIG_ERR	((sig_func_t)-1)   /* an error ocurred during signal processing */
24 
25 
26 /*
27  * structure used by sigaction()
28  *
29  * Note: the 'sa_userdata' field is a non-Posix extension.
30  * See the SPECIAL NOTES below for an explanation of this.
31  *
32  */
33 struct sigaction {
34 	sig_func_t sa_handler;
35 	sigset_t   sa_mask;
36 	int        sa_flags;
37 	void      *sa_userdata;  /* will be passed to the signal handler */
38 };
39 
40 
41 /*
42  * values for sa_flags
43  */
44 #define SA_NOCLDSTOP  0x01
45 #define SA_ONESHOT    0x02
46 #define SA_NOMASK     0x04
47 #define SA_NODEFER    SA_NOMASK
48 #define SA_RESTART    0x08
49 #define SA_STACK      0x10
50 
51 
52 
53 /*
54  * for signals using an alternate stack
55  */
56 typedef struct stack_t {
57 	void   *ss_sp;
58 	size_t  ss_size;
59 	int     ss_flags;
60 } stack_t;
61 
62 
63 /*
64  * for the 'how' arg of sigprocmask()
65  */
66 #define SIG_BLOCK    1
67 #define SIG_UNBLOCK  2
68 #define SIG_SETMASK  3
69 
70 
71 
72 /*
73  * The list of all defined signals:
74  *
75  * The numbering of signals for OpenBeOS attempts to maintain
76  * some consistency with UN*X conventions so that things
77  * like "kill -9" do what you expect.
78  */
79 #define	SIGHUP      1      /* hangup -- tty is gone! */
80 #define SIGINT      2      /* interrupt */
81 #define SIGQUIT     3      /* `quit' special character typed in tty  */
82 #define SIGILL	    4      /* illegal instruction */
83 #define SIGCHLD     5      /* child process exited */
84 #define SIGABRT	    6      /* abort() called, dont' catch */
85 #define SIGPIPE	    7      /* write to a pipe w/no readers */
86 #define SIGFPE	    8      /* floating point exception */
87 #define SIGKILL	    9      /* kill a team (not catchable) */
88 #define SIGSTOP	   10      /* suspend a thread (not catchable) */
89 #define SIGSEGV	   11      /* segmentation violation (read: invalid pointer) */
90 #define SIGCONT    12      /* continue execution if suspended */
91 #define SIGTSTP	   13      /* `stop' special character typed in tty */
92 #define SIGALRM    14      /* an alarm has gone off (see alarm()) */
93 #define SIGTERM	   15      /* termination requested */
94 #define SIGTTIN	   16      /* read of tty from bg process */
95 #define SIGTTOU	   17      /* write to tty from bg process */
96 #define SIGUSR1	   18      /* app defined signal 1 */
97 #define SIGUSR2	   19      /* app defined signal 2 */
98 #define SIGWINCH   20      /* tty window size changed */
99 #define SIGKILLTHR 21      /* be specific: kill just the thread, not team */
100 #define SIGTRAP	   22
101 
102 #define SIGBUS     SIGSEGV /* for old style code */
103 
104 
105 /*
106  * Signal numbers 23-32 are currently free but may be used in future
107  * releases.  Use them at your own peril (if you do use them, at least
108  * be smart and use them backwards from signal 32).
109  */
110 #define MAX_SIGNO     32       /* the most signals that a single thread can reference */
111 #define __signal_max  22       /* the largest signal number that is actually defined */
112 #define NSIG (__signal_max+1)  /* the number of defined signals */
113 
114 
115 
116 /* the global table of text strings containing descriptions for each signal */
117 extern const char * const sys_siglist[NSIG];
118 
119 
120 
121 #ifdef __cplusplus
122 extern "C" {
123 #endif
124 
125 sig_func_t signal(int sig, sig_func_t signal_handler);
126 int        raise(int sig);
127 int        kill(pid_t pid, int sig);
128 int        send_signal(pid_t tid, uint sig);
129 
130 int        sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
131 int        sigprocmask(int how, const sigset_t *set, sigset_t *oset);
132 int        sigpending(sigset_t *set);
133 int        sigsuspend(const sigset_t *mask);
134 
135 int        sigemptyset(sigset_t *set);
136 int        sigfillset(sigset_t *set);
137 static int sigaddset(sigset_t *set, int signo);
138 static int sigdelset(sigset_t *set, int signo);
139 static int sigismember(const sigset_t *set, int signo);
140 
141 const char *strsignal(int sig);
142 
143 const void  set_signal_stack(void *ptr, size_t size);
144 int         sigaltstack(const stack_t *ss, stack_t *oss);         /* XXXdbg */
145 
146 static inline int
147 sigismember(const sigset_t *set, int sig)
148 {
149 	sigset_t mask = (((sigset_t) 1) << (( sig ) - 1)) ;
150 	return   (*set & mask) ? 1 : 0 ;
151 }
152 
153 static inline int
154 sigaddset(sigset_t *set, int sig)
155 {
156 	sigset_t mask = (((sigset_t) 1) << (( sig ) - 1)) ;
157 	return   ((*set |= mask), 0) ;
158 }
159 
160 static inline int
161 sigdelset(sigset_t *set, int sig)
162 {
163 	sigset_t mask = (((sigset_t) 1) << (( sig ) - 1)) ;
164 	return   ((*set &= ~mask), 0) ;
165 }
166 
167 #ifdef __cplusplus
168 }
169 #endif
170 
171 
172 /*
173  * ==================================================
174  * !!! SPECIAL NOTES CONCERNING NON-POSIX EXTENSIONS:
175  * ==================================================
176  *
177  * The standard Posix interface for signal handlers is not as useful
178  * as it could be. The handler can define only one single argument
179  * (the signal number). For example:
180  *    void
181  *    my_signal_handler(int sig)
182  *    {
183  *    . . .
184  *    }
185  *
186  *    // install the handler
187  *    signal(SIGINT, &my_signal_handler);
188  *
189  * The sigaction() function allows finer grained control of the signal
190  * handling. It also allows an opportunity, via the 'sigaction' struct, to
191  * enable additional data to be passed to the handler. For example:
192  *    void
193  *    my_signal_handler(int sig, char *somedata, vregs regs)
194  *    {
195  *    . . .
196  *    }
197  *
198  *    struct sigaction sa;
199  *    char data_buffer[32];
200  *
201  *    sa.sa_handler = (sig_func_t) my_signal_handler;
202  *    sigemptyset(&sa.sa_mask);
203  *    sigaddset(&sa.sa_mask, SIGINT);
204  *    sa.sa_userdata = data_buffer;
205  *
206  *    // install the handler
207  *    sigaction(SIGINT, &sa, NULL);
208  *
209  * The two additional arguments available to the signal handler are extensions
210  * to the Posix standard. This feature was introduced by the BeOS and retained
211  * by OpenBeOS. However, to remain compatible with Posix and ANSI C, the type
212  * of the sa_handler field is defined as 'sig_func_t'. This requires the handler
213  * to be cast when assigned to the sa_handler field, as in the example above.
214  *
215  * NOTE: C++ member functions can not be signal handlers!
216  * This is because they expect a "this" pointer as the first argument.
217  *
218  *
219  * The 3 arguments that OpenBeOS provides to signal handlers are as follows:
220  *
221  *  - The first argument is the (usual) signal number.
222  *
223  *  - The second argument is whatever value is put in the sa_userdata field
224  *    of the sigaction struct.
225  *
226  *  - The third argument is a pointer to a vregs struct (defined below).
227  *    The vregs struct contains the contents of the volatile registers at
228  *    the time the signal was delivered to your thread. You can change the fields
229  *    of the structure. After your signal handler completes, the OS uses this struct
230  *    to reload the registers for your thread (privileged registers are not loaded
231  *    of course). The vregs struct is of course terribly machine dependent.
232  *    If you use it, you should expect to have to re-work your code when new
233  *    processors come out. Nonetheless, the ability to change the registers does
234  *    open some interesting programming possibilities.
235  */
236 
237 
238 
239 
240 /*
241  * the vregs struct:
242  *
243  * signal handlers get this as the last argument
244  */
245 
246 typedef struct vregs vregs;
247 
248 #if __POWERPC__
249 struct vregs
250 {
251 	ulong pc,                                         /* program counter */
252 	      r0,                                         /* scratch */
253 	      r1,                                         /* stack ptr */
254 	      r2,                                         /* TOC */
255 	      r3,r4,r5,r6,r7,r8,r9,r10,                   /* volatile regs */
256 	      r11,r12;                                    /* scratch regs */
257 
258    double f0,                                         /* fp scratch */
259 	      f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13; /* fp volatile regs */
260 
261 	ulong filler1,                                    /* place holder */
262 	      fpscr,                                      /* fp condition codes */
263 	      ctr, xer, cr, msr, lr;                      /* misc. status */
264 };
265 #endif /* __POWERPC__ */
266 
267 #if __INTEL__
268 
269 typedef struct packed_fp_stack {
270 	unsigned char	st0[10];
271 	unsigned char	st1[10];
272 	unsigned char	st2[10];
273 	unsigned char	st3[10];
274 	unsigned char	st4[10];
275 	unsigned char	st5[10];
276 	unsigned char	st6[10];
277 	unsigned char	st7[10];
278 } packed_fp_stack;
279 
280 typedef struct packed_mmx_regs {
281 	unsigned char	mm0[10];
282 	unsigned char	mm1[10];
283 	unsigned char	mm2[10];
284 	unsigned char	mm3[10];
285 	unsigned char	mm4[10];
286 	unsigned char	mm5[10];
287 	unsigned char	mm6[10];
288 	unsigned char	mm7[10];
289 } packed_mmx_regs;
290 
291 typedef struct old_extended_regs {
292 	unsigned short	fp_control;
293 	unsigned short	_reserved1;
294 	unsigned short	fp_status;
295 	unsigned short	_reserved2;
296 	unsigned short	fp_tag;
297 	unsigned short	_reserved3;
298 	unsigned long	fp_eip;
299 	unsigned short	fp_cs;
300 	unsigned short	fp_opcode;
301 	unsigned long	fp_datap;
302 	unsigned short	fp_ds;
303 	unsigned short	_reserved4;
304 	union {
305 		packed_fp_stack	fp;
306 		packed_mmx_regs	mmx;
307 	} fp_mmx;
308 } old_extended_regs;
309 
310 typedef struct fp_stack {
311 	unsigned char	st0[10];
312 	unsigned char	_reserved_42_47[6];
313 	unsigned char	st1[10];
314 	unsigned char	_reserved_58_63[6];
315 	unsigned char	st2[10];
316 	unsigned char	_reserved_74_79[6];
317 	unsigned char	st3[10];
318 	unsigned char	_reserved_90_95[6];
319 	unsigned char	st4[10];
320 	unsigned char	_reserved_106_111[6];
321 	unsigned char	st5[10];
322 	unsigned char	_reserved_122_127[6];
323 	unsigned char	st6[10];
324 	unsigned char	_reserved_138_143[6];
325 	unsigned char	st7[10];
326 	unsigned char	_reserved_154_159[6];
327 } fp_stack;
328 
329 typedef struct mmx_regs {
330 	unsigned char	mm0[10];
331 	unsigned char	_reserved_42_47[6];
332 	unsigned char	mm1[10];
333 	unsigned char	_reserved_58_63[6];
334 	unsigned char	mm2[10];
335 	unsigned char	_reserved_74_79[6];
336 	unsigned char	mm3[10];
337 	unsigned char	_reserved_90_95[6];
338 	unsigned char	mm4[10];
339 	unsigned char	_reserved_106_111[6];
340 	unsigned char	mm5[10];
341 	unsigned char	_reserved_122_127[6];
342 	unsigned char	mm6[10];
343 	unsigned char	_reserved_138_143[6];
344 	unsigned char	mm7[10];
345 	unsigned char	_reserved_154_159[6];
346 } mmx_regs;
347 
348 typedef struct xmmx_regs {
349 	unsigned char	xmm0[16];
350 	unsigned char	xmm1[16];
351 	unsigned char	xmm2[16];
352 	unsigned char	xmm3[16];
353 	unsigned char	xmm4[16];
354 	unsigned char	xmm5[16];
355 	unsigned char	xmm6[16];
356 	unsigned char	xmm7[16];
357 } xmmx_regs;
358 
359 typedef struct new_extended_regs {
360 	unsigned short	fp_control;
361 	unsigned short	fp_status;
362 	unsigned short	fp_tag;
363 	unsigned short	fp_opcode;
364 	unsigned long	fp_eip;
365 	unsigned short	fp_cs;
366 	unsigned short	res_14_15;
367 	unsigned long	fp_datap;
368 	unsigned short	fp_ds;
369 	unsigned short	_reserved_22_23;
370 	unsigned long	mxcsr;
371 	unsigned long	_reserved_28_31;
372 	union {
373 		fp_stack fp;
374 		mmx_regs mmx;
375 	} fp_mmx;
376 	xmmx_regs xmmx;
377 	unsigned char	_reserved_288_511[224];
378 } new_extended_regs;
379 
380 typedef struct extended_regs {
381 	union {
382 		old_extended_regs	old_format;
383 		new_extended_regs	new_format;
384 	} state;
385 	unsigned long	format;
386 } extended_regs;
387 
388 struct vregs {
389 	unsigned long			eip;
390 	unsigned long			eflags;
391 	unsigned long			eax;
392 	unsigned long			ecx;
393 	unsigned long			edx;
394 	unsigned long			esp;
395 	unsigned long			ebp;
396 	unsigned long			_reserved_1;
397 	extended_regs	xregs;
398 	unsigned long			_reserved_2[3];
399 };
400 
401 #endif /* __INTEL__ */
402 
403 
404 #endif /* _SIGNAL_H_ */
405