summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/signal.h
blob: 1818665b45db010e4a0a55dfa1fc31ca41b63064 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 * Copyright 2015, Joyent, Inc.
 */

/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved	*/

/*
 * University Copyright- Copyright (c) 1982, 1986, 1988
 * The Regents of the University of California
 * All Rights Reserved
 *
 * University Acknowledgment- Portions of this document are derived from
 * software developed by the University of California, Berkeley, and its
 * contributors.
 */

#ifndef _SYS_SIGNAL_H
#define	_SYS_SIGNAL_H

#include <sys/feature_tests.h>
#include <sys/iso/signal_iso.h>

#ifdef	__cplusplus
extern "C" {
#endif

#if defined(__EXTENSIONS__) || defined(_KERNEL) || !defined(_STRICT_STDC) || \
	defined(__XOPEN_OR_POSIX)

#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
	(_POSIX_C_SOURCE > 2) || defined(_XPG4_2)
/*
 * We need <sys/siginfo.h> for the declaration of siginfo_t.
 */
#include <sys/siginfo.h>
#endif

/* Duplicated in <sys/ucontext.h> as a result of XPG4v2 requirements */
#ifndef	_SIGSET_T
#define	_SIGSET_T
typedef struct {		/* signal set type */
	unsigned int	__sigbits[4];
} sigset_t;
#endif	/* _SIGSET_T */

typedef	struct {
	unsigned int	__sigbits[3];
} k_sigset_t;

/*
 * The signal handler routine can have either one or three arguments.
 * Existing C code has used either form so not specifing the arguments
 * neatly finesses the problem.  C++ doesn't accept this.  To C++
 * "(*sa_handler)()" indicates a routine with no arguments (ANSI C would
 * specify this as "(*sa_handler)(void)").  One or the other form must be
 * used for C++ and the only logical choice is "(*sa_handler)(int)" to allow
 * the SIG_* defines to work.  "(*sa_sigaction)(int, siginfo_t *, void *)"
 * can be used for the three argument form.
 */

/*
 * Note: storage overlap by sa_handler and sa_sigaction
 */
struct sigaction {
	int sa_flags;
	union {
#ifdef	__cplusplus
		void (*_handler)(int);
#else
		void (*_handler)();
#endif
#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
	(_POSIX_C_SOURCE > 2) || defined(_XPG4_2)
		void (*_sigaction)(int, siginfo_t *, void *);
#endif
	}	_funcptr;
	sigset_t sa_mask;
#ifndef _LP64
	int sa_resv[2];
#endif
};
#define	sa_handler	_funcptr._handler
#define	sa_sigaction	_funcptr._sigaction

#if defined(_SYSCALL32)

/* Kernel view of the ILP32 user sigaction structure */

struct sigaction32 {
	int32_t		sa_flags;
	union {
		caddr32_t	_handler;
		caddr32_t	_sigaction;
	}	_funcptr;
	sigset_t	sa_mask;
	int32_t		sa_resv[2];
};

#endif	/* _SYSCALL32 */

/* this is only valid for SIGCLD */
#define	SA_NOCLDSTOP	0x00020000	/* don't send job control SIGCLD's */
#endif

#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(_POSIX_C_SOURCE)) || \
	defined(_XPG4_2)

			/* non-conformant ANSI compilation	*/

/* definitions for the sa_flags field */
#define	SA_ONSTACK	0x00000001
#define	SA_RESETHAND	0x00000002
#define	SA_RESTART	0x00000004
#endif

#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(_POSIX_C_SOURCE)) || \
	(_POSIX_C_SOURCE > 2) || defined(_XPG4_2)
#define	SA_SIGINFO	0x00000008
#endif

#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
	defined(_XPG4_2)
#define	SA_NODEFER	0x00000010

/* this is only valid for SIGCLD */
#define	SA_NOCLDWAIT	0x00010000	/* don't save zombie children	 */

#if defined(__EXTENSIONS__) || !defined(_XPG4_2)
/*
 * use of these symbols by applications is injurious
 *	to binary compatibility
 */
#define	NSIG	75	/* valid signals range from 1 to NSIG-1 */
#define	MAXSIG	74	/* size of u_signal[], NSIG-1 <= MAXSIG */
#endif /* defined(__EXTENSIONS__) || !defined(_XPG4_2) */

#define	MINSIGSTKSZ	2048
#define	SIGSTKSZ	8192

#define	SS_ONSTACK	0x00000001
#define	SS_DISABLE	0x00000002

/* Duplicated in <sys/ucontext.h> as a result of XPG4v2 requirements. */
#ifndef	_STACK_T
#define	_STACK_T
#if defined(__EXTENSIONS__) || !defined(_XPG4_2)
typedef struct sigaltstack {
#else
typedef struct {
#endif
	void	*ss_sp;
	size_t	ss_size;
	int	ss_flags;
} stack_t;

#if defined(_SYSCALL32)

/* Kernel view of the ILP32 user sigaltstack structure */

typedef struct sigaltstack32 {
	caddr32_t	ss_sp;
	size32_t	ss_size;
	int32_t		ss_flags;
} stack32_t;

#endif /* _SYSCALL32 */

#endif /* _STACK_T */

#endif /* defined(__EXTENSIONS__) || defined(_KERNEL) ... */

#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX))

/* signotify id used only by libc for mq_notify()/aio_notify() */
typedef struct signotify_id {		/* signotify id struct		*/
	pid_t	sn_pid;			/* pid of proc to be notified	*/
	int	sn_index;		/* index in preallocated pool	*/
	int	sn_pad;			/* reserved			*/
} signotify_id_t;

#if defined(_SYSCALL32)

/* Kernel view of the ILP32 user signotify_id structure */

typedef struct signotify32_id {
	pid32_t	sn_pid;			/* pid of proc to be notified */
	int32_t	sn_index;		/* index in preallocated pool */
	int32_t	sn_pad;			/* reserved */
} signotify32_id_t;

#endif	/* _SYSCALL32 */

/* Command codes for sig_notify call */

#define	SN_PROC		1		/* queue signotify for process	*/
#define	SN_CANCEL	2		/* cancel the queued signotify	*/
#define	SN_SEND		3		/* send the notified signal	*/

#endif /* defined(__EXTENSIONS__) || defined(_KERNEL) ... */

/* Added as per XPG4v2 */
#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
	defined(_XPG4_2)
struct sigstack {
	void	*ss_sp;
	int	ss_onstack;
};
#endif /* defined(__EXTENSIONS__) || defined(_KERNEL) ... */

/*
 * For definition of ucontext_t; must follow struct definition
 * for  sigset_t
 */
#if defined(_XPG4_2)
#include <sys/ucontext.h>
#endif /* defined(_XPG4_2) */

#ifdef _KERNEL
#include <sys/t_lock.h>

extern const k_sigset_t nullsmask;	/* a null signal mask */
extern const k_sigset_t fillset;	/* all signals, guaranteed contiguous */
extern const k_sigset_t cantmask;	/* cannot be caught or ignored */
extern const k_sigset_t cantreset;	/* cannot be reset after catching */
extern const k_sigset_t ignoredefault;	/* ignored by default */
extern const k_sigset_t stopdefault;	/* stop by default */
extern const k_sigset_t coredefault;	/* dumps core by default */
extern const k_sigset_t holdvfork;	/* held while doing vfork */

#define	sigmask(n)		((unsigned int)1 << (((n) - 1) & (32 - 1)))
#define	sigword(n)		(((unsigned int)((n) - 1))>>5)

#if ((MAXSIG > (2 * 32)) && (MAXSIG <= (3 * 32)))
#define	FILLSET0	0xffffffffu
#define	FILLSET1	0xffffffffu
#define	FILLSET2	((1u << (MAXSIG - 64)) - 1)
#else
#error "fix me: MAXSIG out of bounds"
#endif

#define	CANTMASK0	(sigmask(SIGKILL)|sigmask(SIGSTOP))
#define	CANTMASK1	0
#define	CANTMASK2	0

#define	sigemptyset(s)		(*(s) = nullsmask)
#define	sigfillset(s)		(*(s) = fillset)
#define	sigaddset(s, n)		((s)->__sigbits[sigword(n)] |= sigmask(n))
#define	sigdelset(s, n)		((s)->__sigbits[sigword(n)] &= ~sigmask(n))
#define	sigismember(s, n)	(sigmask(n) & (s)->__sigbits[sigword(n)])
#define	sigisempty(s)		(!((s)->__sigbits[0] | (s)->__sigbits[1] | \
				(s)->__sigbits[2]))
