xref: /netbsd-src/sys/kern/sys_sig.c (revision db70f1818e7ff50a8dc56df4856a66bb16ccb77b)
1*db70f181Schristos /*	$NetBSD: sys_sig.c,v 1.45 2015/10/02 16:54:15 christos Exp $	*/
2b07ec3fcSad 
3b07ec3fcSad /*-
4284c2b9aSad  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
5b07ec3fcSad  * All rights reserved.
6b07ec3fcSad  *
7b07ec3fcSad  * This code is derived from software contributed to The NetBSD Foundation
8b07ec3fcSad  * by Andrew Doran.
9b07ec3fcSad  *
10b07ec3fcSad  * Redistribution and use in source and binary forms, with or without
11b07ec3fcSad  * modification, are permitted provided that the following conditions
12b07ec3fcSad  * are met:
13b07ec3fcSad  * 1. Redistributions of source code must retain the above copyright
14b07ec3fcSad  *    notice, this list of conditions and the following disclaimer.
15b07ec3fcSad  * 2. Redistributions in binary form must reproduce the above copyright
16b07ec3fcSad  *    notice, this list of conditions and the following disclaimer in the
17b07ec3fcSad  *    documentation and/or other materials provided with the distribution.
18b07ec3fcSad  *
19b07ec3fcSad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20b07ec3fcSad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21b07ec3fcSad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b07ec3fcSad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23b07ec3fcSad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24b07ec3fcSad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25b07ec3fcSad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26b07ec3fcSad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27b07ec3fcSad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28b07ec3fcSad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29b07ec3fcSad  * POSSIBILITY OF SUCH DAMAGE.
30b07ec3fcSad  */
31b07ec3fcSad 
32b07ec3fcSad /*
33b07ec3fcSad  * Copyright (c) 1982, 1986, 1989, 1991, 1993
34b07ec3fcSad  *	The Regents of the University of California.  All rights reserved.
35b07ec3fcSad  * (c) UNIX System Laboratories, Inc.
36b07ec3fcSad  * All or some portions of this file are derived from material licensed
37b07ec3fcSad  * to the University of California by American Telephone and Telegraph
38b07ec3fcSad  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
39b07ec3fcSad  * the permission of UNIX System Laboratories, Inc.
40b07ec3fcSad  *
41b07ec3fcSad  * Redistribution and use in source and binary forms, with or without
42b07ec3fcSad  * modification, are permitted provided that the following conditions
43b07ec3fcSad  * are met:
44b07ec3fcSad  * 1. Redistributions of source code must retain the above copyright
45b07ec3fcSad  *    notice, this list of conditions and the following disclaimer.
46b07ec3fcSad  * 2. Redistributions in binary form must reproduce the above copyright
47b07ec3fcSad  *    notice, this list of conditions and the following disclaimer in the
48b07ec3fcSad  *    documentation and/or other materials provided with the distribution.
49b07ec3fcSad  * 3. Neither the name of the University nor the names of its contributors
50b07ec3fcSad  *    may be used to endorse or promote products derived from this software
51b07ec3fcSad  *    without specific prior written permission.
52b07ec3fcSad  *
53b07ec3fcSad  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54b07ec3fcSad  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55b07ec3fcSad  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56b07ec3fcSad  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57b07ec3fcSad  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58b07ec3fcSad  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59b07ec3fcSad  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60b07ec3fcSad  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61b07ec3fcSad  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62b07ec3fcSad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63b07ec3fcSad  * SUCH DAMAGE.
64b07ec3fcSad  *
65b07ec3fcSad  *	@(#)kern_sig.c	8.14 (Berkeley) 5/14/95
66b07ec3fcSad  */
67b07ec3fcSad 
68b07ec3fcSad #include <sys/cdefs.h>
69*db70f181Schristos __KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.45 2015/10/02 16:54:15 christos Exp $");
70*db70f181Schristos 
71*db70f181Schristos #include "opt_dtrace.h"
72b07ec3fcSad 
73b07ec3fcSad #include <sys/param.h>
74b07ec3fcSad #include <sys/kernel.h>
75b07ec3fcSad #include <sys/signalvar.h>
76b07ec3fcSad #include <sys/proc.h>
77b07ec3fcSad #include <sys/pool.h>
78b07ec3fcSad #include <sys/syscallargs.h>
79b07ec3fcSad #include <sys/kauth.h>
80b07ec3fcSad #include <sys/wait.h>
81b07ec3fcSad #include <sys/kmem.h>
8292ce8c6aSad #include <sys/module.h>
83*db70f181Schristos #include <sys/sdt.h>
84*db70f181Schristos 
85*db70f181Schristos SDT_PROVIDER_DECLARE(proc);
86*db70f181Schristos SDT_PROBE_DEFINE2(proc, kernel, , signal__clear,
87*db70f181Schristos     "int", 		/* signal */
88*db70f181Schristos     "ksiginfo_t *");	/* signal-info */
89b07ec3fcSad 
90b07ec3fcSad int
913c74cdf1Srmind sys___sigaction_sigtramp(struct lwp *l,
923c74cdf1Srmind     const struct sys___sigaction_sigtramp_args *uap, register_t *retval)
93b07ec3fcSad {
947e2790cfSdsl 	/* {
95b07ec3fcSad 		syscallarg(int)				signum;
96b07ec3fcSad 		syscallarg(const struct sigaction *)	nsa;
97b07ec3fcSad 		syscallarg(struct sigaction *)		osa;
98b07ec3fcSad 		syscallarg(void *)			tramp;
99b07ec3fcSad 		syscallarg(int)				vers;
1007e2790cfSdsl 	} */
101b07ec3fcSad 	struct sigaction nsa, osa;
102b07ec3fcSad 	int error;
103b07ec3fcSad 
104b07ec3fcSad 	if (SCARG(uap, nsa)) {
105b07ec3fcSad 		error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa));
106b07ec3fcSad 		if (error)
107b07ec3fcSad 			return (error);
108b07ec3fcSad 	}
109b07ec3fcSad 	error = sigaction1(l, SCARG(uap, signum),
110b07ec3fcSad 	    SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0,
111b07ec3fcSad 	    SCARG(uap, tramp), SCARG(uap, vers));
112b07ec3fcSad 	if (error)
113b07ec3fcSad 		return (error);
114b07ec3fcSad 	if (SCARG(uap, osa)) {
115b07ec3fcSad 		error = copyout(&osa, SCARG(uap, osa), sizeof(osa));
116b07ec3fcSad 		if (error)
117b07ec3fcSad 			return (error);
118b07ec3fcSad 	}
1193c74cdf1Srmind 	return 0;
120b07ec3fcSad }
121b07ec3fcSad 
122b07ec3fcSad /*
123b07ec3fcSad  * Manipulate signal mask.  Note that we receive new mask, not pointer, and
124b07ec3fcSad  * return old mask as return value; the library stub does the rest.
125b07ec3fcSad  */
126b07ec3fcSad int
1273c74cdf1Srmind sys___sigprocmask14(struct lwp *l, const struct sys___sigprocmask14_args *uap,
1283c74cdf1Srmind     register_t *retval)
129b07ec3fcSad {
1307e2790cfSdsl 	/* {
131b07ec3fcSad 		syscallarg(int)			how;
132b07ec3fcSad 		syscallarg(const sigset_t *)	set;
133b07ec3fcSad 		syscallarg(sigset_t *)		oset;
1347e2790cfSdsl 	} */
135b07ec3fcSad 	struct proc	*p = l->l_proc;
136b07ec3fcSad 	sigset_t	nss, oss;
137b07ec3fcSad 	int		error;
138b07ec3fcSad 
139b07ec3fcSad 	if (SCARG(uap, set)) {
140b07ec3fcSad 		error = copyin(SCARG(uap, set), &nss, sizeof(nss));
141b07ec3fcSad 		if (error)
1423c74cdf1Srmind 			return error;
143b07ec3fcSad 	}
144284c2b9aSad 	mutex_enter(p->p_lock);
145b07ec3fcSad 	error = sigprocmask1(l, SCARG(uap, how),
146b07ec3fcSad 	    SCARG(uap, set) ? &nss : 0, SCARG(uap, oset) ? &oss : 0);
147284c2b9aSad 	mutex_exit(p->p_lock);
148b07ec3fcSad 	if (error)
1493c74cdf1Srmind 		return error;
150b07ec3fcSad 	if (SCARG(uap, oset)) {
151b07ec3fcSad 		error = copyout(&oss, SCARG(uap, oset), sizeof(oss));
152b07ec3fcSad 		if (error)
1533c74cdf1Srmind 			return error;
154b07ec3fcSad 	}
1553c74cdf1Srmind 	return 0;
156b07ec3fcSad }
157b07ec3fcSad 
158b07ec3fcSad int
1593c74cdf1Srmind sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap,
1603c74cdf1Srmind     register_t *retval)
161b07ec3fcSad {
1627e2790cfSdsl 	/* {
163b07ec3fcSad 		syscallarg(sigset_t *)	set;
1647e2790cfSdsl 	} */
165b07ec3fcSad 	sigset_t ss;
166b07ec3fcSad 
167b07ec3fcSad 	sigpending1(l, &ss);
1683c74cdf1Srmind 	return copyout(&ss, SCARG(uap, set), sizeof(ss));
169b07ec3fcSad }
170b07ec3fcSad 
171b07ec3fcSad /*
172b07ec3fcSad  * Suspend process until signal, providing mask to be set in the meantime.
173b07ec3fcSad  * Note nonstandard calling convention: libc stub passes mask, not pointer,
174b07ec3fcSad  * to save a copyin.
175b07ec3fcSad  */
176b07ec3fcSad int
1773c74cdf1Srmind sys___sigsuspend14(struct lwp *l, const struct sys___sigsuspend14_args *uap,
1783c74cdf1Srmind     register_t *retval)
179b07ec3fcSad {
1807e2790cfSdsl 	/* {
181b07ec3fcSad 		syscallarg(const sigset_t *)	set;
1827e2790cfSdsl 	} */
183b07ec3fcSad 	sigset_t	ss;
184b07ec3fcSad 	int		error;
185b07ec3fcSad 
186b07ec3fcSad 	if (SCARG(uap, set)) {
187b07ec3fcSad 		error = copyin(SCARG(uap, set), &ss, sizeof(ss));
188b07ec3fcSad 		if (error)
1893c74cdf1Srmind 			return error;
1903c74cdf1Srmind 	}
1913c74cdf1Srmind 	return sigsuspend1(l, SCARG(uap, set) ? &ss : 0);
192b07ec3fcSad }
193b07ec3fcSad 
194b07ec3fcSad int
1953c74cdf1Srmind sys___sigaltstack14(struct lwp *l, const struct sys___sigaltstack14_args *uap,
1963c74cdf1Srmind     register_t *retval)
197b07ec3fcSad {
1987e2790cfSdsl 	/* {
199b07ec3fcSad 		syscallarg(const struct sigaltstack *)	nss;
200b07ec3fcSad 		syscallarg(struct sigaltstack *)	oss;
2017e2790cfSdsl 	} */
202b07ec3fcSad 	struct sigaltstack	nss, oss;
203b07ec3fcSad 	int			error;
204b07ec3fcSad 
205b07ec3fcSad 	if (SCARG(uap, nss)) {
206b07ec3fcSad 		error = copyin(SCARG(uap, nss), &nss, sizeof(nss));
207b07ec3fcSad 		if (error)
2083c74cdf1Srmind 			return error;
209b07ec3fcSad 	}
210b07ec3fcSad 	error = sigaltstack1(l,
211b07ec3fcSad 	    SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
212b07ec3fcSad 	if (error)
2133c74cdf1Srmind 		return error;
214b07ec3fcSad 	if (SCARG(uap, oss)) {
215b07ec3fcSad 		error = copyout(&oss, SCARG(uap, oss), sizeof(oss));
216b07ec3fcSad 		if (error)
2173c74cdf1Srmind 			return error;
218b07ec3fcSad 	}
2193c74cdf1Srmind 	return 0;
220b07ec3fcSad }
221b07ec3fcSad 
2225f7e4ad4Smartin int
2233d70c4b4Schristos kill1(struct lwp *l, pid_t pid, ksiginfo_t *ksi, register_t *retval)
2243d70c4b4Schristos {
2253d70c4b4Schristos 	int error;
2263d70c4b4Schristos 	struct proc *p;
2273d70c4b4Schristos 
2283d70c4b4Schristos 	if ((u_int)ksi->ksi_signo >= NSIG)
2293c74cdf1Srmind 		return EINVAL;
2303d70c4b4Schristos 
231ccc5092eSmartin 	if (pid != l->l_proc->p_pid) {
2323d70c4b4Schristos 		if (ksi->ksi_pid != l->l_proc->p_pid)
2333d70c4b4Schristos 			return EPERM;
2343d70c4b4Schristos 
2353d70c4b4Schristos 		if (ksi->ksi_uid != kauth_cred_geteuid(l->l_cred))
2363d70c4b4Schristos 			return EPERM;
2373d70c4b4Schristos 
2383d70c4b4Schristos 		switch (ksi->ksi_code) {
2393d70c4b4Schristos 		case SI_USER:
2403d70c4b4Schristos 		case SI_QUEUE:
2413d70c4b4Schristos 			break;
2423d70c4b4Schristos 		default:
2433d70c4b4Schristos 			return EPERM;
2443d70c4b4Schristos 		}
245ccc5092eSmartin 	}
2463d70c4b4Schristos 
2473d70c4b4Schristos 	if (pid > 0) {
248b07ec3fcSad 		/* kill single process */
2496d70f903Sad 		mutex_enter(proc_lock);
250c296146aSchristos 		p = proc_find_raw(pid);
251c296146aSchristos 		if (p == NULL || (p->p_stat != SACTIVE && p->p_stat != SSTOP)) {
2526d70f903Sad 			mutex_exit(proc_lock);
253c296146aSchristos 			/* IEEE Std 1003.1-2001: return success for zombies */
254c296146aSchristos 			return p ? 0 : ESRCH;
2556d70f903Sad 		}
256284c2b9aSad 		mutex_enter(p->p_lock);
257b07ec3fcSad 		error = kauth_authorize_process(l->l_cred,
2583d70c4b4Schristos 		    KAUTH_PROCESS_SIGNAL, p, KAUTH_ARG(ksi->ksi_signo),
259b07ec3fcSad 		    NULL, NULL);
2603d70c4b4Schristos 		if (!error && ksi->ksi_signo) {
2613d70c4b4Schristos 			kpsignal2(p, ksi);
262b07ec3fcSad 		}
263284c2b9aSad 		mutex_exit(p->p_lock);
2646d70f903Sad 		mutex_exit(proc_lock);
2653c74cdf1Srmind 		return error;
266b07ec3fcSad 	}
2673d70c4b4Schristos 
2683d70c4b4Schristos 	switch (pid) {
269b07ec3fcSad 	case -1:		/* broadcast signal */
2703d70c4b4Schristos 		return killpg1(l, ksi, 0, 1);
271b07ec3fcSad 	case 0:			/* signal own process group */
2723d70c4b4Schristos 		return killpg1(l, ksi, 0, 0);
273b07ec3fcSad 	default:		/* negative explicit process group */
2743d70c4b4Schristos 		return killpg1(l, ksi, -pid, 0);
275b07ec3fcSad 	}
276b07ec3fcSad 	/* NOTREACHED */
277b07ec3fcSad }
278b07ec3fcSad 
279b07ec3fcSad int
2803d70c4b4Schristos sys_sigqueueinfo(struct lwp *l, const struct sys_sigqueueinfo_args *uap,
2813d70c4b4Schristos     register_t *retval)
2823d70c4b4Schristos {
2833d70c4b4Schristos 	/* {
2843d70c4b4Schristos 		syscallarg(pid_t int)	pid;
2853d70c4b4Schristos 		syscallarg(const siginfo_t *)	info;
2863d70c4b4Schristos 	} */
2873d70c4b4Schristos 	ksiginfo_t	ksi;
2883d70c4b4Schristos 	int error;
2893d70c4b4Schristos 
2903d70c4b4Schristos 	KSI_INIT(&ksi);
2913d70c4b4Schristos 
2923d70c4b4Schristos 	if ((error = copyin(&SCARG(uap, info)->_info, &ksi.ksi_info,
2933d70c4b4Schristos 	    sizeof(ksi.ksi_info))) != 0)
2943d70c4b4Schristos 		return error;
2953d70c4b4Schristos 
2963d70c4b4Schristos 	return kill1(l, SCARG(uap, pid), &ksi, retval);
2973d70c4b4Schristos }
2983d70c4b4Schristos 
2993d70c4b4Schristos int
3003d70c4b4Schristos sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval)
3013d70c4b4Schristos {
3023d70c4b4Schristos 	/* {
3033d70c4b4Schristos 		syscallarg(pid_t)	pid;
3043d70c4b4Schristos 		syscallarg(int)	signum;
3053d70c4b4Schristos 	} */
3063d70c4b4Schristos 	ksiginfo_t	ksi;
3073d70c4b4Schristos 
3083d70c4b4Schristos 	KSI_INIT(&ksi);
3093d70c4b4Schristos 
3103d70c4b4Schristos 	ksi.ksi_signo = SCARG(uap, signum);
3113d70c4b4Schristos 	ksi.ksi_code = SI_USER;
3123d70c4b4Schristos 	ksi.ksi_pid = l->l_proc->p_pid;
3133d70c4b4Schristos 	ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
3143d70c4b4Schristos 
3153d70c4b4Schristos 	return kill1(l, SCARG(uap, pid), &ksi, retval);
3163d70c4b4Schristos }
3173d70c4b4Schristos 
3183d70c4b4Schristos int
3193c74cdf1Srmind sys_getcontext(struct lwp *l, const struct sys_getcontext_args *uap,
3203c74cdf1Srmind     register_t *retval)
321b07ec3fcSad {
3227e2790cfSdsl 	/* {
323b07ec3fcSad 		syscallarg(struct __ucontext *) ucp;
3247e2790cfSdsl 	} */
325b07ec3fcSad 	struct proc *p = l->l_proc;
326b07ec3fcSad 	ucontext_t uc;
327b07ec3fcSad 
32813011308Sjoerg 	memset(&uc, 0, sizeof(uc));
32913011308Sjoerg 
330284c2b9aSad 	mutex_enter(p->p_lock);
331b07ec3fcSad 	getucontext(l, &uc);
332284c2b9aSad 	mutex_exit(p->p_lock);
333b07ec3fcSad 
3343c74cdf1Srmind 	return copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp)));
335b07ec3fcSad }
336b07ec3fcSad 
337b07ec3fcSad int
3383c74cdf1Srmind sys_setcontext(struct lwp *l, const struct sys_setcontext_args *uap,
3393c74cdf1Srmind     register_t *retval)
340b07ec3fcSad {
3417e2790cfSdsl 	/* {
342b07ec3fcSad 		syscallarg(const ucontext_t *) ucp;
3437e2790cfSdsl 	} */
344b07ec3fcSad 	struct proc *p = l->l_proc;
345b07ec3fcSad 	ucontext_t uc;
346b07ec3fcSad 	int error;
347b07ec3fcSad 
348b07ec3fcSad 	error = copyin(SCARG(uap, ucp), &uc, sizeof (uc));
349b07ec3fcSad 	if (error)
3503c74cdf1Srmind 		return error;
3513c74cdf1Srmind 	if ((uc.uc_flags & _UC_CPU) == 0)
3523c74cdf1Srmind 		return EINVAL;
353284c2b9aSad 	mutex_enter(p->p_lock);
354b07ec3fcSad 	error = setucontext(l, &uc);
355284c2b9aSad 	mutex_exit(p->p_lock);
356b07ec3fcSad 	if (error)
3573c74cdf1Srmind  		return error;
358b07ec3fcSad 
3593c74cdf1Srmind 	return EJUSTRETURN;
360b07ec3fcSad }
361b07ec3fcSad 
362b07ec3fcSad /*
363b07ec3fcSad  * sigtimedwait(2) system call, used also for implementation
364b07ec3fcSad  * of sigwaitinfo() and sigwait().
365b07ec3fcSad  *
366b07ec3fcSad  * This only handles single LWP in signal wait. libpthread provides
367f0a7346dSsnj  * its own sigtimedwait() wrapper to DTRT WRT individual threads.
368b07ec3fcSad  */
369b07ec3fcSad int
370461a86f9Schristos sys_____sigtimedwait50(struct lwp *l,
371461a86f9Schristos     const struct sys_____sigtimedwait50_args *uap, register_t *retval)
372b07ec3fcSad {
373b07ec3fcSad 
374d8bca0f2Schristos 	return sigtimedwait1(l, uap, retval, copyin, copyout, copyin, copyout);
375b07ec3fcSad }
376b07ec3fcSad 
377b07ec3fcSad int
378b07ec3fcSad sigaction1(struct lwp *l, int signum, const struct sigaction *nsa,
379b07ec3fcSad 	struct sigaction *osa, const void *tramp, int vers)
380b07ec3fcSad {
381b07ec3fcSad 	struct proc *p;
382b07ec3fcSad 	struct sigacts *ps;
383b07ec3fcSad 	sigset_t tset;
384b07ec3fcSad 	int prop, error;
385b07ec3fcSad 	ksiginfoq_t kq;
3869d09ecfaSad 	static bool v0v1valid;
387b07ec3fcSad 
388b07ec3fcSad 	if (signum <= 0 || signum >= NSIG)
3893c74cdf1Srmind 		return EINVAL;
390b07ec3fcSad 
391b07ec3fcSad 	p = l->l_proc;
392b07ec3fcSad 	error = 0;
393b07ec3fcSad 	ksiginfo_queue_init(&kq);
394b07ec3fcSad 
395b07ec3fcSad 	/*
396b07ec3fcSad 	 * Trampoline ABI version 0 is reserved for the legacy kernel
397b07ec3fcSad 	 * provided on-stack trampoline.  Conversely, if we are using a
398b07ec3fcSad 	 * non-0 ABI version, we must have a trampoline.  Only validate the
399b9e9a610Schristos 	 * vers if a new sigaction was supplied and there was an actual
400b9e9a610Schristos 	 * handler specified (not SIG_IGN or SIG_DFL), which don't require
401b9e9a610Schristos 	 * a trampoline. Emulations use legacy kernel trampolines with
402b9e9a610Schristos 	 * version 0, alternatively check for that too.
40392ce8c6aSad 	 *
40492ce8c6aSad 	 * If version < 2, we try to autoload the compat module.  Note
40592ce8c6aSad 	 * that we interlock with the unload check in compat_modcmd()
40623d5409eSpgoyette 	 * using kernconfig_lock.  If the autoload fails, we don't try it
40792ce8c6aSad 	 * again for this process.
408b07ec3fcSad 	 */
409b9e9a610Schristos 	if (nsa != NULL && nsa->sa_handler != SIG_IGN
410b9e9a610Schristos 	    && nsa->sa_handler != SIG_DFL) {
411131cc4dfSchristos 		if (__predict_false(vers < 2)) {
412131cc4dfSchristos 			if (p->p_flag & PK_32)
413131cc4dfSchristos 				v0v1valid = true;
414131cc4dfSchristos 			else if ((p->p_lflag & PL_SIGCOMPAT) == 0) {
41523d5409eSpgoyette 				kernconfig_lock();
41692ce8c6aSad 				if (sendsig_sigcontext_vec == NULL) {
4179d09ecfaSad 					(void)module_autoload("compat",
4189d09ecfaSad 					    MODULE_CLASS_ANY);
4199d09ecfaSad 				}
4209d09ecfaSad 				if (sendsig_sigcontext_vec != NULL) {
4219d09ecfaSad 					/*
4229d09ecfaSad 					 * We need to remember if the
4239d09ecfaSad 					 * sigcontext method may be useable,
4249d09ecfaSad 					 * because libc may use it even
4259d09ecfaSad 					 * if siginfo is available.
4269d09ecfaSad 					 */
4279d09ecfaSad 					v0v1valid = true;
42892ce8c6aSad 				}
42992ce8c6aSad 				mutex_enter(proc_lock);
4309d09ecfaSad 				/*
4319d09ecfaSad 				 * Prevent unload of compat module while
4329d09ecfaSad 				 * this process remains.
4339d09ecfaSad 				 */
43492ce8c6aSad 				p->p_lflag |= PL_SIGCOMPAT;
43592ce8c6aSad 				mutex_exit(proc_lock);
43623d5409eSpgoyette 				kernconfig_unlock();
43792ce8c6aSad 			}
438131cc4dfSchristos 		}
43992ce8c6aSad 
4409d09ecfaSad 		switch (vers) {
4419d09ecfaSad 		case 0:
4429d09ecfaSad 			/* sigcontext, kernel supplied trampoline. */
4439d09ecfaSad 			if (tramp != NULL || !v0v1valid) {
44492ce8c6aSad 				return EINVAL;
44592ce8c6aSad 			}
4469d09ecfaSad 			break;
4479d09ecfaSad 		case 1:
4489d09ecfaSad 			/* sigcontext, user supplied trampoline. */
4499d09ecfaSad 			if (tramp == NULL || !v0v1valid) {
45092ce8c6aSad 				return EINVAL;
451b07ec3fcSad 			}
4529d09ecfaSad 			break;
4539d09ecfaSad 		case 2:
4549d09ecfaSad 		case 3:
4559d09ecfaSad 			/* siginfo, user supplied trampoline. */
4569d09ecfaSad 			if (tramp == NULL) {
4579d09ecfaSad 				return EINVAL;
4589d09ecfaSad 			}
4599d09ecfaSad 			break;
4609d09ecfaSad 		default:
4619d09ecfaSad 			return EINVAL;
4629d09ecfaSad 		}
4639d09ecfaSad 	}
464b07ec3fcSad 
465284c2b9aSad 	mutex_enter(p->p_lock);
466b07ec3fcSad 
467b07ec3fcSad 	ps = p->p_sigacts;
468b07ec3fcSad 	if (osa)
469b07ec3fcSad 		*osa = SIGACTION_PS(ps, signum);
470b07ec3fcSad 	if (!nsa)
471b07ec3fcSad 		goto out;
472b07ec3fcSad 
473b07ec3fcSad 	prop = sigprop[signum];
474b07ec3fcSad 	if ((nsa->sa_flags & ~SA_ALLBITS) || (prop & SA_CANTMASK)) {
475b07ec3fcSad 		error = EINVAL;
476b07ec3fcSad 		goto out;
477b07ec3fcSad 	}
478b07ec3fcSad 
479b07ec3fcSad 	SIGACTION_PS(ps, signum) = *nsa;
480b07ec3fcSad 	ps->sa_sigdesc[signum].sd_tramp = tramp;
481b07ec3fcSad 	ps->sa_sigdesc[signum].sd_vers = vers;
482b07ec3fcSad 	sigminusset(&sigcantmask, &SIGACTION_PS(ps, signum).sa_mask);
483b07ec3fcSad 
484b07ec3fcSad 	if ((prop & SA_NORESET) != 0)
485b07ec3fcSad 		SIGACTION_PS(ps, signum).sa_flags &= ~SA_RESETHAND;
486b07ec3fcSad 
487b07ec3fcSad 	if (signum == SIGCHLD) {
488b07ec3fcSad 		if (nsa->sa_flags & SA_NOCLDSTOP)
489b07ec3fcSad 			p->p_sflag |= PS_NOCLDSTOP;
490b07ec3fcSad 		else
491b07ec3fcSad 			p->p_sflag &= ~PS_NOCLDSTOP;
492b07ec3fcSad 		if (nsa->sa_flags & SA_NOCLDWAIT) {
493b07ec3fcSad 			/*
494b07ec3fcSad 			 * Paranoia: since SA_NOCLDWAIT is implemented by
495b07ec3fcSad 			 * reparenting the dying child to PID 1 (and trust
496b07ec3fcSad 			 * it to reap the zombie), PID 1 itself is forbidden
497b07ec3fcSad 			 * to set SA_NOCLDWAIT.
498b07ec3fcSad 			 */
499b07ec3fcSad 			if (p->p_pid == 1)
500934634a1Spavel 				p->p_flag &= ~PK_NOCLDWAIT;
501b07ec3fcSad 			else
502934634a1Spavel 				p->p_flag |= PK_NOCLDWAIT;
503b07ec3fcSad 		} else
504934634a1Spavel 			p->p_flag &= ~PK_NOCLDWAIT;
505b07ec3fcSad 
506b07ec3fcSad 		if (nsa->sa_handler == SIG_IGN) {
507b07ec3fcSad 			/*
508b07ec3fcSad 			 * Paranoia: same as above.
509b07ec3fcSad 			 */
510b07ec3fcSad 			if (p->p_pid == 1)
511934634a1Spavel 				p->p_flag &= ~PK_CLDSIGIGN;
512b07ec3fcSad 			else
513934634a1Spavel 				p->p_flag |= PK_CLDSIGIGN;
514b07ec3fcSad 		} else
515934634a1Spavel 			p->p_flag &= ~PK_CLDSIGIGN;
516b07ec3fcSad 	}
517b07ec3fcSad 
518b07ec3fcSad 	if ((nsa->sa_flags & SA_NODEFER) == 0)
519b07ec3fcSad 		sigaddset(&SIGACTION_PS(ps, signum).sa_mask, signum);
520b07ec3fcSad 	else
521b07ec3fcSad 		sigdelset(&SIGACTION_PS(ps, signum).sa_mask, signum);
522b07ec3fcSad 
523b07ec3fcSad 	/*
524b07ec3fcSad 	 * Set bit in p_sigctx.ps_sigignore for signals that are set to
525b07ec3fcSad 	 * SIG_IGN, and for signals set to SIG_DFL where the default is to
526b07ec3fcSad 	 * ignore. However, don't put SIGCONT in p_sigctx.ps_sigignore, as
527b07ec3fcSad 	 * we have to restart the process.
528b07ec3fcSad 	 */
529b07ec3fcSad 	if (nsa->sa_handler == SIG_IGN ||
530b07ec3fcSad 	    (nsa->sa_handler == SIG_DFL && (prop & SA_IGNORE) != 0)) {
531b07ec3fcSad 		/* Never to be seen again. */
532b07ec3fcSad 		sigemptyset(&tset);
533b07ec3fcSad 		sigaddset(&tset, signum);
534b07ec3fcSad 		sigclearall(p, &tset, &kq);
535b07ec3fcSad 		if (signum != SIGCONT) {
536b07ec3fcSad 			/* Easier in psignal */
537b07ec3fcSad 			sigaddset(&p->p_sigctx.ps_sigignore, signum);
538b07ec3fcSad 		}
539b07ec3fcSad 		sigdelset(&p->p_sigctx.ps_sigcatch, signum);
540b07ec3fcSad 	} else {
541b07ec3fcSad 		sigdelset(&p->p_sigctx.ps_sigignore, signum);
542b07ec3fcSad 		if (nsa->sa_handler == SIG_DFL)
543b07ec3fcSad 			sigdelset(&p->p_sigctx.ps_sigcatch, signum);
544b07ec3fcSad 		else
545b07ec3fcSad 			sigaddset(&p->p_sigctx.ps_sigcatch, signum);
546b07ec3fcSad 	}
547b07ec3fcSad 
548b07ec3fcSad 	/*
549b07ec3fcSad 	 * Previously held signals may now have become visible.  Ensure that
550b07ec3fcSad 	 * we check for them before returning to userspace.
551b07ec3fcSad 	 */
552a76d1d29Sad 	if (sigispending(l, 0)) {
553b07ec3fcSad 		lwp_lock(l);
554934634a1Spavel 		l->l_flag |= LW_PENDSIG;
555b07ec3fcSad 		lwp_unlock(l);
556a76d1d29Sad 	}
557b07ec3fcSad out:
558284c2b9aSad 	mutex_exit(p->p_lock);
559b07ec3fcSad 	ksiginfo_queue_drain(&kq);
560b07ec3fcSad 
5613c74cdf1Srmind 	return error;
562b07ec3fcSad }
563b07ec3fcSad 
564b07ec3fcSad int
565b07ec3fcSad sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
566b07ec3fcSad {
567ad12c770Srmind 	sigset_t *mask = &l->l_sigmask;
568ad12c770Srmind 	bool more;
569b07ec3fcSad 
570ad12c770Srmind 	KASSERT(mutex_owned(l->l_proc->p_lock));
571b07ec3fcSad 
572ad12c770Srmind 	if (oss) {
573fc7511b0Swrstuden 		*oss = *mask;
574ad12c770Srmind 	}
575ad12c770Srmind 
576ad12c770Srmind 	if (nss == NULL) {
577ad12c770Srmind 		return 0;
578ad12c770Srmind 	}
579ad12c770Srmind 
580b07ec3fcSad 	switch (how) {
581b07ec3fcSad 	case SIG_BLOCK:
582fc7511b0Swrstuden 		sigplusset(nss, mask);
583ad12c770Srmind 		more = false;
584b07ec3fcSad 		break;
585b07ec3fcSad 	case SIG_UNBLOCK:
586fc7511b0Swrstuden 		sigminusset(nss, mask);
587ad12c770Srmind 		more = true;
588b07ec3fcSad 		break;
589b07ec3fcSad 	case SIG_SETMASK:
590fc7511b0Swrstuden 		*mask = *nss;
591ad12c770Srmind 		more = true;
592b07ec3fcSad 		break;
593b07ec3fcSad 	default:
594ad12c770Srmind 		return EINVAL;
595b07ec3fcSad 	}
596fc7511b0Swrstuden 	sigminusset(&sigcantmask, mask);
597a76d1d29Sad 	if (more && sigispending(l, 0)) {
598b07ec3fcSad 		/*
599b07ec3fcSad 		 * Check for pending signals on return to user.
600b07ec3fcSad 		 */
601b07ec3fcSad 		lwp_lock(l);
602934634a1Spavel 		l->l_flag |= LW_PENDSIG;
603b07ec3fcSad 		lwp_unlock(l);
604b07ec3fcSad 	}
6053c74cdf1Srmind 	return 0;
606b07ec3fcSad }
607b07ec3fcSad 
608b07ec3fcSad void
609b07ec3fcSad sigpending1(struct lwp *l, sigset_t *ss)
610b07ec3fcSad {
611b07ec3fcSad 	struct proc *p = l->l_proc;
612b07ec3fcSad 
613284c2b9aSad 	mutex_enter(p->p_lock);
614b07ec3fcSad 	*ss = l->l_sigpend.sp_set;
615b07ec3fcSad 	sigplusset(&p->p_sigpend.sp_set, ss);
616284c2b9aSad 	mutex_exit(p->p_lock);
617b07ec3fcSad }
618b07ec3fcSad 
619e2543d03Schristos void
620e2543d03Schristos sigsuspendsetup(struct lwp *l, const sigset_t *ss)
621b07ec3fcSad {
6223c74cdf1Srmind 	struct proc *p = l->l_proc;
623b07ec3fcSad 
624b07ec3fcSad 	/*
625e2543d03Schristos 	 * When returning from sigsuspend/pselect/pollts, we want
626b07ec3fcSad 	 * the old mask to be restored after the
627b07ec3fcSad 	 * signal handler has finished.  Thus, we
628b07ec3fcSad 	 * save it here and mark the sigctx structure
629b07ec3fcSad 	 * to indicate this.
630b07ec3fcSad 	 */
631284c2b9aSad 	mutex_enter(p->p_lock);
632b07ec3fcSad 	l->l_sigrestore = 1;
633b07ec3fcSad 	l->l_sigoldmask = l->l_sigmask;
634b07ec3fcSad 	l->l_sigmask = *ss;
635b07ec3fcSad 	sigminusset(&sigcantmask, &l->l_sigmask);
636b07ec3fcSad 
637b07ec3fcSad 	/* Check for pending signals when sleeping. */
638a76d1d29Sad 	if (sigispending(l, 0)) {
639b07ec3fcSad 		lwp_lock(l);
640934634a1Spavel 		l->l_flag |= LW_PENDSIG;
641b07ec3fcSad 		lwp_unlock(l);
642a76d1d29Sad 	}
643284c2b9aSad 	mutex_exit(p->p_lock);
644b07ec3fcSad }
645b07ec3fcSad 
6460b60c7beSchristos void
6470b60c7beSchristos sigsuspendteardown(struct lwp *l)
6480b60c7beSchristos {
6490b60c7beSchristos 	struct proc *p = l->l_proc;
6500b60c7beSchristos 
6510b60c7beSchristos 	mutex_enter(p->p_lock);
65241ceba00Schristos 	/* Check for pending signals when sleeping. */
6530b60c7beSchristos 	if (l->l_sigrestore) {
65441ceba00Schristos 		if (sigispending(l, 0)) {
65541ceba00Schristos 			lwp_lock(l);
65641ceba00Schristos 			l->l_flag |= LW_PENDSIG;
65741ceba00Schristos 			lwp_unlock(l);
65841ceba00Schristos 		} else {
6590b60c7beSchristos 			l->l_sigrestore = 0;
6600b60c7beSchristos 			l->l_sigmask = l->l_sigoldmask;
6610b60c7beSchristos 		}
66241ceba00Schristos 	}
6630b60c7beSchristos 	mutex_exit(p->p_lock);
6640b60c7beSchristos }
6650b60c7beSchristos 
666e2543d03Schristos int
667e2543d03Schristos sigsuspend1(struct lwp *l, const sigset_t *ss)
668e2543d03Schristos {
669e2543d03Schristos 
670e2543d03Schristos 	if (ss)
671e2543d03Schristos 		sigsuspendsetup(l, ss);
672e2543d03Schristos 
6734f3d5a9cSthorpej 	while (kpause("pause", true, 0, NULL) == 0)
674b07ec3fcSad 		;
675b07ec3fcSad 
676b07ec3fcSad 	/* always return EINTR rather than ERESTART... */
6773c74cdf1Srmind 	return EINTR;
678b07ec3fcSad }
679b07ec3fcSad 
680b07ec3fcSad int
681b07ec3fcSad sigaltstack1(struct lwp *l, const struct sigaltstack *nss,
682b07ec3fcSad     struct sigaltstack *oss)
683b07ec3fcSad {
684b07ec3fcSad 	struct proc *p = l->l_proc;
685b07ec3fcSad 	int error = 0;
686b07ec3fcSad 
687284c2b9aSad 	mutex_enter(p->p_lock);
688b07ec3fcSad 
689b07ec3fcSad 	if (oss)
690b07ec3fcSad 		*oss = l->l_sigstk;
691b07ec3fcSad 
692b07ec3fcSad 	if (nss) {
693b07ec3fcSad 		if (nss->ss_flags & ~SS_ALLBITS)
694b07ec3fcSad 			error = EINVAL;
695b07ec3fcSad 		else if (nss->ss_flags & SS_DISABLE) {
696b07ec3fcSad 			if (l->l_sigstk.ss_flags & SS_ONSTACK)
697b07ec3fcSad 				error = EINVAL;
698b07ec3fcSad 		} else if (nss->ss_size < MINSIGSTKSZ)
699b07ec3fcSad 			error = ENOMEM;
700b07ec3fcSad 
701b07ec3fcSad 		if (!error)
702b07ec3fcSad 			l->l_sigstk = *nss;
703b07ec3fcSad 	}
704b07ec3fcSad 
705284c2b9aSad 	mutex_exit(p->p_lock);
706b07ec3fcSad 
7073c74cdf1Srmind 	return error;
708b07ec3fcSad }
709b07ec3fcSad 
710b07ec3fcSad int
711654415b2Spooka sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
712d8bca0f2Schristos     register_t *retval, copyin_t fetchss, copyout_t storeinf, copyin_t fetchts,
713d8bca0f2Schristos     copyout_t storets)
714b07ec3fcSad {
7157e2790cfSdsl 	/* {
716b07ec3fcSad 		syscallarg(const sigset_t *) set;
717b07ec3fcSad 		syscallarg(siginfo_t *) info;
718b07ec3fcSad 		syscallarg(struct timespec *) timeout;
7197e2790cfSdsl 	} */
720b07ec3fcSad 	struct proc *p = l->l_proc;
7213c74cdf1Srmind 	int error, signum, timo;
722b07ec3fcSad 	struct timespec ts, tsstart, tsnow;
723ebd0ab14Srmind 	ksiginfo_t ksi;
724b07ec3fcSad 
725b07ec3fcSad 	/*
726b07ec3fcSad 	 * Calculate timeout, if it was specified.
7277c5d63e1Sapb 	 *
7287c5d63e1Sapb 	 * NULL pointer means an infinite timeout.
7297c5d63e1Sapb 	 * {.tv_sec = 0, .tv_nsec = 0} means do not block.
730b07ec3fcSad 	 */
731b07ec3fcSad 	if (SCARG(uap, timeout)) {
7323c74cdf1Srmind 		error = (*fetchts)(SCARG(uap, timeout), &ts, sizeof(ts));
7336e1db6ceSchristos 		if (error)
7346e1db6ceSchristos 			return error;
735b07ec3fcSad 
7366e1db6ceSchristos 		if ((error = itimespecfix(&ts)) != 0)
7376e1db6ceSchristos 			return error;
738b07ec3fcSad 
7396e1db6ceSchristos 		timo = tstohz(&ts);
740f92c0e46Sapb 		if (timo == 0) {
741f92c0e46Sapb 			if (ts.tv_sec == 0 && ts.tv_nsec == 0)
742f92c0e46Sapb 				timo = -1; /* do not block */
743f92c0e46Sapb 			else
744f92c0e46Sapb 				timo = 1; /* the shortest possible timeout */
745f92c0e46Sapb 		}
746b07ec3fcSad 
747b07ec3fcSad 		/*
748b07ec3fcSad 		 * Remember current uptime, it would be used in
749b07ec3fcSad 		 * ECANCELED/ERESTART case.
750b07ec3fcSad 		 */
751b07ec3fcSad 		getnanouptime(&tsstart);
7523c74cdf1Srmind 	} else {
7533c74cdf1Srmind 		memset(&tsstart, 0, sizeof(tsstart)); /* XXXgcc */
754f92c0e46Sapb 		timo = 0; /* infinite timeout */
755b07ec3fcSad 	}
756b07ec3fcSad 
757d8bca0f2Schristos 	error = (*fetchss)(SCARG(uap, set), &l->l_sigwaitset,
758b07ec3fcSad 	    sizeof(l->l_sigwaitset));
7593c74cdf1Srmind 	if (error)
7603c74cdf1Srmind 		return error;
761b07ec3fcSad 
762b07ec3fcSad 	/*
763b07ec3fcSad 	 * Silently ignore SA_CANTMASK signals. psignal1() would ignore
764b07ec3fcSad 	 * SA_CANTMASK signals in waitset, we do this only for the below
765b07ec3fcSad 	 * siglist check.
766b07ec3fcSad 	 */
767b07ec3fcSad 	sigminusset(&sigcantmask, &l->l_sigwaitset);
768b07ec3fcSad 
769284c2b9aSad 	mutex_enter(p->p_lock);
770b07ec3fcSad 
7713c74cdf1Srmind 	/* Check for pending signals in the process, if no - then in LWP. */
772ebd0ab14Srmind 	if ((signum = sigget(&p->p_sigpend, &ksi, 0, &l->l_sigwaitset)) == 0)
773ebd0ab14Srmind 		signum = sigget(&l->l_sigpend, &ksi, 0, &l->l_sigwaitset);
774b07ec3fcSad 
775b07ec3fcSad 	if (signum != 0) {
7763c74cdf1Srmind 		/* If found a pending signal, just copy it out to the user. */
777284c2b9aSad 		mutex_exit(p->p_lock);
778b07ec3fcSad 		goto out;
779b07ec3fcSad 	}
780b07ec3fcSad 
781f92c0e46Sapb 	if (timo < 0) {
782f92c0e46Sapb 		/* If not allowed to block, return an error */
783f92c0e46Sapb 		mutex_exit(p->p_lock);
784f92c0e46Sapb 		return EAGAIN;
785f92c0e46Sapb 	}
786f92c0e46Sapb 
787b07ec3fcSad 	/*
7883c74cdf1Srmind 	 * Set up the sigwait list and wait for signal to arrive.
7893c74cdf1Srmind 	 * We can either be woken up or time out.
790b07ec3fcSad 	 */
791ebd0ab14Srmind 	l->l_sigwaited = &ksi;
792b07ec3fcSad 	LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter);
793284c2b9aSad 	error = cv_timedwait_sig(&l->l_sigcv, p->p_lock, timo);
794b07ec3fcSad 
795b07ec3fcSad 	/*
7963c74cdf1Srmind 	 * Need to find out if we woke as a result of _lwp_wakeup() or a
797b07ec3fcSad 	 * signal outside our wait set.
798b07ec3fcSad 	 */
799b07ec3fcSad 	if (l->l_sigwaited != NULL) {
800b07ec3fcSad 		if (error == EINTR) {
8013c74cdf1Srmind 			/* Wakeup via _lwp_wakeup(). */
802b07ec3fcSad 			error = ECANCELED;
803b07ec3fcSad 		} else if (!error) {
8043c74cdf1Srmind 			/* Spurious wakeup - arrange for syscall restart. */
805b07ec3fcSad 			error = ERESTART;
806b07ec3fcSad 		}
807b07ec3fcSad 		l->l_sigwaited = NULL;
808b07ec3fcSad 		LIST_REMOVE(l, l_sigwaiter);
809b07ec3fcSad 	}
810284c2b9aSad 	mutex_exit(p->p_lock);
811b07ec3fcSad 
812b07ec3fcSad 	/*
813b07ec3fcSad 	 * If the sleep was interrupted (either by signal or wakeup), update
814b07ec3fcSad 	 * the timeout and copyout new value back.  It would be used when
815b07ec3fcSad 	 * the syscall would be restarted or called again.
816b07ec3fcSad 	 */
817b07ec3fcSad 	if (timo && (error == ERESTART || error == ECANCELED)) {
818b07ec3fcSad 		getnanouptime(&tsnow);
819b07ec3fcSad 
8203c74cdf1Srmind 		/* Compute how much time has passed since start. */
821b07ec3fcSad 		timespecsub(&tsnow, &tsstart, &tsnow);
8223c74cdf1Srmind 
8233c74cdf1Srmind 		/* Substract passed time from timeout. */
824b07ec3fcSad 		timespecsub(&ts, &tsnow, &ts);
825b07ec3fcSad 
826b07ec3fcSad 		if (ts.tv_sec < 0)
827b07ec3fcSad 			error = EAGAIN;
828b07ec3fcSad 		else {
8293c74cdf1Srmind 			/* Copy updated timeout to userland. */
8303c74cdf1Srmind 			error = (*storets)(&ts, SCARG(uap, timeout),
831b07ec3fcSad 			    sizeof(ts));
832b07ec3fcSad 		}
833b07ec3fcSad 	}
8343c74cdf1Srmind out:
835b07ec3fcSad 	/*
836b07ec3fcSad 	 * If a signal from the wait set arrived, copy it to userland.
837b07ec3fcSad 	 * Copy only the used part of siginfo, the padding part is
838b07ec3fcSad 	 * left unchanged (userland is not supposed to touch it anyway).
839b07ec3fcSad 	 */
8408239dc73Sdrochner 	if (error == 0 && SCARG(uap, info)) {
8413c74cdf1Srmind 		error = (*storeinf)(&ksi.ksi_info, SCARG(uap, info),
842ebd0ab14Srmind 		    sizeof(ksi.ksi_info));
8433c74cdf1Srmind 	}
844*db70f181Schristos 	if (error == 0) {
8458239dc73Sdrochner 		*retval = ksi.ksi_info._signo;
846*db70f181Schristos 		SDT_PROBE(proc, kernel, , signal__clear, *retval,
847*db70f181Schristos 		    &ksi, 0, 0, 0);
848*db70f181Schristos 	}
849b07ec3fcSad 	return error;
850b07ec3fcSad }
851