Home | History | Annotate | Line # | Download | only in common
linux_signal.c revision 1.8
      1  1.8   thorpej /*	$NetBSD: linux_signal.c,v 1.8 1995/09/19 22:37:34 thorpej Exp $	*/
      2  1.1      fvdl 
      3  1.1      fvdl /*
      4  1.1      fvdl  * Copyright (c) 1995 Frank van der Linden
      5  1.1      fvdl  * All rights reserved.
      6  1.1      fvdl  *
      7  1.1      fvdl  * Redistribution and use in source and binary forms, with or without
      8  1.1      fvdl  * modification, are permitted provided that the following conditions
      9  1.1      fvdl  * are met:
     10  1.1      fvdl  * 1. Redistributions of source code must retain the above copyright
     11  1.1      fvdl  *    notice, this list of conditions and the following disclaimer.
     12  1.1      fvdl  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1      fvdl  *    notice, this list of conditions and the following disclaimer in the
     14  1.1      fvdl  *    documentation and/or other materials provided with the distribution.
     15  1.1      fvdl  * 3. All advertising materials mentioning features or use of this software
     16  1.1      fvdl  *    must display the following acknowledgement:
     17  1.1      fvdl  *      This product includes software developed for the NetBSD Project
     18  1.1      fvdl  *      by Frank van der Linden
     19  1.1      fvdl  * 4. The name of the author may not be used to endorse or promote products
     20  1.1      fvdl  *    derived from this software without specific prior written permission
     21  1.1      fvdl  *
     22  1.1      fvdl  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  1.1      fvdl  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  1.1      fvdl  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  1.1      fvdl  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  1.1      fvdl  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  1.1      fvdl  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  1.1      fvdl  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  1.1      fvdl  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  1.1      fvdl  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  1.1      fvdl  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  1.1      fvdl  *
     33  1.1      fvdl  * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
     34  1.1      fvdl  */
     35  1.1      fvdl 
     36  1.1      fvdl #include <sys/param.h>
     37  1.1      fvdl #include <sys/systm.h>
     38  1.1      fvdl #include <sys/namei.h>
     39  1.1      fvdl #include <sys/proc.h>
     40  1.1      fvdl #include <sys/filedesc.h>
     41  1.1      fvdl #include <sys/ioctl.h>
     42  1.1      fvdl #include <sys/mount.h>
     43  1.1      fvdl #include <sys/kernel.h>
     44  1.1      fvdl #include <sys/signal.h>
     45  1.1      fvdl #include <sys/signalvar.h>
     46  1.1      fvdl #include <sys/malloc.h>
     47  1.1      fvdl 
     48  1.1      fvdl #include <sys/syscallargs.h>
     49  1.1      fvdl 
     50  1.1      fvdl #include <compat/linux/linux_types.h>
     51  1.7   mycroft #include <compat/linux/linux_signal.h>
     52  1.1      fvdl #include <compat/linux/linux_syscallargs.h>
     53  1.1      fvdl #include <compat/linux/linux_util.h>
     54  1.1      fvdl 
     55  1.6   mycroft #define	sigemptyset(s)		bzero((s), sizeof(*(s)))
     56  1.6   mycroft #define	sigismember(s, n)	(*(s) & sigmask(n))
     57  1.6   mycroft #define	sigaddset(s, n)		(*(s) |= sigmask(n))
     58  1.6   mycroft 
     59  1.6   mycroft #define	linux_sigmask(n)	(1 << ((n) - 1))
     60  1.6   mycroft #define	linux_sigemptyset(s)	bzero((s), sizeof(*(s)))
     61  1.6   mycroft #define	linux_sigismember(s, n)	(*(s) & linux_sigmask(n))
     62  1.6   mycroft #define	linux_sigaddset(s, n)	(*(s) |= linux_sigmask(n))
     63  1.6   mycroft 
     64  1.6   mycroft int bsd_to_linux_sig[] = {
     65  1.6   mycroft 	0,
     66  1.6   mycroft 	LINUX_SIGHUP,
     67  1.6   mycroft 	LINUX_SIGINT,
     68  1.6   mycroft 	LINUX_SIGQUIT,
     69  1.6   mycroft 	LINUX_SIGILL,
     70  1.6   mycroft 	LINUX_SIGTRAP,
     71  1.6   mycroft 	LINUX_SIGABRT,
     72  1.6   mycroft 	0,
     73  1.6   mycroft 	LINUX_SIGFPE,
     74  1.6   mycroft 	LINUX_SIGKILL,
     75  1.6   mycroft 	LINUX_SIGBUS,
     76  1.6   mycroft 	LINUX_SIGSEGV,
     77  1.6   mycroft 	0,
     78  1.6   mycroft 	LINUX_SIGPIPE,
     79  1.6   mycroft 	LINUX_SIGALRM,
     80  1.6   mycroft 	LINUX_SIGTERM,
     81  1.6   mycroft 	LINUX_SIGURG,
     82  1.6   mycroft 	LINUX_SIGSTOP,
     83  1.6   mycroft 	LINUX_SIGTSTP,
     84  1.6   mycroft 	LINUX_SIGCONT,
     85  1.6   mycroft 	LINUX_SIGCHLD,
     86  1.6   mycroft 	LINUX_SIGTTIN,
     87  1.6   mycroft 	LINUX_SIGTTOU,
     88  1.6   mycroft 	LINUX_SIGIO,
     89  1.6   mycroft 	LINUX_SIGXCPU,
     90  1.6   mycroft 	LINUX_SIGXFSZ,
     91  1.6   mycroft 	LINUX_SIGVTALRM,
     92  1.6   mycroft 	LINUX_SIGPROF,
     93  1.6   mycroft 	LINUX_SIGWINCH,
     94  1.6   mycroft 	0,
     95  1.6   mycroft 	LINUX_SIGUSR1,
     96  1.6   mycroft 	LINUX_SIGUSR2,
     97  1.6   mycroft };
     98  1.6   mycroft 
     99  1.6   mycroft int linux_to_bsd_sig[] = {
    100  1.6   mycroft 	0,
    101  1.6   mycroft 	SIGHUP,
    102  1.6   mycroft 	SIGINT,
    103  1.6   mycroft 	SIGQUIT,
    104  1.6   mycroft 	SIGILL,
    105  1.6   mycroft 	SIGTRAP,
    106  1.6   mycroft 	SIGABRT,
    107  1.6   mycroft 	SIGBUS,
    108  1.6   mycroft 	SIGFPE,
    109  1.6   mycroft 	SIGKILL,
    110  1.6   mycroft 	SIGUSR1,
    111  1.6   mycroft 	SIGSEGV,
    112  1.6   mycroft 	SIGUSR2,
    113  1.6   mycroft 	SIGPIPE,
    114  1.6   mycroft 	SIGALRM,
    115  1.6   mycroft 	SIGTERM,
    116  1.6   mycroft 	0,
    117  1.6   mycroft 	SIGCHLD,
    118  1.6   mycroft 	SIGCONT,
    119  1.6   mycroft 	SIGSTOP,
    120  1.6   mycroft 	SIGTSTP,
    121  1.6   mycroft 	SIGTTIN,
    122  1.6   mycroft 	SIGTTOU,
    123  1.6   mycroft 	SIGURG,
    124  1.6   mycroft 	SIGXCPU,
    125  1.6   mycroft 	SIGXFSZ,
    126  1.6   mycroft 	SIGVTALRM,
    127  1.6   mycroft 	SIGPROF,
    128  1.6   mycroft 	SIGWINCH,
    129  1.6   mycroft 	SIGIO,
    130  1.6   mycroft 	0,
    131  1.6   mycroft 	0,
    132  1.6   mycroft };
    133  1.1      fvdl 
    134  1.1      fvdl /*
    135  1.1      fvdl  * Ok, we know that Linux and BSD signals both are just an unsigned int.
    136  1.1      fvdl  * Don't bother to use the sigismember() stuff for now.
    137  1.1      fvdl  */
    138  1.6   mycroft void
    139  1.1      fvdl linux_to_bsd_sigset(lss, bss)
    140  1.1      fvdl 	const linux_sigset_t *lss;
    141  1.1      fvdl 	sigset_t *bss;
    142  1.1      fvdl {
    143  1.1      fvdl 	int i, newsig;
    144  1.1      fvdl 
    145  1.6   mycroft 	sigemptyset(bss);
    146  1.6   mycroft 	for (i = 1; i < LINUX_NSIG; i++) {
    147  1.6   mycroft 		if (linux_sigismember(lss, i)) {
    148  1.6   mycroft 			newsig = linux_to_bsd_sig[i];
    149  1.1      fvdl 			if (newsig)
    150  1.6   mycroft 				sigaddset(bss, newsig);
    151  1.1      fvdl 		}
    152  1.1      fvdl 	}
    153  1.1      fvdl }
    154  1.1      fvdl 
    155  1.1      fvdl void
    156  1.1      fvdl bsd_to_linux_sigset(bss, lss)
    157  1.1      fvdl 	const sigset_t *bss;
    158  1.1      fvdl 	linux_sigset_t *lss;
    159  1.1      fvdl {
    160  1.1      fvdl 	int i, newsig;
    161  1.1      fvdl 
    162  1.6   mycroft 	linux_sigemptyset(lss);
    163  1.6   mycroft 	for (i = 1; i < NSIG; i++) {
    164  1.6   mycroft 		if (sigismember(bss, i)) {
    165  1.6   mycroft 			newsig = bsd_to_linux_sig[i];
    166  1.1      fvdl 			if (newsig)
    167  1.6   mycroft 				linux_sigaddset(lss, newsig);
    168  1.1      fvdl 		}
    169  1.1      fvdl 	}
    170  1.1      fvdl }
    171  1.1      fvdl 
    172  1.1      fvdl /*
    173  1.1      fvdl  * Convert between Linux and BSD sigaction structures. Linux has
    174  1.6   mycroft  * one extra field (sa_restorer) which we don't support.
    175  1.1      fvdl  */
    176  1.1      fvdl void
    177  1.1      fvdl linux_to_bsd_sigaction(lsa, bsa)
    178  1.1      fvdl 	struct linux_sigaction *lsa;
    179  1.1      fvdl 	struct sigaction *bsa;
    180  1.1      fvdl {
    181  1.6   mycroft 
    182  1.1      fvdl 	bsa->sa_handler = lsa->sa_handler;
    183  1.1      fvdl 	linux_to_bsd_sigset(&bsa->sa_mask, &lsa->sa_mask);
    184  1.1      fvdl 	bsa->sa_flags = 0;
    185  1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
    186  1.6   mycroft 		bsa->sa_flags |= SA_ONSTACK;
    187  1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
    188  1.6   mycroft 		bsa->sa_flags |= SA_RESTART;
    189  1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
    190  1.6   mycroft 		bsa->sa_flags |= SA_RESETHAND;
    191  1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
    192  1.6   mycroft 		bsa->sa_flags |= SA_NOCLDSTOP;
    193  1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
    194  1.6   mycroft 		bsa->sa_flags |= SA_NODEFER;
    195  1.1      fvdl }
    196  1.1      fvdl 
    197  1.1      fvdl void
    198  1.1      fvdl bsd_to_linux_sigaction(bsa, lsa)
    199  1.1      fvdl 	struct sigaction *bsa;
    200  1.1      fvdl 	struct linux_sigaction *lsa;
    201  1.1      fvdl {
    202  1.6   mycroft 
    203  1.1      fvdl 	lsa->sa_handler = bsa->sa_handler;
    204  1.1      fvdl 	bsd_to_linux_sigset(&lsa->sa_mask, &bsa->sa_mask);
    205  1.1      fvdl 	lsa->sa_flags = 0;
    206  1.6   mycroft 	if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
    207  1.6   mycroft 		lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
    208  1.6   mycroft 	if ((bsa->sa_flags & SA_ONSTACK) != 0)
    209  1.6   mycroft 		lsa->sa_flags |= LINUX_SA_ONSTACK;
    210  1.6   mycroft 	if ((bsa->sa_flags & SA_RESTART) != 0)
    211  1.6   mycroft 		lsa->sa_flags |= LINUX_SA_RESTART;
    212  1.6   mycroft 	if ((bsa->sa_flags & SA_NODEFER) != 0)
    213  1.6   mycroft 		lsa->sa_flags |= LINUX_SA_NOMASK;
    214  1.6   mycroft 	if ((bsa->sa_flags & SA_RESETHAND) != 0)
    215  1.6   mycroft 		lsa->sa_flags |= LINUX_SA_ONESHOT;
    216  1.1      fvdl 	lsa->sa_restorer = NULL;
    217  1.1      fvdl }
    218  1.1      fvdl 
    219  1.1      fvdl 
    220  1.1      fvdl /*
    221  1.1      fvdl  * The Linux sigaction() system call. Do the usual conversions,
    222  1.1      fvdl  * and just call sigaction(). Some flags and values are silently
    223  1.1      fvdl  * ignored (see above).
    224  1.1      fvdl  */
    225  1.1      fvdl int
    226  1.8   thorpej linux_sigaction(p, v, retval)
    227  1.1      fvdl 	register struct proc *p;
    228  1.8   thorpej 	void *v;
    229  1.8   thorpej 	register_t *retval;
    230  1.8   thorpej {
    231  1.1      fvdl 	struct linux_sigaction_args /* {
    232  1.1      fvdl 		syscallarg(int) signum;
    233  1.1      fvdl 		syscallarg(struct linux_sigaction *) nsa;
    234  1.1      fvdl 		syscallarg(struct linux_sigaction *) osa;
    235  1.8   thorpej 	} */ *uap = v;
    236  1.1      fvdl 	struct linux_sigaction *nlsa, *olsa, tmplsa;
    237  1.6   mycroft 	struct sigaction *nbsa, *obsa, tmpbsa;
    238  1.1      fvdl 	struct sigaction_args sa;
    239  1.1      fvdl 	caddr_t sg;
    240  1.1      fvdl 	int error;
    241  1.1      fvdl 
    242  1.5  christos 	sg = stackgap_init(p->p_emul);
    243  1.6   mycroft 	nlsa = SCARG(uap, nsa);
    244  1.1      fvdl 	olsa = SCARG(uap, osa);
    245  1.1      fvdl 
    246  1.1      fvdl 	if (olsa != NULL)
    247  1.6   mycroft 		obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
    248  1.6   mycroft 	else
    249  1.6   mycroft 		obsa = NULL;
    250  1.1      fvdl 
    251  1.1      fvdl 	if (nlsa != NULL) {
    252  1.6   mycroft 		nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
    253  1.6   mycroft 		if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
    254  1.1      fvdl 			return error;
    255  1.6   mycroft 		linux_to_bsd_sigaction(&tmplsa, &tmpbsa);
    256  1.6   mycroft 		if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
    257  1.1      fvdl 			return error;
    258  1.6   mycroft 	} else
    259  1.6   mycroft 		nbsa = NULL;
    260  1.1      fvdl 
    261  1.6   mycroft 	SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
    262  1.6   mycroft 	SCARG(&sa, nsa) = nbsa;
    263  1.6   mycroft 	SCARG(&sa, osa) = obsa;
    264  1.1      fvdl 
    265  1.6   mycroft 	if ((error = sigaction(p, &sa, retval)) != 0)
    266  1.1      fvdl 		return error;
    267  1.1      fvdl 
    268  1.1      fvdl 	if (olsa != NULL) {
    269  1.6   mycroft 		if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
    270  1.1      fvdl 			return error;
    271  1.6   mycroft 		bsd_to_linux_sigaction(&tmpbsa, &tmplsa);
    272  1.6   mycroft 		if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
    273  1.1      fvdl 			return error;
    274  1.1      fvdl 	}
    275  1.6   mycroft 
    276  1.1      fvdl 	return 0;
    277  1.1      fvdl }
    278  1.1      fvdl 
    279  1.1      fvdl /*
    280  1.1      fvdl  * The Linux signal() system call. I think that the signal() in the C
    281  1.1      fvdl  * library actually calls sigaction, so I doubt this one is ever used.
    282  1.1      fvdl  * But hey, it can't hurt having it here. The same restrictions as for
    283  1.1      fvdl  * sigaction() apply.
    284  1.1      fvdl  */
    285  1.1      fvdl int
    286  1.8   thorpej linux_signal(p, v, retval)
    287  1.1      fvdl 	register struct proc *p;
    288  1.8   thorpej 	void *v;
    289  1.8   thorpej 	register_t *retval;
    290  1.8   thorpej {
    291  1.1      fvdl 	struct linux_signal_args /* {
    292  1.1      fvdl 		syscallarg(int) sig;
    293  1.1      fvdl 		syscallarg(linux_handler_t) handler;
    294  1.8   thorpej 	} */ *uap = v;
    295  1.1      fvdl 	caddr_t sg;
    296  1.1      fvdl 	struct sigaction_args sa_args;
    297  1.1      fvdl 	struct sigaction *osa, *nsa, tmpsa;
    298  1.1      fvdl 	int error;
    299  1.1      fvdl 
    300  1.5  christos 	sg = stackgap_init(p->p_emul);
    301  1.1      fvdl 	nsa = stackgap_alloc(&sg, sizeof *nsa);
    302  1.1      fvdl 	osa = stackgap_alloc(&sg, sizeof *osa);
    303  1.1      fvdl 
    304  1.1      fvdl 	tmpsa.sa_handler = SCARG(uap, handler);
    305  1.1      fvdl 	tmpsa.sa_mask = (sigset_t) 0;
    306  1.6   mycroft 	tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
    307  1.1      fvdl 	if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
    308  1.1      fvdl 		return error;
    309  1.1      fvdl 
    310  1.6   mycroft 	SCARG(&sa_args, signum) = linux_to_bsd_sig[SCARG(uap, sig)];
    311  1.1      fvdl 	SCARG(&sa_args, osa) = osa;
    312  1.1      fvdl 	SCARG(&sa_args, nsa) = nsa;
    313  1.1      fvdl 	if ((error = sigaction(p, &sa_args, retval)))
    314  1.1      fvdl 		return error;
    315  1.1      fvdl 
    316  1.1      fvdl 	if ((error = copyin(osa, &tmpsa, sizeof *osa)))
    317  1.1      fvdl 		return error;
    318  1.1      fvdl 	retval[0] = (register_t) tmpsa.sa_handler;
    319  1.1      fvdl 
    320  1.1      fvdl 	return 0;
    321  1.1      fvdl }
    322  1.1      fvdl 
    323  1.1      fvdl /*
    324  1.1      fvdl  * This is just a copy of the svr4 compat one. I feel so creative now.
    325  1.1      fvdl  */
    326  1.1      fvdl int
    327  1.8   thorpej linux_sigprocmask(p, v, retval)
    328  1.1      fvdl 	register struct proc *p;
    329  1.8   thorpej 	void *v;
    330  1.8   thorpej 	register_t *retval;
    331  1.8   thorpej {
    332  1.6   mycroft 	struct linux_sigprocmask_args /* {
    333  1.1      fvdl 		syscallarg(int) how;
    334  1.1      fvdl 		syscallarg(linux_sigset_t *) set;
    335  1.6   mycroft 		syscallarg(linux_sigset_t *) oset;
    336  1.8   thorpej 	} */ *uap = v;
    337  1.1      fvdl 	linux_sigset_t ss;
    338  1.1      fvdl 	sigset_t bs;
    339  1.1      fvdl 	int error = 0;
    340  1.1      fvdl 
    341  1.1      fvdl 	*retval = 0;
    342  1.1      fvdl 
    343  1.1      fvdl 	if (SCARG(uap, oset) != NULL) {
    344  1.1      fvdl 		/* Fix the return value first if needed */
    345  1.1      fvdl 		bsd_to_linux_sigset(&p->p_sigmask, &ss);
    346  1.1      fvdl 		if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0)
    347  1.1      fvdl 			return error;
    348  1.1      fvdl 	}
    349  1.1      fvdl 
    350  1.1      fvdl 	if (SCARG(uap, set) == NULL)
    351  1.1      fvdl 		/* Just examine */
    352  1.1      fvdl 		return 0;
    353  1.1      fvdl 
    354  1.1      fvdl 	if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0)
    355  1.1      fvdl 		return error;
    356  1.1      fvdl 
    357  1.1      fvdl 	linux_to_bsd_sigset(&ss, &bs);
    358  1.1      fvdl 
    359  1.1      fvdl 	(void) splhigh();
    360  1.1      fvdl 
    361  1.1      fvdl 	switch (SCARG(uap, how)) {
    362  1.1      fvdl 	case LINUX_SIG_BLOCK:
    363  1.1      fvdl 		p->p_sigmask |= bs & ~sigcantmask;
    364  1.1      fvdl 		break;
    365  1.1      fvdl 
    366  1.1      fvdl 	case LINUX_SIG_UNBLOCK:
    367  1.1      fvdl 		p->p_sigmask &= ~bs;
    368  1.1      fvdl 		break;
    369  1.1      fvdl 
    370  1.1      fvdl 	case LINUX_SIG_SETMASK:
    371  1.1      fvdl 		p->p_sigmask = bs & ~sigcantmask;
    372  1.1      fvdl 		break;
    373  1.1      fvdl 
    374  1.1      fvdl 	default:
    375  1.1      fvdl 		error = EINVAL;
    376  1.1      fvdl 		break;
    377  1.1      fvdl 	}
    378  1.1      fvdl 
    379  1.1      fvdl 	(void) spl0();
    380  1.1      fvdl 
    381  1.1      fvdl 	return error;
    382  1.1      fvdl }
    383  1.1      fvdl 
    384  1.1      fvdl /*
    385  1.1      fvdl  * The functions below really make no distinction between an int
    386  1.1      fvdl  * and [linux_]sigset_t. This is ok for now, but it might break
    387  1.1      fvdl  * sometime. Then again, sigset_t is trusted to be an int everywhere
    388  1.1      fvdl  * else in the kernel too.
    389  1.1      fvdl  */
    390  1.1      fvdl /* ARGSUSED */
    391  1.1      fvdl int
    392  1.1      fvdl linux_siggetmask(p, uap, retval)
    393  1.6   mycroft 	register struct proc *p;
    394  1.1      fvdl 	void *uap;
    395  1.1      fvdl 	register_t *retval;
    396  1.1      fvdl {
    397  1.6   mycroft 
    398  1.6   mycroft 	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
    399  1.1      fvdl 	return 0;
    400  1.1      fvdl }
    401  1.1      fvdl 
    402  1.1      fvdl /*
    403  1.1      fvdl  * The following three functions fiddle with a process' signal mask.
    404  1.1      fvdl  * Convert the signal masks because of the different signal
    405  1.1      fvdl  * values for Linux. The need for this is the reason why
    406  1.1      fvdl  * they are here, and have not been mapped directly.
    407  1.1      fvdl  */
    408  1.1      fvdl int
    409  1.8   thorpej linux_sigsetmask(p, v, retval)
    410  1.6   mycroft 	register struct proc *p;
    411  1.8   thorpej 	void *v;
    412  1.8   thorpej 	register_t *retval;
    413  1.8   thorpej {
    414  1.1      fvdl 	struct linux_sigsetmask_args /* {
    415  1.1      fvdl 		syscallarg(linux_sigset_t) mask;
    416  1.8   thorpej 	} */ *uap = v;
    417  1.1      fvdl 	linux_sigset_t mask;
    418  1.1      fvdl 	sigset_t bsdsig;
    419  1.1      fvdl 
    420  1.6   mycroft 	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
    421  1.1      fvdl 
    422  1.1      fvdl 	mask = SCARG(uap, mask);
    423  1.1      fvdl 	bsd_to_linux_sigset(&mask, &bsdsig);
    424  1.1      fvdl 
    425  1.1      fvdl 	splhigh();
    426  1.1      fvdl 	p->p_sigmask = bsdsig & ~sigcantmask;
    427  1.1      fvdl 	spl0();
    428  1.1      fvdl 
    429  1.1      fvdl 	return 0;
    430  1.1      fvdl }
    431  1.1      fvdl 
    432  1.1      fvdl int
    433  1.8   thorpej linux_sigpending(p, v, retval)
    434  1.6   mycroft 	register struct proc *p;
    435  1.8   thorpej 	void *v;
    436  1.8   thorpej 	register_t *retval;
    437  1.8   thorpej {
    438  1.1      fvdl 	struct linux_sigpending_args /* {
    439  1.1      fvdl 		syscallarg(linux_sigset_t *) mask;
    440  1.8   thorpej 	} */ *uap = v;
    441  1.6   mycroft 	sigset_t bs;
    442  1.6   mycroft 	linux_sigset_t ls;
    443  1.1      fvdl 
    444  1.6   mycroft 	bs = p->p_siglist & p->p_sigmask;
    445  1.6   mycroft 	bsd_to_linux_sigset(&bs, &ls);
    446  1.1      fvdl 
    447  1.6   mycroft 	return copyout(&ls, SCARG(uap, mask), sizeof(ls));
    448  1.1      fvdl }
    449  1.1      fvdl 
    450  1.1      fvdl int
    451  1.8   thorpej linux_sigsuspend(p, v, retval)
    452  1.6   mycroft 	register struct proc *p;
    453  1.8   thorpej 	void *v;
    454  1.8   thorpej 	register_t *retval;
    455  1.8   thorpej {
    456  1.1      fvdl 	struct linux_sigsuspend_args /* {
    457  1.3      fvdl 		syscallarg(caddr_t) restart;
    458  1.3      fvdl 		syscallarg(int) oldmask;
    459  1.1      fvdl 		syscallarg(int) mask;
    460  1.8   thorpej 	} */ *uap = v;
    461  1.6   mycroft 	struct sigsuspend_args sa;
    462  1.1      fvdl 
    463  1.6   mycroft 	linux_to_bsd_sigset(&SCARG(uap, mask), &SCARG(&sa, mask));
    464  1.6   mycroft 	return sigsuspend(p, &sa, retval);
    465  1.3      fvdl }
    466  1.3      fvdl 
    467  1.3      fvdl /*
    468  1.3      fvdl  * The deprecated pause(2), which is really just an instance
    469  1.3      fvdl  * of sigsuspend(2).
    470  1.3      fvdl  */
    471  1.3      fvdl int
    472  1.3      fvdl linux_pause(p, uap, retval)
    473  1.6   mycroft 	register struct proc *p;
    474  1.3      fvdl 	void *uap;
    475  1.3      fvdl 	register_t *retval;
    476  1.3      fvdl {
    477  1.3      fvdl 	struct sigsuspend_args bsa;
    478  1.3      fvdl 
    479  1.3      fvdl 	SCARG(&bsa, mask) = p->p_sigmask;
    480  1.3      fvdl 	return sigsuspend(p, &bsa, retval);
    481  1.1      fvdl }
    482  1.1      fvdl 
    483  1.1      fvdl /*
    484  1.1      fvdl  * Once more: only a signal conversion is needed.
    485  1.1      fvdl  */
    486  1.1      fvdl int
    487  1.8   thorpej linux_kill(p, v, retval)
    488  1.6   mycroft 	register struct proc *p;
    489  1.8   thorpej 	void *v;
    490  1.8   thorpej 	register_t *retval;
    491  1.8   thorpej {
    492  1.1      fvdl 	struct linux_kill_args /* {
    493  1.1      fvdl 		syscallarg(int) pid;
    494  1.1      fvdl 		syscallarg(int) signum;
    495  1.8   thorpej 	} */ *uap = v;
    496  1.6   mycroft 	struct kill_args ka;
    497  1.6   mycroft 
    498  1.6   mycroft 	SCARG(&ka, pid) = SCARG(uap, pid);
    499  1.6   mycroft 	SCARG(&ka, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
    500  1.6   mycroft 	return kill(p, &ka, retval);
    501  1.1      fvdl }
    502