#define	sigutok(us, ks)		\
	((ks)->__sigbits[0] = (us)->__sigbits[0] & (FILLSET0 & ~CANTMASK0), \
	(ks)->__sigbits[1] = (us)->__sigbits[1] & (FILLSET1 & ~CANTMASK1), \
	(ks)->__sigbits[2] = (us)->__sigbits[2] & (FILLSET2 & ~CANTMASK2))
#define	sigktou(ks, us)		((us)->__sigbits[0] = (ks)->__sigbits[0], \
				(us)->__sigbits[1] = (ks)->__sigbits[1], \
				(us)->__sigbits[2] = (ks)->__sigbits[2], \
				(us)->__sigbits[3] = 0)
typedef struct {
	int	sig;				/* signal no.		*/
	int	perm;				/* flag for EPERM	*/
	int	checkperm;			/* check perm or not	*/
	int	sicode;				/* has siginfo.si_code	*/
	union sigval value;			/* user specified value	*/
} sigsend_t;

typedef struct {
	sigqueue_t	sn_sigq;	/* sigq struct for notification */
	u_longlong_t	sn_snid;	/* unique id for notification	*/
} signotifyq_t;

typedef struct sigqhdr {		/* sigqueue pool header		*/
	sigqueue_t	*sqb_free;	/* free sigq struct list	*/
	int		sqb_count;	/* sigq free count		*/
	uint_t		sqb_maxcount;	/* sigq max free count		*/
	size_t		sqb_size;	/* size of header+free structs	*/
	uchar_t		sqb_pexited;	/* process has exited		*/
	uint_t		sqb_sent;	/* number of sigq sent		*/
	kcondvar_t	sqb_cv;		/* waiting for a sigq struct	*/
	kmutex_t	sqb_lock;	/* lock for sigq pool		*/
} sigqhdr_t;

#define	_SIGQUEUE_SIZE_BASIC		128	/* basic limit */
#define	_SIGQUEUE_SIZE_PRIVILEGED	512	/* privileged limit */

#define	_SIGNOTIFY_MAX	32

extern	void	setsigact(int, void (*)(int), const k_sigset_t *, int);
extern	void	sigorset(k_sigset_t *, const k_sigset_t *);
extern	void	sigandset(k_sigset_t *, const k_sigset_t *);
extern	void	sigdiffset(k_sigset_t *, const k_sigset_t *);
extern	void	sigintr(k_sigset_t *, int);
extern	void	sigunintr(k_sigset_t *);
extern	void	sigreplace(k_sigset_t *, k_sigset_t *);

extern	int	kill(pid_t, int);

#endif /* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_SIGNAL_H */