1/*
2 * Copyright 2002-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _SIGNAL_H_
6#define _SIGNAL_H_
7
8
9#include <sys/types.h>
10
11
12typedef int	sig_atomic_t;
13typedef __haiku_uint64 sigset_t;
14
15
16/* macros defining the standard signal handling behavior */
17#define SIG_DFL		((__sighandler_t)0)		/* "default" signal behaviour */
18#define SIG_IGN		((__sighandler_t)1)		/* ignore signal */
19#define SIG_ERR		((__sighandler_t)-1)	/* an error occurred during signal
20											   processing */
21#define SIG_HOLD	((__sighandler_t)3)		/* the signal was hold */
22
23/* macros specifying the event notification type (sigevent::sigev_notify) */
24#define SIGEV_NONE		0	/* no notification */
25#define SIGEV_SIGNAL	1	/* notify via queued signal */
26#define SIGEV_THREAD	2	/* notify via function called in new thread */
27
28
29union sigval {
30	int		sival_int;
31	void*	sival_ptr;
32};
33
34struct sigevent {
35	int				sigev_notify;	/* notification type */
36	int				sigev_signo;	/* signal number */
37	union sigval	sigev_value;	/* user-defined signal value */
38	void			(*sigev_notify_function)(union sigval);
39									/* notification function in case of
40									   SIGEV_THREAD */
41	pthread_attr_t*	sigev_notify_attributes;
42									/* pthread creation attributes in case of
43									   SIGEV_THREAD */
44};
45
46typedef struct __siginfo_t {
47	int				si_signo;	/* signal number */
48	int				si_code;	/* signal code */
49	int				si_errno;	/* if non zero, an error number associated with
50								   this signal */
51	pid_t			si_pid;		/* sending process ID */
52	uid_t			si_uid;		/* real user ID of sending process */
53	void*			si_addr;	/* address of faulting instruction */
54	int				si_status;	/* exit value or signal */
55	long			si_band;	/* band event for SIGPOLL */
56	union sigval	si_value;	/* signal value */
57} siginfo_t;
58
59
60/* signal handler function types */
61typedef void (*__sighandler_t)(int);
62typedef void  (*__siginfo_handler_t)(int, siginfo_t*, void*);
63
64#if defined(_DEFAULT_SOURCE)
65typedef __sighandler_t	sighandler_t;
66	/* GNU-like signal handler typedef */
67#endif
68
69
70/* structure used by sigaction() */
71struct sigaction {
72	union {
73		__sighandler_t		sa_handler;
74		__siginfo_handler_t	sa_sigaction;
75	};
76	sigset_t				sa_mask;
77	int						sa_flags;
78	void*					sa_userdata;	/* will be passed to the signal
79											   handler, BeOS extension */
80};
81
82/* values for sa_flags */
83#define SA_NOCLDSTOP	0x01
84#define SA_NOCLDWAIT	0x02
85#define SA_RESETHAND	0x04
86#define SA_NODEFER		0x08
87#define SA_RESTART		0x10
88#define SA_ONSTACK		0x20
89#define SA_SIGINFO		0x40
90#define SA_NOMASK		SA_NODEFER
91#define SA_STACK		SA_ONSTACK
92#define SA_ONESHOT		SA_RESETHAND
93
94/* values for ss_flags */
95#define SS_ONSTACK		0x1
96#define SS_DISABLE		0x2
97
98#define MINSIGSTKSZ		8192
99#define SIGSTKSZ		16384
100
101/* for signals using an alternate stack */
102typedef struct stack_t {
103	void*	ss_sp;
104	size_t	ss_size;
105	int		ss_flags;
106} stack_t;
107
108/* for the 'how' arg of sigprocmask() */
109#define SIG_BLOCK		1
110#define SIG_UNBLOCK		2
111#define SIG_SETMASK		3
112
113/*
114 * The list of all defined signals:
115 *
116 * The numbering of signals for Haiku attempts to maintain
117 * some consistency with UN*X conventions so that things
118 * like "kill -9" do what you expect.
119 */
120#define	SIGHUP			1	/* hangup -- tty is gone! */
121#define SIGINT			2	/* interrupt */
122#define SIGQUIT			3	/* `quit' special character typed in tty  */
123#define SIGILL			4	/* illegal instruction */
124#define SIGCHLD			5	/* child process exited */
125#define SIGABRT			6	/* abort() called, dont' catch */
126#define SIGPIPE			7	/* write to a pipe w/no readers */
127#define SIGFPE			8	/* floating point exception */
128#define SIGKILL			9	/* kill a team (not catchable) */
129#define SIGSTOP			10	/* suspend a thread (not catchable) */
130#define SIGSEGV			11	/* segmentation violation (read: invalid pointer) */
131#define SIGCONT			12	/* continue execution if suspended */
132#define SIGTSTP			13	/* `stop' special character typed in tty */
133#define SIGALRM			14	/* an alarm has gone off (see alarm()) */
134#define SIGTERM			15	/* termination requested */
135#define SIGTTIN			16	/* read of tty from bg process */
136#define SIGTTOU			17	/* write to tty from bg process */
137#define SIGUSR1			18	/* app defined signal 1 */
138#define SIGUSR2			19	/* app defined signal 2 */
139#define SIGWINCH		20	/* tty window size changed */
140#define SIGKILLTHR		21	/* be specific: kill just the thread, not team */
141#define SIGTRAP			22	/* Trace/breakpoint trap */
142#define SIGPOLL			23	/* Pollable event */
143#define SIGPROF			24	/* Profiling timer expired */
144#define SIGSYS			25	/* Bad system call */
145#define SIGURG			26	/* High bandwidth data is available at socket */
146#define SIGVTALRM		27	/* Virtual timer expired */
147#define SIGXCPU			28	/* CPU time limit exceeded */
148#define SIGXFSZ			29	/* File size limit exceeded */
149#define SIGBUS			30	/* access to undefined portion of a memory object */
150#define SIGRESERVED1	31	/* reserved for future use */
151#define SIGRESERVED2	32	/* reserved for future use */
152
153#define SIGRTMIN		(__signal_get_sigrtmin())
154							/* lowest realtime signal number */
155#define SIGRTMAX		(__signal_get_sigrtmax())
156							/* greatest realtime signal number */
157
158#define __MAX_SIGNO		64	/* greatest possible signal number, can be used (+1)
159							   as size of static arrays */
160#define NSIG			(__MAX_SIGNO + 1)
161							/* BSD extension, size of the sys_siglist table,
162							   obsolete */
163
164
165/* Signal code values appropriate for siginfo_t::si_code: */
166/* any signal */
167#define SI_USER			0	/* signal sent by user */
168#define SI_QUEUE		1	/* signal sent by sigqueue() */
169#define SI_TIMER		2	/* signal sent on timer_settime() timeout */
170#define SI_ASYNCIO		3	/* signal sent on asynchronous I/O completion */
171#define SI_MESGQ		4	/* signal sent on arrival of message on empty
172							   message queue */
173/* SIGILL */
174#define ILL_ILLOPC		10	/* illegal opcode */
175#define ILL_ILLOPN		11	/* illegal operand */
176#define ILL_ILLADR		12	/* illegal addressing mode */
177#define ILL_ILLTRP		13	/* illegal trap */
178#define ILL_PRVOPC		14	/* privileged opcode */
179#define ILL_PRVREG		15	/* privileged register */
180#define ILL_COPROC		16	/* coprocessor error */
181#define ILL_BADSTK		17	/* internal stack error */
182/* SIGFPE */
183#define FPE_INTDIV		20	/* integer division by zero */
184#define FPE_INTOVF		21	/* integer overflow */
185#define FPE_FLTDIV		22	/* floating-point division by zero */
186#define FPE_FLTOVF		23	/* floating-point overflow */
187#define FPE_FLTUND		24	/* floating-point underflow */
188#define FPE_FLTRES		25	/* floating-point inexact result */
189#define FPE_FLTINV		26	/* invalid floating-point operation */
190#define FPE_FLTSUB		27	/* subscript out of range */
191/* SIGSEGV */
192#define SEGV_MAPERR		30	/* address not mapped to object */
193#define SEGV_ACCERR		31	/* invalid permissions for mapped object */
194/* SIGBUS */
195#define BUS_ADRALN		40	/* invalid address alignment */
196#define BUS_ADRERR		41	/* nonexistent physical address */
197#define BUS_OBJERR		42	/* object-specific hardware error */
198/* SIGTRAP */
199#define TRAP_BRKPT		50	/* process breakpoint */
200#define TRAP_TRACE		51	/* process trace trap. */
201/* SIGCHLD */
202#define CLD_EXITED		60	/* child exited */
203#define CLD_KILLED		61	/* child terminated abnormally without core dump */
204#define CLD_DUMPED		62	/* child terminated abnormally with core dump */
205#define CLD_TRAPPED		63	/* traced child trapped */
206#define CLD_STOPPED		64	/* child stopped */
207#define CLD_CONTINUED	65	/* stopped child continued */
208/* SIGPOLL */
209#define POLL_IN			70	/* input available */
210#define POLL_OUT		71	/* output available */
211#define POLL_MSG		72	/* input message available */
212#define POLL_ERR		73	/* I/O error */
213#define POLL_PRI		74	/* high priority input available */
214#define POLL_HUP		75	/* device disconnected */
215
216
217/* the global table of text strings containing descriptions for each signal */
218extern const char* const sys_siglist[NSIG];
219	/* BSD extension, obsolete, use strsignal() instead */
220
221
222#ifdef __cplusplus
223extern "C" {
224#endif
225
226
227/* signal management (actions and block masks) */
228__sighandler_t signal(int _signal, __sighandler_t signalHandler);
229int     sigaction(int _signal, const struct sigaction* action,
230			struct sigaction* oldAction);
231__sighandler_t sigset(int _signal, __sighandler_t signalHandler);
232int		sigignore(int _signal);
233int		siginterrupt(int _signal, int flag);
234
235int     sigprocmask(int how, const sigset_t* set, sigset_t* oldSet);
236int		pthread_sigmask(int how, const sigset_t* set, sigset_t* oldSet);
237int		sighold(int _signal);
238int		sigrelse(int _signal);
239
240/* sending signals */
241int     raise(int _signal);
242int     kill(pid_t pid, int _signal);
243int		killpg(pid_t processGroupID, int _signal);
244int		sigqueue(pid_t pid, int _signal, const union sigval userValue);
245int		pthread_kill(pthread_t thread, int _signal);
246
247/* querying and waiting for signals */
248int     sigpending(sigset_t* set);
249int     sigsuspend(const sigset_t* mask);
250int		sigpause(int _signal);
251int 	sigwait(const sigset_t* set, int* _signal);
252int		sigwaitinfo(const sigset_t* set, siginfo_t* info);
253int		sigtimedwait(const sigset_t* set, siginfo_t* info,
254           const struct timespec* timeout);
255
256/* setting the per-thread signal stack */
257int		sigaltstack(const stack_t* stack, stack_t* oldStack);
258
259/* signal set (sigset_t) manipulation */
260int     sigemptyset(sigset_t* set);
261int     sigfillset(sigset_t* set);
262int 	sigaddset(sigset_t* set, int _signal);
263int 	sigdelset(sigset_t* set, int _signal);
264int 	sigismember(const sigset_t* set, int _signal);
265
266/* printing signal names */
267void	psiginfo(const siginfo_t* info, const char* message);
268void	psignal(int _signal, const char* message);
269
270/* implementation private */
271int		__signal_get_sigrtmin();
272int		__signal_get_sigrtmax();
273
274
275#ifdef __cplusplus
276}
277#endif
278
279
280/* TODO: move this into the documentation!
281 * ==================================================
282 * !!! SPECIAL NOTES CONCERNING NON-POSIX EXTENSIONS:
283 * ==================================================
284 *
285 * The standard Posix interface for signal handlers is not as useful
286 * as it could be. The handler can define only one single argument
287 * (the signal number). For example:
288 *    void
289 *    my_signal_handler(int sig)
290 *    {
291 *    . . .
292 *    }
293 *
294 *    // install the handler
295 *    signal(SIGINT, &my_signal_handler);
296 *
297 * The sigaction() function allows finer grained control of the signal
298 * handling. It also allows an opportunity, via the 'sigaction' struct, to
299 * enable additional data to be passed to the handler. For example:
300 *    void
301 *    my_signal_handler(int sig, char* userData, vregs* regs)
302 *    {
303 *    . . .
304 *    }
305 *
306 *    struct sigaction sa;
307 *    char data_buffer[32];
308 *
309 *    sa.sa_handler = (__sighandler_t)my_signal_handler;
310 *    sigemptyset(&sa.sa_mask);
311 *    sa.sa_userdata = userData;
312 *
313 *    // install the handler
314 *    sigaction(SIGINT, &sa, NULL);
315 *
316 * The two additional arguments available to the signal handler are extensions
317 * to the Posix standard. This feature was introduced by the BeOS and retained
318 * by Haiku. However, to remain compatible with Posix and ANSI C, the type
319 * of the sa_handler field is defined as '__sighandler_t'. This requires the
320 * handler to be cast when assigned to the sa_handler field, as in the example
321 * above.
322 *
323 * The 3 arguments that Haiku provides to signal handlers are as follows:
324 * 1) The first argument is the (usual) signal number.
325 *
326 * 2) The second argument is whatever value is put in the sa_userdata field
327 *    of the sigaction struct.
328 *
329 * 3) The third argument is a pointer to a vregs struct (defined below).
330 *    The vregs struct contains the contents of the volatile registers at
331 *    the time the signal was delivered to your thread. You can change the
332 *    fields of the structure. After your signal handler completes, the OS uses
333 *    this struct to reload the registers for your thread (privileged registers
334 *    are not loaded of course). The vregs struct is of course terribly machine
335 *    dependent.
336 *    Note that in BeOS the vregs argument was passed by value, not by pointer.
337 *    While Haiku retains binary compability with code compiled for BeOS, code
338 *    built under Haiku must use the pointer argument.
339 */
340
341/*
342 * the vregs struct:
343 *
344 * signal handlers get this as the last argument
345 */
346typedef struct vregs vregs;
347	/* BeOS extension */
348
349
350/* include architecture specific definitions */
351#include __HAIKU_ARCH_HEADER(signal.h)
352
353
354typedef struct vregs mcontext_t;
355
356typedef struct __ucontext_t {
357	struct __ucontext_t*	uc_link;
358	sigset_t				uc_sigmask;
359	stack_t					uc_stack;
360	mcontext_t				uc_mcontext;
361} ucontext_t;
362
363
364#endif /* _SIGNAL_H_ */
365