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