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