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