sys_sig.c revision 1.1.2.2 1 /* $NetBSD: sys_sig.c,v 1.1.2.2 2006/10/24 21:10:21 ad Exp $ */
2
3 /*-
4 * Copyright (c) 2006 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the NetBSD
18 * Foundation, Inc. and its contributors.
19 * 4. Neither the name of The NetBSD Foundation nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /*
37 * Copyright (c) 1982, 1986, 1989, 1991, 1993
38 * The Regents of the University of California. All rights reserved.
39 * (c) UNIX System Laboratories, Inc.
40 * All or some portions of this file are derived from material licensed
41 * to the University of California by American Telephone and Telegraph
42 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
43 * the permission of UNIX System Laboratories, Inc.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. Neither the name of the University nor the names of its contributors
54 * may be used to endorse or promote products derived from this software
55 * without specific prior written permission.
56 *
57 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67 * SUCH DAMAGE.
68 *
69 * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95
70 */
71
72 #include <sys/cdefs.h>
73 __KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.1.2.2 2006/10/24 21:10:21 ad Exp $");
74
75 #include "opt_ptrace.h"
76 #include "opt_compat_netbsd.h"
77 #include "opt_compat_netbsd32.h"
78
79 #include <sys/param.h>
80 #include <sys/kernel.h>
81 #include <sys/malloc.h>
82 #include <sys/signalvar.h>
83 #include <sys/proc.h>
84 #include <sys/pool.h>
85 #include <sys/sa.h>
86 #include <sys/savar.h>
87 #include <sys/syscallargs.h>
88 #include <sys/kauth.h>
89 #include <sys/wait.h>
90
91 #ifdef COMPAT_16
92 /* ARGSUSED */
93 int
94 compat_16_sys___sigaction14(struct lwp *l, void *v, register_t *retval)
95 {
96 struct compat_16_sys___sigaction14_args /* {
97 syscallarg(int) signum;
98 syscallarg(const struct sigaction *) nsa;
99 syscallarg(struct sigaction *) osa;
100 } */ *uap = v;
101 struct sigaction nsa, osa;
102 int error;
103
104 if (SCARG(uap, nsa)) {
105 error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa));
106 if (error)
107 return (error);
108 }
109 error = sigaction1(l, SCARG(uap, signum),
110 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0,
111 NULL, 0);
112 if (error)
113 return (error);
114 if (SCARG(uap, osa)) {
115 error = copyout(&osa, SCARG(uap, osa), sizeof(osa));
116 if (error)
117 return (error);
118 }
119 return (0);
120 }
121 #endif
122
123 /* ARGSUSED */
124 int
125 sys___sigaction_sigtramp(struct lwp *l, void *v, register_t *retval)
126 {
127 struct sys___sigaction_sigtramp_args /* {
128 syscallarg(int) signum;
129 syscallarg(const struct sigaction *) nsa;
130 syscallarg(struct sigaction *) osa;
131 syscallarg(void *) tramp;
132 syscallarg(int) vers;
133 } */ *uap = v;
134 struct sigaction nsa, osa;
135 int error;
136
137 if (SCARG(uap, nsa)) {
138 error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa));
139 if (error)
140 return (error);
141 }
142 error = sigaction1(l, SCARG(uap, signum),
143 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0,
144 SCARG(uap, tramp), SCARG(uap, vers));
145 if (error)
146 return (error);
147 if (SCARG(uap, osa)) {
148 error = copyout(&osa, SCARG(uap, osa), sizeof(osa));
149 if (error)
150 return (error);
151 }
152 return (0);
153 }
154
155 /*
156 * Manipulate signal mask. Note that we receive new mask, not pointer, and
157 * return old mask as return value; the library stub does the rest.
158 */
159 int
160 sys___sigprocmask14(struct lwp *l, void *v, register_t *retval)
161 {
162 struct sys___sigprocmask14_args /* {
163 syscallarg(int) how;
164 syscallarg(const sigset_t *) set;
165 syscallarg(sigset_t *) oset;
166 } */ *uap = v;
167 sigset_t nss, oss;
168 int error;
169
170 if (SCARG(uap, set)) {
171 error = copyin(SCARG(uap, set), &nss, sizeof(nss));
172 if (error)
173 return (error);
174 }
175 error = sigprocmask1(l, SCARG(uap, how),
176 SCARG(uap, set) ? &nss : 0, SCARG(uap, oset) ? &oss : 0);
177 if (error)
178 return (error);
179 if (SCARG(uap, oset)) {
180 error = copyout(&oss, SCARG(uap, oset), sizeof(oss));
181 if (error)
182 return (error);
183 }
184 return (0);
185 }
186
187 /* ARGSUSED */
188 int
189 sys___sigpending14(struct lwp *l, void *v, register_t *retval)
190 {
191 struct sys___sigpending14_args /* {
192 syscallarg(sigset_t *) set;
193 } */ *uap = v;
194 sigset_t ss;
195
196 sigpending1(l, &ss);
197 return (copyout(&ss, SCARG(uap, set), sizeof(ss)));
198 }
199
200 /*
201 * Suspend process until signal, providing mask to be set in the meantime.
202 * Note nonstandard calling convention: libc stub passes mask, not pointer,
203 * to save a copyin.
204 */
205 /* ARGSUSED */
206 int
207 sys___sigsuspend14(struct lwp *l, void *v, register_t *retval)
208 {
209 struct sys___sigsuspend14_args /* {
210 syscallarg(const sigset_t *) set;
211 } */ *uap = v;
212 sigset_t ss;
213 int error;
214
215 if (SCARG(uap, set)) {
216 error = copyin(SCARG(uap, set), &ss, sizeof(ss));
217 if (error)
218 return (error);
219 }
220
221 return (sigsuspend1(l, SCARG(uap, set) ? &ss : 0));
222 }
223
224 /* ARGSUSED */
225 int
226 sys___sigaltstack14(struct lwp *l, void *v, register_t *retval)
227 {
228 struct sys___sigaltstack14_args /* {
229 syscallarg(const struct sigaltstack *) nss;
230 syscallarg(struct sigaltstack *) oss;
231 } */ *uap = v;
232 struct sigaltstack nss, oss;
233 int error;
234
235 if (SCARG(uap, nss)) {
236 error = copyin(SCARG(uap, nss), &nss, sizeof(nss));
237 if (error)
238 return (error);
239 }
240 error = sigaltstack1(l,
241 SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
242 if (error)
243 return (error);
244 if (SCARG(uap, oss)) {
245 error = copyout(&oss, SCARG(uap, oss), sizeof(oss));
246 if (error)
247 return (error);
248 }
249 return (0);
250 }
251
252 /* ARGSUSED */
253 int
254 sys_kill(struct lwp *l, void *v, register_t *retval)
255 {
256 struct sys_kill_args /* {
257 syscallarg(int) pid;
258 syscallarg(int) signum;
259 } */ *uap = v;
260 struct proc *p;
261 ksiginfo_t ksi;
262 int signum = SCARG(uap, signum);
263 int error;
264
265 if ((u_int)signum >= NSIG)
266 return (EINVAL);
267 KSI_INIT(&ksi);
268 ksi.ksi_signo = signum;
269 ksi.ksi_code = SI_USER;
270 ksi.ksi_pid = l->l_proc->p_pid;
271 ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
272 if (SCARG(uap, pid) > 0) {
273 /* kill single process */
274 if ((p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL)) == NULL)
275 return (ESRCH);
276 mutex_enter(&p->p_crmutex);
277 error = kauth_authorize_process(l->l_cred,
278 KAUTH_PROCESS_CANSIGNAL, p, (void *)(uintptr_t)signum,
279 NULL, NULL);
280 if (!error && signum) {
281 mutex_enter(&p->p_smutex);
282 kpsignal2(p, &ksi);
283 mutex_exit(&p->p_smutex);
284 }
285 mutex_exit(&p->p_crmutex);
286 rw_exit(&proclist_lock);
287 return (0);
288 }
289 switch (SCARG(uap, pid)) {
290 case -1: /* broadcast signal */
291 return (killpg1(l, &ksi, 0, 1));
292 case 0: /* signal own process group */
293 return (killpg1(l, &ksi, 0, 0));
294 default: /* negative explicit process group */
295 return (killpg1(l, &ksi, -SCARG(uap, pid), 0));
296 }
297 /* NOTREACHED */
298 }
299
300 /*
301 * Nonexistent system call-- signal process (may want to handle it). Flag
302 * error in case process won't see signal immediately (blocked or ignored).
303 *
304 * XXX This should not be here.
305 */
306 #ifndef PTRACE
307 __weak_alias(sys_ptrace, sys_nosys);
308 #endif
309
310 /* ARGSUSED */
311 int
312 sys_nosys(struct lwp *l, void *v, register_t *retval)
313 {
314
315 psignal(l->l_proc, SIGSYS);
316 return (ENOSYS);
317 }
318
319 /* ARGSUSED */
320 int
321 sys_getcontext(struct lwp *l, void *v, register_t *retval)
322 {
323 struct sys_getcontext_args /* {
324 syscallarg(struct __ucontext *) ucp;
325 } */ *uap = v;
326 ucontext_t uc;
327
328 getucontext(l, &uc);
329
330 return (copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp))));
331 }
332
333 /* ARGSUSED */
334 int
335 sys_setcontext(struct lwp *l, void *v, register_t *retval)
336 {
337 struct sys_setcontext_args /* {
338 syscallarg(const ucontext_t *) ucp;
339 } */ *uap = v;
340 ucontext_t uc;
341 int error;
342
343 if (SCARG(uap, ucp) == NULL) { /* i.e. end of uc_link chain */
344 /* Acquire the sched state mutex. exit1() will release it. */
345 mutex_enter(&l->l_proc->p_smutex);
346 exit1(l, W_EXITCODE(0, 0));
347 } else if ((error = copyin(SCARG(uap, ucp), &uc, sizeof (uc))) != 0 ||
348 (error = setucontext(l, &uc)) != 0)
349 return (error);
350
351 return (EJUSTRETURN);
352 }
353
354 /*
355 * sigtimedwait(2) system call, used also for implementation
356 * of sigwaitinfo() and sigwait().
357 *
358 * This only handles single LWP in signal wait. libpthread provides
359 * it's own sigtimedwait() wrapper to DTRT WRT individual threads.
360 */
361 int
362 sys___sigtimedwait(struct lwp *l, void *v, register_t *retval)
363 {
364
365 return __sigtimedwait1(l, v, retval, copyout, copyin, copyout);
366 }
367
368 int
369 sigaction1(struct lwp *l, int signum, const struct sigaction *nsa,
370 struct sigaction *osa, const void *tramp, int vers)
371 {
372 struct proc *p;
373 struct sigacts *ps;
374 sigset_t tset;
375 int prop;
376
377 if (signum <= 0 || signum >= NSIG)
378 return (EINVAL);
379
380 p = l->l_proc;
381
382 /*
383 * Trampoline ABI version 0 is reserved for the legacy kernel
384 * provided on-stack trampoline. Conversely, if we are using a
385 * non-0 ABI version, we must have a trampoline. Only validate the
386 * vers if a new sigaction was supplied. Emulations use legacy
387 * kernel trampolines with version 0, alternatively check for that
388 * too.
389 */
390 if ((vers != 0 && tramp == NULL) ||
391 #ifdef SIGTRAMP_VALID
392 (nsa != NULL &&
393 ((vers == 0) ?
394 (p->p_emul->e_sigcode == NULL) :
395 !SIGTRAMP_VALID(vers))) ||
396 #endif
397 (vers == 0 && tramp != NULL)) {
398 return (EINVAL);
399 }
400
401 mutex_enter(&p->p_smutex);
402 ps = p->p_sigacts;
403 if (osa)
404 *osa = SIGACTION_PS(ps, signum);
405 if (!nsa) {
406 mutex_exit(&p->p_smutex);
407 return (0);
408 }
409
410 prop = sigprop[signum];
411 if ((nsa->sa_flags & ~SA_ALLBITS) || (prop & SA_CANTMASK)) {
412 mutex_exit(&p->p_smutex);
413 return (EINVAL);
414 }
415
416 SIGACTION_PS(ps, signum) = *nsa;
417 ps->sa_sigdesc[signum].sd_tramp = tramp;
418 ps->sa_sigdesc[signum].sd_vers = vers;
419 sigminusset(&sigcantmask, &SIGACTION_PS(ps, signum).sa_mask);
420
421 if ((prop & SA_NORESET) != 0)
422 SIGACTION_PS(ps, signum).sa_flags &= ~SA_RESETHAND;
423
424 if (signum == SIGCHLD) {
425 if (nsa->sa_flags & SA_NOCLDSTOP)
426 p->p_flag |= P_NOCLDSTOP;
427 else
428 p->p_flag &= ~P_NOCLDSTOP;
429 if (nsa->sa_flags & SA_NOCLDWAIT) {
430 /*
431 * Paranoia: since SA_NOCLDWAIT is implemented by
432 * reparenting the dying child to PID 1 (and trust
433 * it to reap the zombie), PID 1 itself is forbidden
434 * to set SA_NOCLDWAIT.
435 */
436 if (p->p_pid == 1)
437 p->p_flag &= ~P_NOCLDWAIT;
438 else
439 p->p_flag |= P_NOCLDWAIT;
440 } else
441 p->p_flag &= ~P_NOCLDWAIT;
442
443 if (nsa->sa_handler == SIG_IGN) {
444 /*
445 * Paranoia: same as above.
446 */
447 if (p->p_pid == 1)
448 p->p_flag &= ~P_CLDSIGIGN;
449 else
450 p->p_flag |= P_CLDSIGIGN;
451 } else
452 p->p_flag &= ~P_CLDSIGIGN;
453 }
454
455 if ((nsa->sa_flags & SA_NODEFER) == 0)
456 sigaddset(&SIGACTION_PS(ps, signum).sa_mask, signum);
457 else
458 sigdelset(&SIGACTION_PS(ps, signum).sa_mask, signum);
459
460 /*
461 * Set bit in p_sigctx.ps_sigignore for signals that are set to
462 * SIG_IGN, and for signals set to SIG_DFL where the default is to
463 * ignore. However, don't put SIGCONT in p_sigctx.ps_sigignore, as
464 * we have to restart the process.
465 */
466 if (nsa->sa_handler == SIG_IGN ||
467 (nsa->sa_handler == SIG_DFL && (prop & SA_IGNORE) != 0)) {
468 /* Never to be seen again. */
469 sigemptyset(&tset);
470 sigaddset(&tset, signum);
471 sigclearall(p, &tset);
472 if (signum != SIGCONT) {
473 /* Easier in psignal */
474 sigaddset(&p->p_sigctx.ps_sigignore, signum);
475 }
476 sigdelset(&p->p_sigctx.ps_sigcatch, signum);
477 } else {
478 sigdelset(&p->p_sigctx.ps_sigignore, signum);
479 if (nsa->sa_handler == SIG_DFL)
480 sigdelset(&p->p_sigctx.ps_sigcatch, signum);
481 else
482 sigaddset(&p->p_sigctx.ps_sigcatch, signum);
483 }
484
485 /*
486 * Previously held signals may now have become visible. Ensure that
487 * we check for them before returning to userspace.
488 */
489 lwp_lock(l);
490 signotify(l);
491 lwp_unlock(l);
492
493 mutex_exit(&p->p_smutex);
494 return (0);
495 }
496
497 int
498 sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
499 {
500 struct proc *p = l->l_proc;
501 int more;
502
503 mutex_enter(&p->p_smutex);
504
505 if (oss)
506 *oss = *l->l_sigmask;
507 if (nss) {
508 switch (how) {
509 case SIG_BLOCK:
510 sigplusset(nss, l->l_sigmask);
511 more = 0;
512 break;
513 case SIG_UNBLOCK:
514 sigminusset(nss, l->l_sigmask);
515 more = 1;
516 break;
517 case SIG_SETMASK:
518 *l->l_sigmask = *nss;
519 more = 1;
520 break;
521 default:
522 mutex_exit(&p->p_smutex);
523 return (EINVAL);
524 }
525 sigminusset(&sigcantmask, l->l_sigmask);
526 if (more) {
527 /*
528 * Pinch any signals from the per-process pending
529 * list that are now of interest to us.
530 */
531 if ((p->p_flag & P_SA) == 0)
532 sigpinch(&p->p_sigpend, l->l_sigpend,
533 l->l_sigmask);
534
535 /*
536 * Check for pending signals on return to user.
537 */
538 lwp_lock(l);
539 signotify(l);
540 lwp_unlock(l);
541 }
542 }
543
544 mutex_exit(&p->p_smutex);
545
546 return (0);
547 }
548
549 void
550 sigpending1(struct lwp *l, sigset_t *ss)
551 {
552 struct proc *p = l->l_proc;
553
554 mutex_enter(&p->p_smutex);
555 *ss = l->l_sigpend->sp_set;
556 sigplusset(&p->p_sigpend.sp_set, ss);
557 sigminusset(l->l_sigmask, ss);
558 mutex_exit(&p->p_smutex);
559 }
560
561 int
562 sigsuspend1(struct lwp *l, const sigset_t *ss)
563 {
564 struct proc *p;
565 struct sigacts *ps;
566
567 p = l->l_proc;
568 ps = p->p_sigacts;
569
570 mutex_enter(&p->p_smutex);
571
572 if (ss) {
573 /*
574 * When returning from sigpause, we want
575 * the old mask to be restored after the
576 * signal handler has finished. Thus, we
577 * save it here and mark the sigctx structure
578 * to indicate this.
579 */
580 l->l_sigoldmask = *l->l_sigmask;
581 l->l_sigrestore = 1;
582 *l->l_sigmask = *ss;
583 sigminusset(&sigcantmask, l->l_sigmask);
584 lwp_lock(l);
585 signotify(l);
586 lwp_unlock(l);
587 }
588
589 while (mtsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0,
590 &p->p_smutex) == 0)
591 /* void */;
592
593 mutex_exit(&p->p_smutex);
594
595 /* always return EINTR rather than ERESTART... */
596 return (EINTR);
597 }
598
599 int
600 sigaltstack1(struct lwp *l, const struct sigaltstack *nss,
601 struct sigaltstack *oss)
602 {
603 struct proc *p = l->l_proc;
604 int error = 0;
605
606 mutex_enter(&p->p_smutex);
607
608 if (oss)
609 *oss = *l->l_sigstk;
610
611 if (nss) {
612 if (nss->ss_flags & ~SS_ALLBITS)
613 error = EINVAL;
614 else if (nss->ss_flags & SS_DISABLE) {
615 if (l->l_sigstk->ss_flags & SS_ONSTACK)
616 error = EINVAL;
617 } else if (nss->ss_size < MINSIGSTKSZ)
618 error = ENOMEM;
619
620 if (!error)
621 *l->l_sigstk = *nss;
622 }
623
624 mutex_exit(&p->p_smutex);
625
626 return (error);
627 }
628
629 int
630 __sigtimedwait1(struct lwp *l, void *v, register_t *retval,
631 copyout_t put_info, copyin_t fetch_timeout, copyout_t put_timeout)
632 {
633 struct sys___sigtimedwait_args /* {
634 syscallarg(const sigset_t *) set;
635 syscallarg(siginfo_t *) info;
636 syscallarg(struct timespec *) timeout;
637 } */ *uap = v;
638 sigset_t *waitset;
639 struct proc *p = l->l_proc;
640 int error, signum;
641 int timo = 0;
642 struct timespec ts, tsstart, tsnow;
643 ksiginfo_t *ksi;
644
645 memset(&tsstart, 0, sizeof tsstart); /* XXX gcc */
646
647 /*
648 * Calculate timeout, if it was specified.
649 */
650 if (SCARG(uap, timeout)) {
651 uint64_t ms;
652
653 if ((error = (*fetch_timeout)(SCARG(uap, timeout), &ts, sizeof(ts))))
654 return (error);
655
656 ms = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
657 timo = mstohz(ms);
658 if (timo == 0 && ts.tv_sec == 0 && ts.tv_nsec > 0)
659 timo = 1;
660 if (timo <= 0)
661 return (EAGAIN);
662
663 /*
664 * Remember current uptime, it would be used in
665 * ECANCELED/ERESTART case.
666 */
667 getnanouptime(&tsstart);
668 }
669
670 MALLOC(waitset, sigset_t *, sizeof(sigset_t), M_TEMP, M_WAITOK);
671 if ((error = copyin(SCARG(uap, set), waitset, sizeof(sigset_t)))) {
672 FREE(waitset, M_TEMP);
673 return (error);
674 }
675
676 /*
677 * Silently ignore SA_CANTMASK signals. psignal1() would ignore
678 * SA_CANTMASK signals in waitset, we do this only for the below
679 * siglist check.
680 */
681 sigminusset(&sigcantmask, waitset);
682
683 /*
684 * Allocate a ksi up front. We can't sleep with the mutex held.
685 */
686 ksi = pool_get(&ksiginfo_pool, PR_WAITOK);
687
688 /*
689 * First scan the per-proc and per-LWP lists and check if there is
690 * signal from our waitset already pending.
691 */
692 mutex_enter(&p->p_smutex);
693
694 /*
695 * SA processes can have no more than 1 sigwaiter.
696 */
697 if ((p->p_flag & P_SA) != 0 && !LIST_EMPTY(&p->p_sigwaiters)) {
698 mutex_exit(&p->p_smutex);
699 error = EINVAL;
700 goto out;
701 }
702
703 if ((signum = sigget(&p->p_sigpend, ksi, 0, waitset)) == 0)
704 if ((p->p_flag & P_SA) == 0)
705 signum = sigget(l->l_sigpend, ksi, 0, waitset);
706
707 if (signum != 0) {
708 /*
709 * We found a pending signal - copy it out to the user.
710 */
711 mutex_exit(&p->p_smutex);
712 goto out;
713 }
714
715 /*
716 * Set up the sigwait list. Pass pointer to malloced memory here;
717 * it's not possible to pass pointer to a structure on current
718 * process's stack, the current LWP might be swapped out when the
719 * when the signal is delivered.
720 */
721 l->l_sigwaited = ksi;
722 l->l_sigwait = waitset;
723 LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter);
724
725 /*
726 * Wait for signal to arrive. We can either be woken up or time out.
727 */
728 error = mtsleep(&l->l_sigwait, PPAUSE|PCATCH, "sigwait", timo,
729 &p->p_smutex);
730
731 /*
732 * Need to find out if we woke as a result of lwp_wakeup() or a
733 * signal outside our wait set.
734 */
735 if (l->l_sigwaited != NULL) {
736 if (error == EINTR) {
737 /* wakeup via _lwp_wakeup() */
738 error = ECANCELED;
739 } else if (!error) {
740 /* spurious wakeup - arrange for syscall restart */
741 error = ERESTART;
742 }
743 }
744
745 /*
746 * Clear the sigwait indication and unlock.
747 */
748 l->l_sigwait = NULL;
749 l->l_sigwaited = NULL;
750 LIST_REMOVE(l, l_sigwaiter);
751 mutex_exit(&p->p_smutex);
752
753 /*
754 * If the sleep was interrupted (either by signal or wakeup), update
755 * the timeout and copyout new value back. It would be used when
756 * the syscall would be restarted or called again.
757 */
758 if (timo && (error == ERESTART || error == ECANCELED)) {
759 getnanouptime(&tsnow);
760
761 /* compute how much time has passed since start */
762 timespecsub(&tsnow, &tsstart, &tsnow);
763 /* substract passed time from timeout */
764 timespecsub(&ts, &tsnow, &ts);
765
766 if (ts.tv_sec < 0)
767 error = EAGAIN;
768 else {
769 /* copy updated timeout to userland */
770 error = (*put_timeout)(&ts, SCARG(uap, timeout),
771 sizeof(ts));
772 }
773 }
774
775 /*
776 * If a signal from the wait set arrived, copy it to userland.
777 * Copy only the used part of siginfo, the padding part is
778 * left unchanged (userland is not supposed to touch it anyway).
779 */
780 out:
781 FREE(waitset, M_TEMP);
782 pool_put(&ksiginfo_pool, ksi);
783
784 if (error == 0)
785 error = (*put_info)(&ksi->ksi_info, SCARG(uap, info),
786 sizeof(ksi->ksi_info));
787
788 return error;
789 }
790