Commit | Line | Data |
---|---|---|
984263bc MD |
1 | /* |
2 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 | |
3 | * The Regents of the University of California. All rights reserved. | |
4 | * (c) UNIX System Laboratories, Inc. | |
5 | * All or some portions of this file are derived from material licensed | |
6 | * to the University of California by American Telephone and Telegraph | |
7 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | |
8 | * the permission of UNIX System Laboratories, Inc. | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. All advertising materials mentioning features or use of this software | |
19 | * must display the following acknowledgement: | |
20 | * This product includes software developed by the University of | |
21 | * California, Berkeley and its contributors. | |
22 | * 4. Neither the name of the University nor the names of its contributors | |
23 | * may be used to endorse or promote products derived from this software | |
24 | * without specific prior written permission. | |
25 | * | |
26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
36 | * SUCH DAMAGE. | |
37 | * | |
38 | * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 | |
39 | * $FreeBSD: src/sys/kern/kern_sig.c,v 1.72.2.17 2003/05/16 16:34:34 obrien Exp $ | |
a72187e9 | 40 | * $DragonFly: src/sys/kern/kern_sig.c,v 1.13 2003/07/25 05:26:50 dillon Exp $ |
984263bc MD |
41 | */ |
42 | ||
43 | #include "opt_compat.h" | |
44 | #include "opt_ktrace.h" | |
45 | ||
46 | #include <sys/param.h> | |
dadab5e9 | 47 | #include <sys/systm.h> |
984263bc MD |
48 | #include <sys/kernel.h> |
49 | #include <sys/sysproto.h> | |
50 | #include <sys/signalvar.h> | |
51 | #include <sys/resourcevar.h> | |
984263bc MD |
52 | #include <sys/vnode.h> |
53 | #include <sys/event.h> | |
54 | #include <sys/proc.h> | |
dadab5e9 | 55 | #include <sys/namei.h> |
984263bc MD |
56 | #include <sys/pioctl.h> |
57 | #include <sys/systm.h> | |
58 | #include <sys/acct.h> | |
59 | #include <sys/fcntl.h> | |
60 | #include <sys/wait.h> | |
61 | #include <sys/ktrace.h> | |
62 | #include <sys/syslog.h> | |
63 | #include <sys/stat.h> | |
64 | #include <sys/sysent.h> | |
65 | #include <sys/sysctl.h> | |
66 | #include <sys/malloc.h> | |
67 | #include <sys/unistd.h> | |
68 | ||
69 | ||
70 | #include <machine/ipl.h> | |
71 | #include <machine/cpu.h> | |
72 | #include <machine/smp.h> | |
73 | ||
74 | #define ONSIG 32 /* NSIG for osig* syscalls. XXX. */ | |
75 | ||
76 | static int coredump __P((struct proc *)); | |
41c20dac | 77 | static int do_sigaction __P((int sig, struct sigaction *act, |
984263bc | 78 | struct sigaction *oact, int old)); |
41c20dac | 79 | static int do_sigprocmask __P((int how, sigset_t *set, |
984263bc MD |
80 | sigset_t *oset, int old)); |
81 | static char *expand_name __P((const char *, uid_t, pid_t)); | |
41c20dac | 82 | static int killpg1 __P((int sig, int pgid, int all)); |
984263bc MD |
83 | static int sig_ffs __P((sigset_t *set)); |
84 | static int sigprop __P((int sig)); | |
85 | static void stop __P((struct proc *)); | |
cb973d15 MD |
86 | #ifdef SMP |
87 | static void signotify_remote(void *arg); | |
88 | #endif | |
984263bc MD |
89 | |
90 | static int filt_sigattach(struct knote *kn); | |
91 | static void filt_sigdetach(struct knote *kn); | |
92 | static int filt_signal(struct knote *kn, long hint); | |
93 | ||
94 | struct filterops sig_filtops = | |
95 | { 0, filt_sigattach, filt_sigdetach, filt_signal }; | |
96 | ||
97 | static int kern_logsigexit = 1; | |
98 | SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, | |
99 | &kern_logsigexit, 0, | |
100 | "Log processes quitting on abnormal signals to syslog(3)"); | |
101 | ||
102 | /* | |
103 | * Can process p, with pcred pc, send the signal sig to process q? | |
104 | */ | |
41c20dac MD |
105 | #define CANSIGNAL(q, sig) \ |
106 | (!p_trespass(curproc->p_ucred, (q)->p_ucred) || \ | |
107 | ((sig) == SIGCONT && (q)->p_session == curproc->p_session)) | |
984263bc MD |
108 | |
109 | /* | |
110 | * Policy -- Can real uid ruid with ucred uc send a signal to process q? | |
111 | */ | |
112 | #define CANSIGIO(ruid, uc, q) \ | |
113 | ((uc)->cr_uid == 0 || \ | |
41c20dac MD |
114 | (ruid) == (q)->p_ucred->cr_ruid || \ |
115 | (uc)->cr_uid == (q)->p_ucred->cr_ruid || \ | |
984263bc MD |
116 | (ruid) == (q)->p_ucred->cr_uid || \ |
117 | (uc)->cr_uid == (q)->p_ucred->cr_uid) | |
118 | ||
119 | int sugid_coredump; | |
120 | SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, | |
121 | &sugid_coredump, 0, "Enable coredumping set user/group ID processes"); | |
122 | ||
123 | static int do_coredump = 1; | |
124 | SYSCTL_INT(_kern, OID_AUTO, coredump, CTLFLAG_RW, | |
125 | &do_coredump, 0, "Enable/Disable coredumps"); | |
126 | ||
127 | /* | |
128 | * Signal properties and actions. | |
129 | * The array below categorizes the signals and their default actions | |
130 | * according to the following properties: | |
131 | */ | |
132 | #define SA_KILL 0x01 /* terminates process by default */ | |
133 | #define SA_CORE 0x02 /* ditto and coredumps */ | |
134 | #define SA_STOP 0x04 /* suspend process */ | |
135 | #define SA_TTYSTOP 0x08 /* ditto, from tty */ | |
136 | #define SA_IGNORE 0x10 /* ignore by default */ | |
137 | #define SA_CONT 0x20 /* continue if suspended */ | |
138 | #define SA_CANTMASK 0x40 /* non-maskable, catchable */ | |
139 | ||
140 | static int sigproptbl[NSIG] = { | |
141 | SA_KILL, /* SIGHUP */ | |
142 | SA_KILL, /* SIGINT */ | |
143 | SA_KILL|SA_CORE, /* SIGQUIT */ | |
144 | SA_KILL|SA_CORE, /* SIGILL */ | |
145 | SA_KILL|SA_CORE, /* SIGTRAP */ | |
146 | SA_KILL|SA_CORE, /* SIGABRT */ | |
147 | SA_KILL|SA_CORE, /* SIGEMT */ | |
148 | SA_KILL|SA_CORE, /* SIGFPE */ | |
149 | SA_KILL, /* SIGKILL */ | |
150 | SA_KILL|SA_CORE, /* SIGBUS */ | |
151 | SA_KILL|SA_CORE, /* SIGSEGV */ | |
152 | SA_KILL|SA_CORE, /* SIGSYS */ | |
153 | SA_KILL, /* SIGPIPE */ | |
154 | SA_KILL, /* SIGALRM */ | |
155 | SA_KILL, /* SIGTERM */ | |
156 | SA_IGNORE, /* SIGURG */ | |
157 | SA_STOP, /* SIGSTOP */ | |
158 | SA_STOP|SA_TTYSTOP, /* SIGTSTP */ | |
159 | SA_IGNORE|SA_CONT, /* SIGCONT */ | |
160 | SA_IGNORE, /* SIGCHLD */ | |
161 | SA_STOP|SA_TTYSTOP, /* SIGTTIN */ | |
162 | SA_STOP|SA_TTYSTOP, /* SIGTTOU */ | |
163 | SA_IGNORE, /* SIGIO */ | |
164 | SA_KILL, /* SIGXCPU */ | |
165 | SA_KILL, /* SIGXFSZ */ | |
166 | SA_KILL, /* SIGVTALRM */ | |
167 | SA_KILL, /* SIGPROF */ | |
168 | SA_IGNORE, /* SIGWINCH */ | |
169 | SA_IGNORE, /* SIGINFO */ | |
170 | SA_KILL, /* SIGUSR1 */ | |
171 | SA_KILL, /* SIGUSR2 */ | |
172 | }; | |
173 | ||
174 | static __inline int | |
175 | sigprop(int sig) | |
176 | { | |
177 | ||
178 | if (sig > 0 && sig < NSIG) | |
179 | return (sigproptbl[_SIG_IDX(sig)]); | |
180 | return (0); | |
181 | } | |
182 | ||
183 | static __inline int | |
184 | sig_ffs(sigset_t *set) | |
185 | { | |
186 | int i; | |
187 | ||
188 | for (i = 0; i < _SIG_WORDS; i++) | |
189 | if (set->__bits[i]) | |
190 | return (ffs(set->__bits[i]) + (i * 32)); | |
191 | return (0); | |
192 | } | |
193 | ||
194 | /* | |
195 | * do_sigaction | |
196 | * sigaction | |
197 | * osigaction | |
198 | */ | |
199 | static int | |
41c20dac | 200 | do_sigaction(int sig, struct sigaction *act, struct sigaction *oact, int old) |
984263bc | 201 | { |
41c20dac MD |
202 | struct proc *p = curproc; |
203 | struct sigacts *ps = p->p_sigacts; | |
984263bc MD |
204 | |
205 | if (sig <= 0 || sig > _SIG_MAXSIG) | |
206 | return (EINVAL); | |
207 | ||
208 | if (oact) { | |
209 | oact->sa_handler = ps->ps_sigact[_SIG_IDX(sig)]; | |
210 | oact->sa_mask = ps->ps_catchmask[_SIG_IDX(sig)]; | |
211 | oact->sa_flags = 0; | |
212 | if (SIGISMEMBER(ps->ps_sigonstack, sig)) | |
213 | oact->sa_flags |= SA_ONSTACK; | |
214 | if (!SIGISMEMBER(ps->ps_sigintr, sig)) | |
215 | oact->sa_flags |= SA_RESTART; | |
216 | if (SIGISMEMBER(ps->ps_sigreset, sig)) | |
217 | oact->sa_flags |= SA_RESETHAND; | |
218 | if (SIGISMEMBER(ps->ps_signodefer, sig)) | |
219 | oact->sa_flags |= SA_NODEFER; | |
220 | if (SIGISMEMBER(ps->ps_siginfo, sig)) | |
221 | oact->sa_flags |= SA_SIGINFO; | |
222 | if (sig == SIGCHLD && p->p_procsig->ps_flag & PS_NOCLDSTOP) | |
223 | oact->sa_flags |= SA_NOCLDSTOP; | |
224 | if (sig == SIGCHLD && p->p_procsig->ps_flag & PS_NOCLDWAIT) | |
225 | oact->sa_flags |= SA_NOCLDWAIT; | |
226 | } | |
227 | if (act) { | |
228 | if ((sig == SIGKILL || sig == SIGSTOP) && | |
229 | act->sa_handler != SIG_DFL) | |
230 | return (EINVAL); | |
231 | ||
232 | /* | |
233 | * Change setting atomically. | |
234 | */ | |
235 | (void) splhigh(); | |
236 | ||
237 | ps->ps_catchmask[_SIG_IDX(sig)] = act->sa_mask; | |
238 | SIG_CANTMASK(ps->ps_catchmask[_SIG_IDX(sig)]); | |
239 | if (act->sa_flags & SA_SIGINFO) { | |
240 | ps->ps_sigact[_SIG_IDX(sig)] = | |
241 | (__sighandler_t *)act->sa_sigaction; | |
242 | SIGADDSET(ps->ps_siginfo, sig); | |
243 | } else { | |
244 | ps->ps_sigact[_SIG_IDX(sig)] = act->sa_handler; | |
245 | SIGDELSET(ps->ps_siginfo, sig); | |
246 | } | |
247 | if (!(act->sa_flags & SA_RESTART)) | |
248 | SIGADDSET(ps->ps_sigintr, sig); | |
249 | else | |
250 | SIGDELSET(ps->ps_sigintr, sig); | |
251 | if (act->sa_flags & SA_ONSTACK) | |
252 | SIGADDSET(ps->ps_sigonstack, sig); | |
253 | else | |
254 | SIGDELSET(ps->ps_sigonstack, sig); | |
255 | if (act->sa_flags & SA_RESETHAND) | |
256 | SIGADDSET(ps->ps_sigreset, sig); | |
257 | else | |
258 | SIGDELSET(ps->ps_sigreset, sig); | |
259 | if (act->sa_flags & SA_NODEFER) | |
260 | SIGADDSET(ps->ps_signodefer, sig); | |
261 | else | |
262 | SIGDELSET(ps->ps_signodefer, sig); | |
263 | #ifdef COMPAT_SUNOS | |
264 | if (act->sa_flags & SA_USERTRAMP) | |
265 | SIGADDSET(ps->ps_usertramp, sig); | |
266 | else | |
267 | SIGDELSET(ps->ps_usertramp, seg); | |
268 | #endif | |
269 | if (sig == SIGCHLD) { | |
270 | if (act->sa_flags & SA_NOCLDSTOP) | |
271 | p->p_procsig->ps_flag |= PS_NOCLDSTOP; | |
272 | else | |
273 | p->p_procsig->ps_flag &= ~PS_NOCLDSTOP; | |
274 | if (act->sa_flags & SA_NOCLDWAIT) { | |
275 | /* | |
276 | * Paranoia: since SA_NOCLDWAIT is implemented | |
277 | * by reparenting the dying child to PID 1 (and | |
278 | * trust it to reap the zombie), PID 1 itself | |
279 | * is forbidden to set SA_NOCLDWAIT. | |
280 | */ | |
281 | if (p->p_pid == 1) | |
282 | p->p_procsig->ps_flag &= ~PS_NOCLDWAIT; | |
283 | else | |
284 | p->p_procsig->ps_flag |= PS_NOCLDWAIT; | |
285 | } else | |
286 | p->p_procsig->ps_flag &= ~PS_NOCLDWAIT; | |
287 | } | |
288 | /* | |
289 | * Set bit in p_sigignore for signals that are set to SIG_IGN, | |
290 | * and for signals set to SIG_DFL where the default is to | |
291 | * ignore. However, don't put SIGCONT in p_sigignore, as we | |
292 | * have to restart the process. | |
293 | */ | |
294 | if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN || | |
295 | (sigprop(sig) & SA_IGNORE && | |
296 | ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)) { | |
297 | /* never to be seen again */ | |
298 | SIGDELSET(p->p_siglist, sig); | |
299 | if (sig != SIGCONT) | |
300 | /* easier in psignal */ | |
301 | SIGADDSET(p->p_sigignore, sig); | |
302 | SIGDELSET(p->p_sigcatch, sig); | |
303 | } else { | |
304 | SIGDELSET(p->p_sigignore, sig); | |
305 | if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL) | |
306 | SIGDELSET(p->p_sigcatch, sig); | |
307 | else | |
308 | SIGADDSET(p->p_sigcatch, sig); | |
309 | } | |
310 | if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN || | |
311 | ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL || !old) | |
312 | SIGDELSET(ps->ps_osigset, sig); | |
313 | else | |
314 | SIGADDSET(ps->ps_osigset, sig); | |
315 | ||
316 | (void) spl0(); | |
317 | } | |
318 | return (0); | |
319 | } | |
320 | ||
984263bc MD |
321 | /* ARGSUSED */ |
322 | int | |
41c20dac | 323 | sigaction(struct sigaction_args *uap) |
984263bc MD |
324 | { |
325 | struct sigaction act, oact; | |
326 | register struct sigaction *actp, *oactp; | |
327 | int error; | |
328 | ||
329 | actp = (uap->act != NULL) ? &act : NULL; | |
330 | oactp = (uap->oact != NULL) ? &oact : NULL; | |
331 | if (actp) { | |
332 | error = copyin(uap->act, actp, sizeof(act)); | |
333 | if (error) | |
334 | return (error); | |
335 | } | |
41c20dac | 336 | error = do_sigaction(uap->sig, actp, oactp, 0); |
984263bc MD |
337 | if (oactp && !error) { |
338 | error = copyout(oactp, uap->oact, sizeof(oact)); | |
339 | } | |
340 | return (error); | |
341 | } | |
342 | ||
984263bc MD |
343 | /* ARGSUSED */ |
344 | int | |
41c20dac | 345 | osigaction(struct osigaction_args *uap) |
984263bc MD |
346 | { |
347 | struct osigaction sa; | |
348 | struct sigaction nsa, osa; | |
349 | register struct sigaction *nsap, *osap; | |
350 | int error; | |
351 | ||
352 | if (uap->signum <= 0 || uap->signum >= ONSIG) | |
353 | return (EINVAL); | |
354 | nsap = (uap->nsa != NULL) ? &nsa : NULL; | |
355 | osap = (uap->osa != NULL) ? &osa : NULL; | |
356 | if (nsap) { | |
357 | error = copyin(uap->nsa, &sa, sizeof(sa)); | |
358 | if (error) | |
359 | return (error); | |
360 | nsap->sa_handler = sa.sa_handler; | |
361 | nsap->sa_flags = sa.sa_flags; | |
362 | OSIG2SIG(sa.sa_mask, nsap->sa_mask); | |
363 | } | |
41c20dac | 364 | error = do_sigaction(uap->signum, nsap, osap, 1); |
984263bc MD |
365 | if (osap && !error) { |
366 | sa.sa_handler = osap->sa_handler; | |
367 | sa.sa_flags = osap->sa_flags; | |
368 | SIG2OSIG(osap->sa_mask, sa.sa_mask); | |
369 | error = copyout(&sa, uap->osa, sizeof(sa)); | |
370 | } | |
371 | return (error); | |
372 | } | |
373 | ||
374 | /* | |
375 | * Initialize signal state for process 0; | |
376 | * set to ignore signals that are ignored by default. | |
377 | */ | |
378 | void | |
379 | siginit(p) | |
380 | struct proc *p; | |
381 | { | |
382 | register int i; | |
383 | ||
384 | for (i = 1; i <= NSIG; i++) | |
385 | if (sigprop(i) & SA_IGNORE && i != SIGCONT) | |
386 | SIGADDSET(p->p_sigignore, i); | |
387 | } | |
388 | ||
389 | /* | |
390 | * Reset signals for an exec of the specified process. | |
391 | */ | |
392 | void | |
393 | execsigs(p) | |
394 | register struct proc *p; | |
395 | { | |
396 | register struct sigacts *ps = p->p_sigacts; | |
397 | register int sig; | |
398 | ||
399 | /* | |
400 | * Reset caught signals. Held signals remain held | |
401 | * through p_sigmask (unless they were caught, | |
402 | * and are now ignored by default). | |
403 | */ | |
404 | while (SIGNOTEMPTY(p->p_sigcatch)) { | |
405 | sig = sig_ffs(&p->p_sigcatch); | |
406 | SIGDELSET(p->p_sigcatch, sig); | |
407 | if (sigprop(sig) & SA_IGNORE) { | |
408 | if (sig != SIGCONT) | |
409 | SIGADDSET(p->p_sigignore, sig); | |
410 | SIGDELSET(p->p_siglist, sig); | |
411 | } | |
412 | ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; | |
413 | } | |
414 | /* | |
415 | * Reset stack state to the user stack. | |
416 | * Clear set of signals caught on the signal stack. | |
417 | */ | |
418 | p->p_sigstk.ss_flags = SS_DISABLE; | |
419 | p->p_sigstk.ss_size = 0; | |
420 | p->p_sigstk.ss_sp = 0; | |
421 | p->p_flag &= ~P_ALTSTACK; | |
422 | /* | |
423 | * Reset no zombies if child dies flag as Solaris does. | |
424 | */ | |
425 | p->p_procsig->ps_flag &= ~PS_NOCLDWAIT; | |
426 | } | |
427 | ||
428 | /* | |
429 | * do_sigprocmask() - MP SAFE ONLY IF p == curproc | |
430 | * | |
431 | * Manipulate signal mask. This routine is MP SAFE *ONLY* if | |
432 | * p == curproc. Also remember that in order to remain MP SAFE | |
433 | * no spl*() calls may be made. | |
434 | */ | |
435 | static int | |
41c20dac | 436 | do_sigprocmask(int how, sigset_t *set, sigset_t *oset, int old) |
984263bc | 437 | { |
41c20dac | 438 | struct proc *p = curproc; |
984263bc MD |
439 | int error; |
440 | ||
441 | if (oset != NULL) | |
442 | *oset = p->p_sigmask; | |
443 | ||
444 | error = 0; | |
445 | if (set != NULL) { | |
446 | switch (how) { | |
447 | case SIG_BLOCK: | |
448 | SIG_CANTMASK(*set); | |
449 | SIGSETOR(p->p_sigmask, *set); | |
450 | break; | |
451 | case SIG_UNBLOCK: | |
452 | SIGSETNAND(p->p_sigmask, *set); | |
453 | break; | |
454 | case SIG_SETMASK: | |
455 | SIG_CANTMASK(*set); | |
456 | if (old) | |
457 | SIGSETLO(p->p_sigmask, *set); | |
458 | else | |
459 | p->p_sigmask = *set; | |
460 | break; | |
461 | default: | |
462 | error = EINVAL; | |
463 | break; | |
464 | } | |
465 | } | |
466 | return (error); | |
467 | } | |
468 | ||
469 | /* | |
470 | * sigprocmask() - MP SAFE | |
471 | */ | |
984263bc | 472 | int |
41c20dac | 473 | sigprocmask(struct sigprocmask_args *uap) |
984263bc MD |
474 | { |
475 | sigset_t set, oset; | |
476 | sigset_t *setp, *osetp; | |
477 | int error; | |
478 | ||
479 | setp = (uap->set != NULL) ? &set : NULL; | |
480 | osetp = (uap->oset != NULL) ? &oset : NULL; | |
481 | if (setp) { | |
482 | error = copyin(uap->set, setp, sizeof(set)); | |
483 | if (error) | |
484 | return (error); | |
485 | } | |
41c20dac | 486 | error = do_sigprocmask(uap->how, setp, osetp, 0); |
984263bc MD |
487 | if (osetp && !error) { |
488 | error = copyout(osetp, uap->oset, sizeof(oset)); | |
489 | } | |
490 | return (error); | |
491 | } | |
492 | ||
493 | /* | |
494 | * osigprocmask() - MP SAFE | |
495 | */ | |
984263bc | 496 | int |
41c20dac | 497 | osigprocmask(struct osigprocmask_args *uap) |
984263bc MD |
498 | { |
499 | sigset_t set, oset; | |
500 | int error; | |
501 | ||
502 | OSIG2SIG(uap->mask, set); | |
41c20dac MD |
503 | error = do_sigprocmask(uap->how, &set, &oset, 1); |
504 | SIG2OSIG(oset, curproc->p_retval[0]); | |
984263bc MD |
505 | return (error); |
506 | } | |
507 | ||
984263bc MD |
508 | /* ARGSUSED */ |
509 | int | |
41c20dac | 510 | sigpending(struct sigpending_args *uap) |
984263bc | 511 | { |
41c20dac | 512 | struct proc *p = curproc; |
984263bc MD |
513 | |
514 | return (copyout(&p->p_siglist, uap->set, sizeof(sigset_t))); | |
515 | } | |
516 | ||
984263bc MD |
517 | /* ARGSUSED */ |
518 | int | |
41c20dac | 519 | osigpending(struct osigpending_args *uap) |
984263bc | 520 | { |
41c20dac | 521 | struct proc *p = curproc; |
984263bc MD |
522 | |
523 | SIG2OSIG(p->p_siglist, p->p_retval[0]); | |
524 | return (0); | |
525 | } | |
526 | ||
527 | #if defined(COMPAT_43) || defined(COMPAT_SUNOS) | |
528 | /* | |
529 | * Generalized interface signal handler, 4.3-compatible. | |
530 | */ | |
984263bc MD |
531 | /* ARGSUSED */ |
532 | int | |
41c20dac | 533 | osigvec(struct osigvec_args *uap) |
984263bc MD |
534 | { |
535 | struct sigvec vec; | |
536 | struct sigaction nsa, osa; | |
537 | register struct sigaction *nsap, *osap; | |
538 | int error; | |
539 | ||
540 | if (uap->signum <= 0 || uap->signum >= ONSIG) | |
541 | return (EINVAL); | |
542 | nsap = (uap->nsv != NULL) ? &nsa : NULL; | |
543 | osap = (uap->osv != NULL) ? &osa : NULL; | |
544 | if (nsap) { | |
545 | error = copyin(uap->nsv, &vec, sizeof(vec)); | |
546 | if (error) | |
547 | return (error); | |
548 | nsap->sa_handler = vec.sv_handler; | |
549 | OSIG2SIG(vec.sv_mask, nsap->sa_mask); | |
550 | nsap->sa_flags = vec.sv_flags; | |
551 | nsap->sa_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */ | |
552 | #ifdef COMPAT_SUNOS | |
553 | nsap->sa_flags |= SA_USERTRAMP; | |
554 | #endif | |
555 | } | |
41c20dac | 556 | error = do_sigaction(uap->signum, nsap, osap, 1); |
984263bc MD |
557 | if (osap && !error) { |
558 | vec.sv_handler = osap->sa_handler; | |
559 | SIG2OSIG(osap->sa_mask, vec.sv_mask); | |
560 | vec.sv_flags = osap->sa_flags; | |
561 | vec.sv_flags &= ~SA_NOCLDWAIT; | |
562 | vec.sv_flags ^= SA_RESTART; | |
563 | #ifdef COMPAT_SUNOS | |
564 | vec.sv_flags &= ~SA_NOCLDSTOP; | |
565 | #endif | |
566 | error = copyout(&vec, uap->osv, sizeof(vec)); | |
567 | } | |
568 | return (error); | |
569 | } | |
570 | ||
984263bc | 571 | int |
41c20dac | 572 | osigblock(struct osigblock_args *uap) |
984263bc | 573 | { |
41c20dac | 574 | struct proc *p = curproc; |
984263bc MD |
575 | sigset_t set; |
576 | ||
577 | OSIG2SIG(uap->mask, set); | |
578 | SIG_CANTMASK(set); | |
579 | (void) splhigh(); | |
580 | SIG2OSIG(p->p_sigmask, p->p_retval[0]); | |
581 | SIGSETOR(p->p_sigmask, set); | |
582 | (void) spl0(); | |
583 | return (0); | |
584 | } | |
585 | ||
984263bc | 586 | int |
41c20dac | 587 | osigsetmask(struct osigsetmask_args *uap) |
984263bc | 588 | { |
41c20dac | 589 | struct proc *p = curproc; |
984263bc MD |
590 | sigset_t set; |
591 | ||
592 | OSIG2SIG(uap->mask, set); | |
593 | SIG_CANTMASK(set); | |
594 | (void) splhigh(); | |
595 | SIG2OSIG(p->p_sigmask, p->p_retval[0]); | |
596 | SIGSETLO(p->p_sigmask, set); | |
597 | (void) spl0(); | |
598 | return (0); | |
599 | } | |
600 | #endif /* COMPAT_43 || COMPAT_SUNOS */ | |
601 | ||
602 | /* | |
603 | * Suspend process until signal, providing mask to be set | |
604 | * in the meantime. Note nonstandard calling convention: | |
605 | * libc stub passes mask, not pointer, to save a copyin. | |
606 | */ | |
984263bc MD |
607 | /* ARGSUSED */ |
608 | int | |
41c20dac | 609 | sigsuspend(struct sigsuspend_args *uap) |
984263bc | 610 | { |
41c20dac | 611 | struct proc *p = curproc; |
984263bc | 612 | sigset_t mask; |
41c20dac | 613 | struct sigacts *ps = p->p_sigacts; |
984263bc MD |
614 | int error; |
615 | ||
616 | error = copyin(uap->sigmask, &mask, sizeof(mask)); | |
617 | if (error) | |
618 | return (error); | |
619 | ||
620 | /* | |
621 | * When returning from sigsuspend, we want | |
622 | * the old mask to be restored after the | |
623 | * signal handler has finished. Thus, we | |
624 | * save it here and mark the sigacts structure | |
625 | * to indicate this. | |
626 | */ | |
627 | p->p_oldsigmask = p->p_sigmask; | |
628 | p->p_flag |= P_OLDMASK; | |
629 | ||
630 | SIG_CANTMASK(mask); | |
631 | p->p_sigmask = mask; | |
377d4740 | 632 | while (tsleep((caddr_t) ps, PCATCH, "pause", 0) == 0) |
984263bc MD |
633 | /* void */; |
634 | /* always return EINTR rather than ERESTART... */ | |
635 | return (EINTR); | |
636 | } | |
637 | ||
984263bc MD |
638 | /* ARGSUSED */ |
639 | int | |
41c20dac | 640 | osigsuspend(struct osigsuspend_args *uap) |
984263bc MD |
641 | { |
642 | sigset_t mask; | |
41c20dac MD |
643 | struct proc *p = curproc; |
644 | struct sigacts *ps = p->p_sigacts; | |
984263bc MD |
645 | |
646 | p->p_oldsigmask = p->p_sigmask; | |
647 | p->p_flag |= P_OLDMASK; | |
648 | OSIG2SIG(uap->mask, mask); | |
649 | SIG_CANTMASK(mask); | |
650 | SIGSETLO(p->p_sigmask, mask); | |
377d4740 | 651 | while (tsleep((caddr_t) ps, PCATCH, "opause", 0) == 0) |
984263bc MD |
652 | /* void */; |
653 | /* always return EINTR rather than ERESTART... */ | |
654 | return (EINTR); | |
655 | } | |
656 | ||
657 | #if defined(COMPAT_43) || defined(COMPAT_SUNOS) | |
984263bc MD |
658 | /* ARGSUSED */ |
659 | int | |
41c20dac | 660 | osigstack(struct osigstack_args *uap) |
984263bc | 661 | { |
41c20dac | 662 | struct proc *p = curproc; |
984263bc MD |
663 | struct sigstack ss; |
664 | int error = 0; | |
665 | ||
666 | ss.ss_sp = p->p_sigstk.ss_sp; | |
667 | ss.ss_onstack = p->p_sigstk.ss_flags & SS_ONSTACK; | |
668 | if (uap->oss && (error = copyout(&ss, uap->oss, | |
669 | sizeof(struct sigstack)))) | |
670 | return (error); | |
671 | if (uap->nss && (error = copyin(uap->nss, &ss, sizeof(ss))) == 0) { | |
672 | p->p_sigstk.ss_sp = ss.ss_sp; | |
673 | p->p_sigstk.ss_size = 0; | |
674 | p->p_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK; | |
675 | p->p_flag |= P_ALTSTACK; | |
676 | } | |
677 | return (error); | |
678 | } | |
679 | #endif /* COMPAT_43 || COMPAT_SUNOS */ | |
680 | ||
984263bc MD |
681 | /* ARGSUSED */ |
682 | int | |
41c20dac | 683 | sigaltstack(struct sigaltstack_args *uap) |
984263bc | 684 | { |
41c20dac | 685 | struct proc *p = curproc; |
984263bc MD |
686 | stack_t ss; |
687 | int error; | |
688 | ||
689 | if ((p->p_flag & P_ALTSTACK) == 0) | |
690 | p->p_sigstk.ss_flags |= SS_DISABLE; | |
691 | if (uap->oss && (error = copyout(&p->p_sigstk, uap->oss, | |
692 | sizeof(stack_t)))) | |
693 | return (error); | |
694 | if (uap->ss == 0) | |
695 | return (0); | |
696 | if ((error = copyin(uap->ss, &ss, sizeof(ss)))) | |
697 | return (error); | |
698 | if (ss.ss_flags & SS_DISABLE) { | |
699 | if (p->p_sigstk.ss_flags & SS_ONSTACK) | |
700 | return (EINVAL); | |
701 | p->p_flag &= ~P_ALTSTACK; | |
702 | p->p_sigstk.ss_flags = ss.ss_flags; | |
703 | return (0); | |
704 | } | |
705 | if (ss.ss_size < p->p_sysent->sv_minsigstksz) | |
706 | return (ENOMEM); | |
707 | p->p_flag |= P_ALTSTACK; | |
708 | p->p_sigstk = ss; | |
709 | return (0); | |
710 | } | |
711 | ||
712 | /* | |
713 | * Common code for kill process group/broadcast kill. | |
714 | * cp is calling process. | |
715 | */ | |
716 | int | |
41c20dac | 717 | killpg1(int sig, int pgid, int all) |
984263bc | 718 | { |
41c20dac MD |
719 | struct proc *cp = curproc; |
720 | struct proc *p; | |
984263bc MD |
721 | struct pgrp *pgrp; |
722 | int nfound = 0; | |
723 | ||
724 | if (all) | |
725 | /* | |
726 | * broadcast | |
727 | */ | |
728 | LIST_FOREACH(p, &allproc, p_list) { | |
729 | if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || | |
41c20dac | 730 | p == cp || !CANSIGNAL(p, sig)) |
984263bc MD |
731 | continue; |
732 | nfound++; | |
733 | if (sig) | |
734 | psignal(p, sig); | |
735 | } | |
736 | else { | |
737 | if (pgid == 0) | |
738 | /* | |
739 | * zero pgid means send to my process group. | |
740 | */ | |
741 | pgrp = cp->p_pgrp; | |
742 | else { | |
743 | pgrp = pgfind(pgid); | |
744 | if (pgrp == NULL) | |
745 | return (ESRCH); | |
746 | } | |
747 | LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { | |
748 | if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || | |
749 | p->p_stat == SZOMB || | |
41c20dac | 750 | !CANSIGNAL(p, sig)) |
984263bc MD |
751 | continue; |
752 | nfound++; | |
753 | if (sig) | |
754 | psignal(p, sig); | |
755 | } | |
756 | } | |
757 | return (nfound ? 0 : ESRCH); | |
758 | } | |
759 | ||
984263bc MD |
760 | /* ARGSUSED */ |
761 | int | |
41c20dac | 762 | kill(struct kill_args *uap) |
984263bc | 763 | { |
41c20dac | 764 | struct proc *p; |
984263bc MD |
765 | |
766 | if ((u_int)uap->signum > _SIG_MAXSIG) | |
767 | return (EINVAL); | |
768 | if (uap->pid > 0) { | |
769 | /* kill single process */ | |
770 | if ((p = pfind(uap->pid)) == NULL) | |
771 | return (ESRCH); | |
41c20dac | 772 | if (!CANSIGNAL(p, uap->signum)) |
984263bc MD |
773 | return (EPERM); |
774 | if (uap->signum) | |
775 | psignal(p, uap->signum); | |
776 | return (0); | |
777 | } | |
778 | switch (uap->pid) { | |
779 | case -1: /* broadcast signal */ | |
41c20dac | 780 | return (killpg1(uap->signum, 0, 1)); |
984263bc | 781 | case 0: /* signal own process group */ |
41c20dac | 782 | return (killpg1(uap->signum, 0, 0)); |
984263bc | 783 | default: /* negative explicit process group */ |
41c20dac | 784 | return (killpg1(uap->signum, -uap->pid, 0)); |
984263bc MD |
785 | } |
786 | /* NOTREACHED */ | |
787 | } | |
788 | ||
789 | #if defined(COMPAT_43) || defined(COMPAT_SUNOS) | |
984263bc MD |
790 | /* ARGSUSED */ |
791 | int | |
41c20dac | 792 | okillpg(struct okillpg_args *uap) |
984263bc | 793 | { |
984263bc MD |
794 | if ((u_int)uap->signum > _SIG_MAXSIG) |
795 | return (EINVAL); | |
41c20dac | 796 | return (killpg1(uap->signum, uap->pgid, 0)); |
984263bc MD |
797 | } |
798 | #endif /* COMPAT_43 || COMPAT_SUNOS */ | |
799 | ||
800 | /* | |
801 | * Send a signal to a process group. | |
802 | */ | |
803 | void | |
41c20dac | 804 | gsignal(int pgid, int sig) |
984263bc MD |
805 | { |
806 | struct pgrp *pgrp; | |
807 | ||
808 | if (pgid && (pgrp = pgfind(pgid))) | |
809 | pgsignal(pgrp, sig, 0); | |
810 | } | |
811 | ||
812 | /* | |
813 | * Send a signal to a process group. If checktty is 1, | |
814 | * limit to members which have a controlling terminal. | |
815 | */ | |
816 | void | |
817 | pgsignal(pgrp, sig, checkctty) | |
818 | struct pgrp *pgrp; | |
819 | int sig, checkctty; | |
820 | { | |
821 | register struct proc *p; | |
822 | ||
823 | if (pgrp) | |
824 | LIST_FOREACH(p, &pgrp->pg_members, p_pglist) | |
825 | if (checkctty == 0 || p->p_flag & P_CONTROLT) | |
826 | psignal(p, sig); | |
827 | } | |
828 | ||
829 | /* | |
830 | * Send a signal caused by a trap to the current process. | |
831 | * If it will be caught immediately, deliver it with correct code. | |
832 | * Otherwise, post it normally. | |
833 | */ | |
834 | void | |
835 | trapsignal(p, sig, code) | |
836 | struct proc *p; | |
837 | register int sig; | |
838 | u_long code; | |
839 | { | |
dadab5e9 | 840 | struct sigacts *ps = p->p_sigacts; |
984263bc MD |
841 | |
842 | if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(p->p_sigcatch, sig) && | |
843 | !SIGISMEMBER(p->p_sigmask, sig)) { | |
844 | p->p_stats->p_ru.ru_nsignals++; | |
845 | #ifdef KTRACE | |
dadab5e9 | 846 | if (KTRPOINT(p->p_thread, KTR_PSIG)) |
984263bc MD |
847 | ktrpsig(p->p_tracep, sig, ps->ps_sigact[_SIG_IDX(sig)], |
848 | &p->p_sigmask, code); | |
849 | #endif | |
850 | (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], sig, | |
851 | &p->p_sigmask, code); | |
852 | SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]); | |
853 | if (!SIGISMEMBER(ps->ps_signodefer, sig)) | |
854 | SIGADDSET(p->p_sigmask, sig); | |
855 | if (SIGISMEMBER(ps->ps_sigreset, sig)) { | |
856 | /* | |
857 | * See do_sigaction() for origin of this code. | |
858 | */ | |
859 | SIGDELSET(p->p_sigcatch, sig); | |
860 | if (sig != SIGCONT && | |
861 | sigprop(sig) & SA_IGNORE) | |
862 | SIGADDSET(p->p_sigignore, sig); | |
863 | ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; | |
864 | } | |
865 | } else { | |
866 | p->p_code = code; /* XXX for core dump/debugger */ | |
867 | p->p_sig = sig; /* XXX to verify code */ | |
868 | psignal(p, sig); | |
869 | } | |
870 | } | |
871 | ||
872 | /* | |
873 | * Send the signal to the process. If the signal has an action, the action | |
874 | * is usually performed by the target process rather than the caller; we add | |
875 | * the signal to the set of pending signals for the process. | |
876 | * | |
877 | * Exceptions: | |
878 | * o When a stop signal is sent to a sleeping process that takes the | |
879 | * default action, the process is stopped without awakening it. | |
880 | * o SIGCONT restarts stopped processes (or puts them back to sleep) | |
881 | * regardless of the signal action (eg, blocked or ignored). | |
882 | * | |
883 | * Other ignored signals are discarded immediately. | |
884 | */ | |
cb973d15 | 885 | |
984263bc MD |
886 | void |
887 | psignal(p, sig) | |
888 | register struct proc *p; | |
889 | register int sig; | |
890 | { | |
cb973d15 MD |
891 | int s, prop; |
892 | sig_t action; | |
984263bc MD |
893 | |
894 | if (sig > _SIG_MAXSIG || sig <= 0) { | |
895 | printf("psignal: signal %d\n", sig); | |
896 | panic("psignal signal number"); | |
897 | } | |
898 | ||
899 | s = splhigh(); | |
900 | KNOTE(&p->p_klist, NOTE_SIGNAL | sig); | |
901 | splx(s); | |
902 | ||
903 | prop = sigprop(sig); | |
904 | ||
905 | /* | |
906 | * If proc is traced, always give parent a chance; | |
907 | * if signal event is tracked by procfs, give *that* | |
908 | * a chance, as well. | |
909 | */ | |
910 | if ((p->p_flag & P_TRACED) || (p->p_stops & S_SIG)) | |
911 | action = SIG_DFL; | |
912 | else { | |
913 | /* | |
914 | * If the signal is being ignored, | |
915 | * then we forget about it immediately. | |
916 | * (Note: we don't set SIGCONT in p_sigignore, | |
917 | * and if it is set to SIG_IGN, | |
918 | * action will be SIG_DFL here.) | |
919 | */ | |
920 | if (SIGISMEMBER(p->p_sigignore, sig) || (p->p_flag & P_WEXIT)) | |
921 | return; | |
922 | if (SIGISMEMBER(p->p_sigmask, sig)) | |
923 | action = SIG_HOLD; | |
924 | else if (SIGISMEMBER(p->p_sigcatch, sig)) | |
925 | action = SIG_CATCH; | |
926 | else | |
927 | action = SIG_DFL; | |
928 | } | |
929 | ||
930 | if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) && | |
931 | (p->p_flag & P_TRACED) == 0) | |
932 | p->p_nice = NZERO; | |
933 | ||
934 | if (prop & SA_CONT) | |
935 | SIG_STOPSIGMASK(p->p_siglist); | |
936 | ||
937 | if (prop & SA_STOP) { | |
938 | /* | |
939 | * If sending a tty stop signal to a member of an orphaned | |
940 | * process group, discard the signal here if the action | |
941 | * is default; don't stop the process below if sleeping, | |
942 | * and don't clear any pending SIGCONT. | |
943 | */ | |
944 | if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 && | |
945 | action == SIG_DFL) | |
946 | return; | |
947 | SIG_CONTSIGMASK(p->p_siglist); | |
948 | } | |
949 | SIGADDSET(p->p_siglist, sig); | |
950 | ||
951 | /* | |
952 | * Defer further processing for signals which are held, | |
953 | * except that stopped processes must be continued by SIGCONT. | |
954 | */ | |
955 | if (action == SIG_HOLD && (!(prop & SA_CONT) || p->p_stat != SSTOP)) | |
956 | return; | |
957 | s = splhigh(); | |
958 | switch (p->p_stat) { | |
959 | ||
960 | case SSLEEP: | |
961 | /* | |
962 | * If process is sleeping uninterruptibly | |
963 | * we can't interrupt the sleep... the signal will | |
964 | * be noticed when the process returns through | |
965 | * trap() or syscall(). | |
966 | */ | |
967 | if ((p->p_flag & P_SINTR) == 0) | |
968 | goto out; | |
969 | /* | |
970 | * Process is sleeping and traced... make it runnable | |
971 | * so it can discover the signal in issignal() and stop | |
972 | * for the parent. | |
973 | */ | |
974 | if (p->p_flag & P_TRACED) | |
975 | goto run; | |
976 | /* | |
977 | * If SIGCONT is default (or ignored) and process is | |
978 | * asleep, we are finished; the process should not | |
979 | * be awakened. | |
980 | */ | |
981 | if ((prop & SA_CONT) && action == SIG_DFL) { | |
982 | SIGDELSET(p->p_siglist, sig); | |
983 | goto out; | |
984 | } | |
985 | /* | |
986 | * When a sleeping process receives a stop | |
987 | * signal, process immediately if possible. | |
988 | * All other (caught or default) signals | |
989 | * cause the process to run. | |
990 | */ | |
991 | if (prop & SA_STOP) { | |
992 | if (action != SIG_DFL) | |
26a0694b | 993 | goto run; |
984263bc MD |
994 | /* |
995 | * If a child holding parent blocked, | |
996 | * stopping could cause deadlock. | |
997 | */ | |
998 | if (p->p_flag & P_PPWAIT) | |
999 | goto out; | |
1000 | SIGDELSET(p->p_siglist, sig); | |
1001 | p->p_xstat = sig; | |
1002 | if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) | |
1003 | psignal(p->p_pptr, SIGCHLD); | |
1004 | stop(p); | |
1005 | goto out; | |
1006 | } else | |
26a0694b | 1007 | goto run; |
984263bc MD |
1008 | /*NOTREACHED*/ |
1009 | ||
1010 | case SSTOP: | |
1011 | /* | |
1012 | * If traced process is already stopped, | |
1013 | * then no further action is necessary. | |
1014 | */ | |
1015 | if (p->p_flag & P_TRACED) | |
1016 | goto out; | |
1017 | ||
1018 | /* | |
1019 | * Kill signal always sets processes running. | |
1020 | */ | |
1021 | if (sig == SIGKILL) | |
26a0694b | 1022 | goto run; |
984263bc MD |
1023 | |
1024 | if (prop & SA_CONT) { | |
1025 | /* | |
1026 | * If SIGCONT is default (or ignored), we continue the | |
1027 | * process but don't leave the signal in p_siglist, as | |
1028 | * it has no further action. If SIGCONT is held, we | |
1029 | * continue the process and leave the signal in | |
1030 | * p_siglist. If the process catches SIGCONT, let it | |
1031 | * handle the signal itself. If it isn't waiting on | |
1032 | * an event, then it goes back to run state. | |
1033 | * Otherwise, process goes back to sleep state. | |
1034 | */ | |
1035 | if (action == SIG_DFL) | |
1036 | SIGDELSET(p->p_siglist, sig); | |
1037 | if (action == SIG_CATCH) | |
26a0694b | 1038 | goto run; |
984263bc MD |
1039 | if (p->p_wchan == 0) |
1040 | goto run; | |
26a0694b | 1041 | clrrunnable(p, SSLEEP); |
984263bc MD |
1042 | goto out; |
1043 | } | |
1044 | ||
1045 | if (prop & SA_STOP) { | |
1046 | /* | |
1047 | * Already stopped, don't need to stop again. | |
1048 | * (If we did the shell could get confused.) | |
1049 | */ | |
1050 | SIGDELSET(p->p_siglist, sig); | |
1051 | goto out; | |
1052 | } | |
1053 | ||
1054 | /* | |
1055 | * If process is sleeping interruptibly, then simulate a | |
1056 | * wakeup so that when it is continued, it will be made | |
1057 | * runnable and can look at the signal. But don't make | |
1058 | * the process runnable, leave it stopped. | |
1059 | */ | |
92e4c1e5 | 1060 | if (p->p_wchan && (p->p_flag & P_SINTR)) |
0cfcada1 | 1061 | unsleep(p->p_thread); |
984263bc MD |
1062 | goto out; |
1063 | ||
1064 | default: | |
1065 | /* | |
1066 | * SRUN, SIDL, SZOMB do nothing with the signal, | |
1067 | * other than kicking ourselves if we are running. | |
1068 | * It will either never be noticed, or noticed very soon. | |
cb973d15 MD |
1069 | * |
1070 | * For SMP we may have to forward the request to another cpu. | |
1071 | * YYY the MP lock prevents the target process from moving | |
1072 | * to another cpu, see kern/kern_switch.c | |
984263bc | 1073 | */ |
984263bc | 1074 | #ifdef SMP |
cb973d15 | 1075 | if (p == lwkt_preempted_proc()) { |
235957ed | 1076 | signotify(); |
cb973d15 | 1077 | } else { |
a72187e9 MD |
1078 | struct thread *td = p->p_thread; |
1079 | ||
1080 | if (td->td_gd != mycpu) | |
1081 | lwkt_send_ipiq(td->td_gd->gd_cpuid, signotify_remote, p); | |
cb973d15 MD |
1082 | } |
1083 | #else | |
1084 | if (p == lwkt_preempted_proc()) | |
235957ed | 1085 | signotify(); |
984263bc MD |
1086 | #endif |
1087 | goto out; | |
1088 | } | |
1089 | /*NOTREACHED*/ | |
984263bc MD |
1090 | run: |
1091 | setrunnable(p); | |
1092 | out: | |
1093 | splx(s); | |
1094 | } | |
1095 | ||
cb973d15 MD |
1096 | #ifdef SMP |
1097 | ||
1098 | /* | |
1099 | * This function is called via an IPI. We will be in a critical section but | |
1100 | * the MP lock will NOT be held. Also note that by the time the ipi message | |
1101 | * gets to us the process 'p' (arg) may no longer be scheduled or even valid. | |
1102 | */ | |
1103 | static void | |
1104 | signotify_remote(void *arg) | |
1105 | { | |
1106 | struct proc *p = arg; | |
1107 | if (p == lwkt_preempted_proc()) | |
235957ed | 1108 | signotify(); |
cb973d15 MD |
1109 | } |
1110 | ||
1111 | #endif | |
1112 | ||
984263bc MD |
1113 | /* |
1114 | * If the current process has received a signal (should be caught or cause | |
1115 | * termination, should interrupt current syscall), return the signal number. | |
1116 | * Stop signals with default action are processed immediately, then cleared; | |
1117 | * they aren't returned. This is checked after each entry to the system for | |
1118 | * a syscall or trap (though this can usually be done without calling issignal | |
1119 | * by checking the pending signal masks in the CURSIG macro.) The normal call | |
1120 | * sequence is | |
1121 | * | |
1122 | * while (sig = CURSIG(curproc)) | |
1123 | * postsig(sig); | |
1124 | */ | |
1125 | int | |
1126 | issignal(p) | |
1127 | register struct proc *p; | |
1128 | { | |
1129 | sigset_t mask; | |
1130 | register int sig, prop; | |
1131 | ||
1132 | for (;;) { | |
1133 | int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); | |
1134 | ||
1135 | mask = p->p_siglist; | |
1136 | SIGSETNAND(mask, p->p_sigmask); | |
1137 | if (p->p_flag & P_PPWAIT) | |
1138 | SIG_STOPSIGMASK(mask); | |
1139 | if (!SIGNOTEMPTY(mask)) /* no signal to send */ | |
1140 | return (0); | |
1141 | sig = sig_ffs(&mask); | |
1142 | ||
1143 | STOPEVENT(p, S_SIG, sig); | |
1144 | ||
1145 | /* | |
1146 | * We should see pending but ignored signals | |
1147 | * only if P_TRACED was on when they were posted. | |
1148 | */ | |
1149 | if (SIGISMEMBER(p->p_sigignore, sig) && (traced == 0)) { | |
1150 | SIGDELSET(p->p_siglist, sig); | |
1151 | continue; | |
1152 | } | |
1153 | if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) { | |
1154 | /* | |
1155 | * If traced, always stop, and stay | |
1156 | * stopped until released by the parent. | |
1157 | */ | |
1158 | p->p_xstat = sig; | |
1159 | psignal(p->p_pptr, SIGCHLD); | |
1160 | do { | |
1161 | stop(p); | |
1162 | mi_switch(); | |
26a0694b | 1163 | } while (!trace_req(p) && p->p_flag & P_TRACED); |
984263bc MD |
1164 | |
1165 | /* | |
1166 | * If parent wants us to take the signal, | |
1167 | * then it will leave it in p->p_xstat; | |
1168 | * otherwise we just look for signals again. | |
1169 | */ | |
1170 | SIGDELSET(p->p_siglist, sig); /* clear old signal */ | |
1171 | sig = p->p_xstat; | |
1172 | if (sig == 0) | |
1173 | continue; | |
1174 | ||
1175 | /* | |
1176 | * Put the new signal into p_siglist. If the | |
1177 | * signal is being masked, look for other signals. | |
1178 | */ | |
1179 | SIGADDSET(p->p_siglist, sig); | |
1180 | if (SIGISMEMBER(p->p_sigmask, sig)) | |
1181 | continue; | |
1182 | ||
1183 | /* | |
1184 | * If the traced bit got turned off, go back up | |
1185 | * to the top to rescan signals. This ensures | |
1186 | * that p_sig* and ps_sigact are consistent. | |
1187 | */ | |
1188 | if ((p->p_flag & P_TRACED) == 0) | |
1189 | continue; | |
1190 | } | |
1191 | ||
1192 | prop = sigprop(sig); | |
1193 | ||
1194 | /* | |
1195 | * Decide whether the signal should be returned. | |
1196 | * Return the signal's number, or fall through | |
1197 | * to clear it from the pending mask. | |
1198 | */ | |
1199 | switch ((int)(intptr_t)p->p_sigacts->ps_sigact[_SIG_IDX(sig)]) { | |
1200 | ||
1201 | case (int)SIG_DFL: | |
1202 | /* | |
1203 | * Don't take default actions on system processes. | |
1204 | */ | |
1205 | if (p->p_pid <= 1) { | |
1206 | #ifdef DIAGNOSTIC | |
1207 | /* | |
1208 | * Are you sure you want to ignore SIGSEGV | |
1209 | * in init? XXX | |
1210 | */ | |
1211 | printf("Process (pid %lu) got signal %d\n", | |
1212 | (u_long)p->p_pid, sig); | |
1213 | #endif | |
1214 | break; /* == ignore */ | |
1215 | } | |
1216 | /* | |
1217 | * If there is a pending stop signal to process | |
1218 | * with default action, stop here, | |
1219 | * then clear the signal. However, | |
1220 | * if process is member of an orphaned | |
1221 | * process group, ignore tty stop signals. | |
1222 | */ | |
1223 | if (prop & SA_STOP) { | |
1224 | if (p->p_flag & P_TRACED || | |
1225 | (p->p_pgrp->pg_jobc == 0 && | |
1226 | prop & SA_TTYSTOP)) | |
1227 | break; /* == ignore */ | |
1228 | p->p_xstat = sig; | |
1229 | stop(p); | |
1230 | if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) | |
1231 | psignal(p->p_pptr, SIGCHLD); | |
1232 | mi_switch(); | |
1233 | break; | |
1234 | } else if (prop & SA_IGNORE) { | |
1235 | /* | |
1236 | * Except for SIGCONT, shouldn't get here. | |
1237 | * Default action is to ignore; drop it. | |
1238 | */ | |
1239 | break; /* == ignore */ | |
1240 | } else | |
1241 | return (sig); | |
1242 | /*NOTREACHED*/ | |
1243 | ||
1244 | case (int)SIG_IGN: | |
1245 | /* | |
1246 | * Masking above should prevent us ever trying | |
1247 | * to take action on an ignored signal other | |
1248 | * than SIGCONT, unless process is traced. | |
1249 | */ | |
1250 | if ((prop & SA_CONT) == 0 && | |
1251 | (p->p_flag & P_TRACED) == 0) | |
1252 | printf("issignal\n"); | |
1253 | break; /* == ignore */ | |
1254 | ||
1255 | default: | |
1256 | /* | |
1257 | * This signal has an action, let | |
1258 | * postsig() process it. | |
1259 | */ | |
1260 | return (sig); | |
1261 | } | |
1262 | SIGDELSET(p->p_siglist, sig); /* take the signal! */ | |
1263 | } | |
1264 | /* NOTREACHED */ | |
1265 | } | |
1266 | ||
1267 | /* | |
1268 | * Put the argument process into the stopped state and notify the parent | |
1269 | * via wakeup. Signals are handled elsewhere. The process must not be | |
1270 | * on the run queue. | |
1271 | */ | |
1272 | void | |
1273 | stop(p) | |
1274 | register struct proc *p; | |
1275 | { | |
1276 | ||
1277 | p->p_stat = SSTOP; | |
1278 | p->p_flag &= ~P_WAITED; | |
1279 | wakeup((caddr_t)p->p_pptr); | |
1280 | } | |
1281 | ||
1282 | /* | |
1283 | * Take the action for the specified signal | |
1284 | * from the current set of pending signals. | |
1285 | */ | |
1286 | void | |
1287 | postsig(sig) | |
1288 | register int sig; | |
1289 | { | |
41c20dac | 1290 | struct proc *p = curproc; |
984263bc MD |
1291 | struct sigacts *ps = p->p_sigacts; |
1292 | sig_t action; | |
1293 | sigset_t returnmask; | |
1294 | int code; | |
1295 | ||
1296 | KASSERT(sig != 0, ("postsig")); | |
1297 | ||
1298 | SIGDELSET(p->p_siglist, sig); | |
1299 | action = ps->ps_sigact[_SIG_IDX(sig)]; | |
1300 | #ifdef KTRACE | |
dadab5e9 | 1301 | if (KTRPOINT(p->p_thread, KTR_PSIG)) |
984263bc MD |
1302 | ktrpsig(p->p_tracep, sig, action, p->p_flag & P_OLDMASK ? |
1303 | &p->p_oldsigmask : &p->p_sigmask, 0); | |
1304 | #endif | |
1305 | STOPEVENT(p, S_SIG, sig); | |
1306 | ||
1307 | if (action == SIG_DFL) { | |
1308 | /* | |
1309 | * Default action, where the default is to kill | |
1310 | * the process. (Other cases were ignored above.) | |
1311 | */ | |
1312 | sigexit(p, sig); | |
1313 | /* NOTREACHED */ | |
1314 | } else { | |
1315 | /* | |
1316 | * If we get here, the signal must be caught. | |
1317 | */ | |
1318 | KASSERT(action != SIG_IGN && !SIGISMEMBER(p->p_sigmask, sig), | |
1319 | ("postsig action")); | |
1320 | /* | |
1321 | * Set the new mask value and also defer further | |
1322 | * occurrences of this signal. | |
1323 | * | |
1324 | * Special case: user has done a sigsuspend. Here the | |
1325 | * current mask is not of interest, but rather the | |
1326 | * mask from before the sigsuspend is what we want | |
1327 | * restored after the signal processing is completed. | |
1328 | */ | |
1329 | (void) splhigh(); | |
1330 | if (p->p_flag & P_OLDMASK) { | |
1331 | returnmask = p->p_oldsigmask; | |
1332 | p->p_flag &= ~P_OLDMASK; | |
1333 | } else | |
1334 | returnmask = p->p_sigmask; | |
1335 | ||
1336 | SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]); | |
1337 | if (!SIGISMEMBER(ps->ps_signodefer, sig)) | |
1338 | SIGADDSET(p->p_sigmask, sig); | |
1339 | ||
1340 | if (SIGISMEMBER(ps->ps_sigreset, sig)) { | |
1341 | /* | |
1342 | * See do_sigaction() for origin of this code. | |
1343 | */ | |
1344 | SIGDELSET(p->p_sigcatch, sig); | |
1345 | if (sig != SIGCONT && | |
1346 | sigprop(sig) & SA_IGNORE) | |
1347 | SIGADDSET(p->p_sigignore, sig); | |
1348 | ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; | |
1349 | } | |
1350 | (void) spl0(); | |
1351 | p->p_stats->p_ru.ru_nsignals++; | |
1352 | if (p->p_sig != sig) { | |
1353 | code = 0; | |
1354 | } else { | |
1355 | code = p->p_code; | |
1356 | p->p_code = 0; | |
1357 | p->p_sig = 0; | |
1358 | } | |
1359 | (*p->p_sysent->sv_sendsig)(action, sig, &returnmask, code); | |
1360 | } | |
1361 | } | |
1362 | ||
1363 | /* | |
1364 | * Kill the current process for stated reason. | |
1365 | */ | |
1366 | void | |
1367 | killproc(p, why) | |
1368 | struct proc *p; | |
1369 | char *why; | |
1370 | { | |
1371 | log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm, | |
41c20dac | 1372 | p->p_ucred ? p->p_ucred->cr_uid : -1, why); |
984263bc MD |
1373 | psignal(p, SIGKILL); |
1374 | } | |
1375 | ||
1376 | /* | |
1377 | * Force the current process to exit with the specified signal, dumping core | |
1378 | * if appropriate. We bypass the normal tests for masked and caught signals, | |
1379 | * allowing unrecoverable failures to terminate the process without changing | |
1380 | * signal state. Mark the accounting record with the signal termination. | |
1381 | * If dumping core, save the signal number for the debugger. Calls exit and | |
1382 | * does not return. | |
1383 | */ | |
1384 | void | |
41c20dac | 1385 | sigexit(struct proc *p, int sig) |
984263bc | 1386 | { |
984263bc MD |
1387 | p->p_acflag |= AXSIG; |
1388 | if (sigprop(sig) & SA_CORE) { | |
1389 | p->p_sig = sig; | |
1390 | /* | |
1391 | * Log signals which would cause core dumps | |
1392 | * (Log as LOG_INFO to appease those who don't want | |
1393 | * these messages.) | |
1394 | * XXX : Todo, as well as euid, write out ruid too | |
1395 | */ | |
1396 | if (coredump(p) == 0) | |
1397 | sig |= WCOREFLAG; | |
1398 | if (kern_logsigexit) | |
1399 | log(LOG_INFO, | |
1400 | "pid %d (%s), uid %d: exited on signal %d%s\n", | |
1401 | p->p_pid, p->p_comm, | |
41c20dac | 1402 | p->p_ucred ? p->p_ucred->cr_uid : -1, |
984263bc MD |
1403 | sig &~ WCOREFLAG, |
1404 | sig & WCOREFLAG ? " (core dumped)" : ""); | |
1405 | } | |
41c20dac | 1406 | exit1(W_EXITCODE(0, sig)); |
984263bc MD |
1407 | /* NOTREACHED */ |
1408 | } | |
1409 | ||
1410 | static char corefilename[MAXPATHLEN+1] = {"%N.core"}; | |
1411 | SYSCTL_STRING(_kern, OID_AUTO, corefile, CTLFLAG_RW, corefilename, | |
1412 | sizeof(corefilename), "process corefile name format string"); | |
1413 | ||
1414 | /* | |
1415 | * expand_name(name, uid, pid) | |
1416 | * Expand the name described in corefilename, using name, uid, and pid. | |
1417 | * corefilename is a printf-like string, with three format specifiers: | |
1418 | * %N name of process ("name") | |
1419 | * %P process id (pid) | |
1420 | * %U user id (uid) | |
1421 | * For example, "%N.core" is the default; they can be disabled completely | |
1422 | * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P". | |
1423 | * This is controlled by the sysctl variable kern.corefile (see above). | |
1424 | */ | |
1425 | ||
1426 | static char * | |
1427 | expand_name(name, uid, pid) | |
1428 | const char *name; uid_t uid; pid_t pid; { | |
1429 | char *temp; | |
1430 | char buf[11]; /* Buffer for pid/uid -- max 4B */ | |
1431 | int i, n; | |
1432 | char *format = corefilename; | |
1433 | size_t namelen; | |
1434 | ||
1435 | temp = malloc(MAXPATHLEN + 1, M_TEMP, M_NOWAIT); | |
1436 | if (temp == NULL) | |
1437 | return NULL; | |
1438 | namelen = strlen(name); | |
1439 | for (i = 0, n = 0; n < MAXPATHLEN && format[i]; i++) { | |
1440 | int l; | |
1441 | switch (format[i]) { | |
1442 | case '%': /* Format character */ | |
1443 | i++; | |
1444 | switch (format[i]) { | |
1445 | case '%': | |
1446 | temp[n++] = '%'; | |
1447 | break; | |
1448 | case 'N': /* process name */ | |
1449 | if ((n + namelen) > MAXPATHLEN) { | |
1450 | log(LOG_ERR, "pid %d (%s), uid (%u): Path `%s%s' is too long\n", | |
1451 | pid, name, uid, temp, name); | |
1452 | free(temp, M_TEMP); | |
1453 | return NULL; | |
1454 | } | |
1455 | memcpy(temp+n, name, namelen); | |
1456 | n += namelen; | |
1457 | break; | |
1458 | case 'P': /* process id */ | |
1459 | l = sprintf(buf, "%u", pid); | |
1460 | if ((n + l) > MAXPATHLEN) { | |
1461 | log(LOG_ERR, "pid %d (%s), uid (%u): Path `%s%s' is too long\n", | |
1462 | pid, name, uid, temp, name); | |
1463 | free(temp, M_TEMP); | |
1464 | return NULL; | |
1465 | } | |
1466 | memcpy(temp+n, buf, l); | |
1467 | n += l; | |
1468 | break; | |
1469 | case 'U': /* user id */ | |
1470 | l = sprintf(buf, "%u", uid); | |
1471 | if ((n + l) > MAXPATHLEN) { | |
1472 | log(LOG_ERR, "pid %d (%s), uid (%u): Path `%s%s' is too long\n", | |
1473 | pid, name, uid, temp, name); | |
1474 | free(temp, M_TEMP); | |
1475 | return NULL; | |
1476 | } | |
1477 | memcpy(temp+n, buf, l); | |
1478 | n += l; | |
1479 | break; | |
1480 | default: | |
1481 | log(LOG_ERR, "Unknown format character %c in `%s'\n", format[i], format); | |
1482 | } | |
1483 | break; | |
1484 | default: | |
1485 | temp[n++] = format[i]; | |
1486 | } | |
1487 | } | |
1488 | temp[n] = '\0'; | |
1489 | return temp; | |
1490 | } | |
1491 | ||
1492 | /* | |
1493 | * Dump a process' core. The main routine does some | |
1494 | * policy checking, and creates the name of the coredump; | |
1495 | * then it passes on a vnode and a size limit to the process-specific | |
1496 | * coredump routine if there is one; if there _is not_ one, it returns | |
1497 | * ENOSYS; otherwise it returns the error from the process-specific routine. | |
1498 | */ | |
1499 | ||
1500 | static int | |
dadab5e9 | 1501 | coredump(struct proc *p) |
984263bc | 1502 | { |
dadab5e9 MD |
1503 | struct vnode *vp; |
1504 | struct ucred *cred = p->p_ucred; | |
1505 | struct thread *td = p->p_thread; | |
984263bc MD |
1506 | struct flock lf; |
1507 | struct nameidata nd; | |
1508 | struct vattr vattr; | |
1509 | int error, error1; | |
1510 | char *name; /* name of corefile */ | |
1511 | off_t limit; | |
1512 | ||
1513 | STOPEVENT(p, S_CORE, 0); | |
1514 | ||
1515 | if (((sugid_coredump == 0) && p->p_flag & P_SUGID) || do_coredump == 0) | |
1516 | return (EFAULT); | |
1517 | ||
1518 | /* | |
1519 | * Note that the bulk of limit checking is done after | |
1520 | * the corefile is created. The exception is if the limit | |
1521 | * for corefiles is 0, in which case we don't bother | |
1522 | * creating the corefile at all. This layout means that | |
1523 | * a corefile is truncated instead of not being created, | |
1524 | * if it is larger than the limit. | |
1525 | */ | |
1526 | limit = p->p_rlimit[RLIMIT_CORE].rlim_cur; | |
1527 | if (limit == 0) | |
1528 | return 0; | |
1529 | ||
1530 | name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid); | |
1531 | if (name == NULL) | |
1532 | return (EINVAL); | |
dadab5e9 | 1533 | NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); |
984263bc MD |
1534 | error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR); |
1535 | free(name, M_TEMP); | |
1536 | if (error) | |
1537 | return (error); | |
1538 | NDFREE(&nd, NDF_ONLY_PNBUF); | |
1539 | vp = nd.ni_vp; | |
1540 | ||
dadab5e9 | 1541 | VOP_UNLOCK(vp, 0, td); |
984263bc MD |
1542 | lf.l_whence = SEEK_SET; |
1543 | lf.l_start = 0; | |
1544 | lf.l_len = 0; | |
1545 | lf.l_type = F_WRLCK; | |
1546 | error = VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &lf, F_FLOCK); | |
1547 | if (error) | |
1548 | goto out2; | |
1549 | ||
1550 | /* Don't dump to non-regular files or files with links. */ | |
1551 | if (vp->v_type != VREG || | |
3b568787 | 1552 | VOP_GETATTR(vp, &vattr, td) || vattr.va_nlink != 1) { |
984263bc MD |
1553 | error = EFAULT; |
1554 | goto out1; | |
1555 | } | |
1556 | ||
1557 | VATTR_NULL(&vattr); | |
dadab5e9 | 1558 | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); |
984263bc | 1559 | vattr.va_size = 0; |
dadab5e9 MD |
1560 | VOP_LEASE(vp, td, cred, LEASE_WRITE); |
1561 | VOP_SETATTR(vp, &vattr, cred, td); | |
984263bc | 1562 | p->p_acflag |= ACORE; |
dadab5e9 | 1563 | VOP_UNLOCK(vp, 0, td); |
984263bc MD |
1564 | |
1565 | error = p->p_sysent->sv_coredump ? | |
1566 | p->p_sysent->sv_coredump(p, vp, limit) : | |
1567 | ENOSYS; | |
1568 | ||
1569 | out1: | |
1570 | lf.l_type = F_UNLCK; | |
1571 | VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK); | |
1572 | out2: | |
3b568787 | 1573 | error1 = vn_close(vp, FWRITE, td); |
984263bc MD |
1574 | if (error == 0) |
1575 | error = error1; | |
1576 | return (error); | |
1577 | } | |
1578 | ||
1579 | /* | |
1580 | * Nonexistent system call-- signal process (may want to handle it). | |
1581 | * Flag error in case process won't see signal immediately (blocked or ignored). | |
1582 | */ | |
984263bc MD |
1583 | /* ARGSUSED */ |
1584 | int | |
41c20dac | 1585 | nosys(struct nosys_args *args) |
984263bc | 1586 | { |
41c20dac | 1587 | psignal(curproc, SIGSYS); |
984263bc MD |
1588 | return (EINVAL); |
1589 | } | |
1590 | ||
1591 | /* | |
1592 | * Send a SIGIO or SIGURG signal to a process or process group using | |
1593 | * stored credentials rather than those of the current process. | |
1594 | */ | |
1595 | void | |
dadab5e9 | 1596 | pgsigio(struct sigio *sigio, int sig, int checkctty) |
984263bc MD |
1597 | { |
1598 | if (sigio == NULL) | |
1599 | return; | |
1600 | ||
1601 | if (sigio->sio_pgid > 0) { | |
1602 | if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, | |
1603 | sigio->sio_proc)) | |
1604 | psignal(sigio->sio_proc, sig); | |
1605 | } else if (sigio->sio_pgid < 0) { | |
1606 | struct proc *p; | |
1607 | ||
1608 | LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) | |
1609 | if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, p) && | |
1610 | (checkctty == 0 || (p->p_flag & P_CONTROLT))) | |
1611 | psignal(p, sig); | |
1612 | } | |
1613 | } | |
1614 | ||
1615 | static int | |
1616 | filt_sigattach(struct knote *kn) | |
1617 | { | |
1618 | struct proc *p = curproc; | |
1619 | ||
1620 | kn->kn_ptr.p_proc = p; | |
1621 | kn->kn_flags |= EV_CLEAR; /* automatically set */ | |
1622 | ||
1623 | /* XXX lock the proc here while adding to the list? */ | |
1624 | SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext); | |
1625 | ||
1626 | return (0); | |
1627 | } | |
1628 | ||
1629 | static void | |
1630 | filt_sigdetach(struct knote *kn) | |
1631 | { | |
1632 | struct proc *p = kn->kn_ptr.p_proc; | |
1633 | ||
1634 | SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext); | |
1635 | } | |
1636 | ||
1637 | /* | |
1638 | * signal knotes are shared with proc knotes, so we apply a mask to | |
1639 | * the hint in order to differentiate them from process hints. This | |
1640 | * could be avoided by using a signal-specific knote list, but probably | |
1641 | * isn't worth the trouble. | |
1642 | */ | |
1643 | static int | |
1644 | filt_signal(struct knote *kn, long hint) | |
1645 | { | |
1646 | ||
1647 | if (hint & NOTE_SIGNAL) { | |
1648 | hint &= ~NOTE_SIGNAL; | |
1649 | ||
1650 | if (kn->kn_id == hint) | |
1651 | kn->kn_data++; | |
1652 | } | |
1653 | return (kn->kn_data != 0); | |
1654 | } |