Home | History | Annotate | Line # | Download | only in common
linux_signal.c revision 1.11
      1  1.11     perry /*	$NetBSD: linux_signal.c,v 1.11 1998/08/09 20:37:54 perry 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.11     perry #define	sigemptyset(s)		memset((s), 0, 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.11     perry #define	linux_sigemptyset(s)	memset((s), 0, 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.10  christos 
    135  1.10  christos /* linux_signal.c */
    136  1.10  christos void linux_to_bsd_sigset __P((const linux_sigset_t *, sigset_t *));
    137  1.10  christos void bsd_to_linux_sigset __P((const sigset_t *, linux_sigset_t *));
    138  1.10  christos void linux_to_bsd_sigaction __P((struct linux_sigaction *, struct sigaction *));
    139  1.10  christos void bsd_to_linux_sigaction __P((struct sigaction *, struct linux_sigaction *));
    140  1.10  christos 
    141   1.1      fvdl /*
    142   1.1      fvdl  * Ok, we know that Linux and BSD signals both are just an unsigned int.
    143   1.1      fvdl  * Don't bother to use the sigismember() stuff for now.
    144   1.1      fvdl  */
    145   1.6   mycroft void
    146   1.1      fvdl linux_to_bsd_sigset(lss, bss)
    147   1.1      fvdl 	const linux_sigset_t *lss;
    148   1.1      fvdl 	sigset_t *bss;
    149   1.1      fvdl {
    150   1.1      fvdl 	int i, newsig;
    151   1.1      fvdl 
    152   1.6   mycroft 	sigemptyset(bss);
    153   1.6   mycroft 	for (i = 1; i < LINUX_NSIG; i++) {
    154   1.6   mycroft 		if (linux_sigismember(lss, i)) {
    155   1.6   mycroft 			newsig = linux_to_bsd_sig[i];
    156   1.1      fvdl 			if (newsig)
    157   1.6   mycroft 				sigaddset(bss, newsig);
    158   1.1      fvdl 		}
    159   1.1      fvdl 	}
    160   1.1      fvdl }
    161   1.1      fvdl 
    162   1.1      fvdl void
    163   1.1      fvdl bsd_to_linux_sigset(bss, lss)
    164   1.1      fvdl 	const sigset_t *bss;
    165   1.1      fvdl 	linux_sigset_t *lss;
    166   1.1      fvdl {
    167   1.1      fvdl 	int i, newsig;
    168   1.1      fvdl 
    169   1.6   mycroft 	linux_sigemptyset(lss);
    170   1.6   mycroft 	for (i = 1; i < NSIG; i++) {
    171   1.6   mycroft 		if (sigismember(bss, i)) {
    172   1.6   mycroft 			newsig = bsd_to_linux_sig[i];
    173   1.1      fvdl 			if (newsig)
    174   1.6   mycroft 				linux_sigaddset(lss, newsig);
    175   1.1      fvdl 		}
    176   1.1      fvdl 	}
    177   1.1      fvdl }
    178   1.1      fvdl 
    179   1.1      fvdl /*
    180   1.1      fvdl  * Convert between Linux and BSD sigaction structures. Linux has
    181   1.6   mycroft  * one extra field (sa_restorer) which we don't support.
    182   1.1      fvdl  */
    183   1.1      fvdl void
    184   1.1      fvdl linux_to_bsd_sigaction(lsa, bsa)
    185   1.1      fvdl 	struct linux_sigaction *lsa;
    186   1.1      fvdl 	struct sigaction *bsa;
    187   1.1      fvdl {
    188   1.6   mycroft 
    189   1.1      fvdl 	bsa->sa_handler = lsa->sa_handler;
    190  1.10  christos 	linux_to_bsd_sigset(&lsa->sa_mask, &bsa->sa_mask);
    191   1.1      fvdl 	bsa->sa_flags = 0;
    192   1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
    193   1.6   mycroft 		bsa->sa_flags |= SA_ONSTACK;
    194   1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
    195   1.6   mycroft 		bsa->sa_flags |= SA_RESTART;
    196   1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
    197   1.6   mycroft 		bsa->sa_flags |= SA_RESETHAND;
    198   1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
    199   1.6   mycroft 		bsa->sa_flags |= SA_NOCLDSTOP;
    200   1.6   mycroft 	if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
    201   1.6   mycroft 		bsa->sa_flags |= SA_NODEFER;
    202   1.1      fvdl }
    203   1.1      fvdl 
    204   1.1      fvdl void
    205   1.1      fvdl bsd_to_linux_sigaction(bsa, lsa)
    206   1.1      fvdl 	struct sigaction *bsa;
    207   1.1      fvdl 	struct linux_sigaction *lsa;
    208   1.1      fvdl {
    209   1.6   mycroft 
    210   1.1      fvdl 	lsa->sa_handler = bsa->sa_handler;
    211  1.10  christos 	bsd_to_linux_sigset(&bsa->sa_mask, &lsa->sa_mask);
    212   1.1      fvdl 	lsa->sa_flags = 0;
    213   1.6   mycroft 	if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
    214   1.6   mycroft 		lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
    215   1.6   mycroft 	if ((bsa->sa_flags & SA_ONSTACK) != 0)
    216   1.6   mycroft 		lsa->sa_flags |= LINUX_SA_ONSTACK;
    217   1.6   mycroft 	if ((bsa->sa_flags & SA_RESTART) != 0)
    218   1.6   mycroft 		lsa->sa_flags |= LINUX_SA_RESTART;
    219   1.6   mycroft 	if ((bsa->sa_flags & SA_NODEFER) != 0)
    220   1.6   mycroft 		lsa->sa_flags |= LINUX_SA_NOMASK;
    221   1.6   mycroft 	if ((bsa->sa_flags & SA_RESETHAND) != 0)
    222   1.6   mycroft 		lsa->sa_flags |= LINUX_SA_ONESHOT;
    223   1.1      fvdl 	lsa->sa_restorer = NULL;
    224   1.1      fvdl }
    225   1.1      fvdl 
    226   1.1      fvdl 
    227   1.1      fvdl /*
    228   1.1      fvdl  * The Linux sigaction() system call. Do the usual conversions,
    229   1.1      fvdl  * and just call sigaction(). Some flags and values are silently
    230   1.1      fvdl  * ignored (see above).
    231   1.1      fvdl  */
    232   1.1      fvdl int
    233   1.9   mycroft linux_sys_sigaction(p, v, retval)
    234   1.1      fvdl 	register struct proc *p;
    235   1.8   thorpej 	void *v;
    236   1.8   thorpej 	register_t *retval;
    237   1.8   thorpej {
    238   1.9   mycroft 	struct linux_sys_sigaction_args /* {
    239   1.1      fvdl 		syscallarg(int) signum;
    240   1.1      fvdl 		syscallarg(struct linux_sigaction *) nsa;
    241   1.1      fvdl 		syscallarg(struct linux_sigaction *) osa;
    242   1.8   thorpej 	} */ *uap = v;
    243   1.1      fvdl 	struct linux_sigaction *nlsa, *olsa, tmplsa;
    244   1.6   mycroft 	struct sigaction *nbsa, *obsa, tmpbsa;
    245   1.9   mycroft 	struct sys_sigaction_args sa;
    246   1.1      fvdl 	caddr_t sg;
    247   1.1      fvdl 	int error;
    248   1.1      fvdl 
    249   1.5  christos 	sg = stackgap_init(p->p_emul);
    250   1.6   mycroft 	nlsa = SCARG(uap, nsa);
    251   1.1      fvdl 	olsa = SCARG(uap, osa);
    252   1.1      fvdl 
    253   1.1      fvdl 	if (olsa != NULL)
    254   1.6   mycroft 		obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
    255   1.6   mycroft 	else
    256   1.6   mycroft 		obsa = NULL;
    257   1.1      fvdl 
    258   1.1      fvdl 	if (nlsa != NULL) {
    259   1.6   mycroft 		nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
    260   1.6   mycroft 		if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
    261   1.1      fvdl 			return error;
    262   1.6   mycroft 		linux_to_bsd_sigaction(&tmplsa, &tmpbsa);
    263   1.6   mycroft 		if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
    264   1.1      fvdl 			return error;
    265   1.6   mycroft 	} else
    266   1.6   mycroft 		nbsa = NULL;
    267   1.1      fvdl 
    268   1.6   mycroft 	SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
    269   1.6   mycroft 	SCARG(&sa, nsa) = nbsa;
    270   1.6   mycroft 	SCARG(&sa, osa) = obsa;
    271   1.1      fvdl 
    272   1.9   mycroft 	if ((error = sys_sigaction(p, &sa, retval)) != 0)
    273   1.1      fvdl 		return error;
    274   1.1      fvdl 
    275   1.1      fvdl 	if (olsa != NULL) {
    276   1.6   mycroft 		if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
    277   1.1      fvdl 			return error;
    278   1.6   mycroft 		bsd_to_linux_sigaction(&tmpbsa, &tmplsa);
    279   1.6   mycroft 		if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
    280   1.1      fvdl 			return error;
    281   1.1      fvdl 	}
    282   1.6   mycroft 
    283   1.1      fvdl 	return 0;
    284   1.1      fvdl }
    285   1.1      fvdl 
    286   1.1      fvdl /*
    287   1.1      fvdl  * The Linux signal() system call. I think that the signal() in the C
    288   1.1      fvdl  * library actually calls sigaction, so I doubt this one is ever used.
    289   1.1      fvdl  * But hey, it can't hurt having it here. The same restrictions as for
    290   1.1      fvdl  * sigaction() apply.
    291   1.1      fvdl  */
    292   1.1      fvdl int
    293   1.9   mycroft linux_sys_signal(p, v, retval)
    294   1.1      fvdl 	register struct proc *p;
    295   1.8   thorpej 	void *v;
    296   1.8   thorpej 	register_t *retval;
    297   1.8   thorpej {
    298   1.9   mycroft 	struct linux_sys_signal_args /* {
    299   1.1      fvdl 		syscallarg(int) sig;
    300   1.1      fvdl 		syscallarg(linux_handler_t) handler;
    301   1.8   thorpej 	} */ *uap = v;
    302   1.1      fvdl 	caddr_t sg;
    303   1.9   mycroft 	struct sys_sigaction_args sa_args;
    304   1.1      fvdl 	struct sigaction *osa, *nsa, tmpsa;
    305   1.1      fvdl 	int error;
    306   1.1      fvdl 
    307   1.5  christos 	sg = stackgap_init(p->p_emul);
    308   1.1      fvdl 	nsa = stackgap_alloc(&sg, sizeof *nsa);
    309   1.1      fvdl 	osa = stackgap_alloc(&sg, sizeof *osa);
    310   1.1      fvdl 
    311   1.1      fvdl 	tmpsa.sa_handler = SCARG(uap, handler);
    312   1.1      fvdl 	tmpsa.sa_mask = (sigset_t) 0;
    313   1.6   mycroft 	tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
    314   1.1      fvdl 	if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
    315   1.1      fvdl 		return error;
    316   1.1      fvdl 
    317   1.6   mycroft 	SCARG(&sa_args, signum) = linux_to_bsd_sig[SCARG(uap, sig)];
    318   1.1      fvdl 	SCARG(&sa_args, osa) = osa;
    319   1.1      fvdl 	SCARG(&sa_args, nsa) = nsa;
    320   1.9   mycroft 	if ((error = sys_sigaction(p, &sa_args, retval)))
    321   1.1      fvdl 		return error;
    322   1.1      fvdl 
    323   1.1      fvdl 	if ((error = copyin(osa, &tmpsa, sizeof *osa)))
    324   1.1      fvdl 		return error;
    325   1.1      fvdl 	retval[0] = (register_t) tmpsa.sa_handler;
    326   1.1      fvdl 
    327   1.1      fvdl 	return 0;
    328   1.1      fvdl }
    329   1.1      fvdl 
    330   1.1      fvdl /*
    331   1.1      fvdl  * This is just a copy of the svr4 compat one. I feel so creative now.
    332   1.1      fvdl  */
    333   1.1      fvdl int
    334   1.9   mycroft linux_sys_sigprocmask(p, v, retval)
    335   1.1      fvdl 	register struct proc *p;
    336   1.8   thorpej 	void *v;
    337   1.8   thorpej 	register_t *retval;
    338   1.8   thorpej {
    339   1.9   mycroft 	struct linux_sys_sigprocmask_args /* {
    340   1.1      fvdl 		syscallarg(int) how;
    341   1.1      fvdl 		syscallarg(linux_sigset_t *) set;
    342   1.6   mycroft 		syscallarg(linux_sigset_t *) oset;
    343   1.8   thorpej 	} */ *uap = v;
    344   1.1      fvdl 	linux_sigset_t ss;
    345   1.1      fvdl 	sigset_t bs;
    346   1.1      fvdl 	int error = 0;
    347   1.1      fvdl 
    348   1.1      fvdl 	*retval = 0;
    349   1.1      fvdl 
    350   1.1      fvdl 	if (SCARG(uap, oset) != NULL) {
    351   1.1      fvdl 		/* Fix the return value first if needed */
    352   1.1      fvdl 		bsd_to_linux_sigset(&p->p_sigmask, &ss);
    353   1.1      fvdl 		if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0)
    354   1.1      fvdl 			return error;
    355   1.1      fvdl 	}
    356   1.1      fvdl 
    357   1.1      fvdl 	if (SCARG(uap, set) == NULL)
    358   1.1      fvdl 		/* Just examine */
    359   1.1      fvdl 		return 0;
    360   1.1      fvdl 
    361   1.1      fvdl 	if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0)
    362   1.1      fvdl 		return error;
    363   1.1      fvdl 
    364   1.1      fvdl 	linux_to_bsd_sigset(&ss, &bs);
    365   1.1      fvdl 
    366   1.1      fvdl 	(void) splhigh();
    367   1.1      fvdl 
    368   1.1      fvdl 	switch (SCARG(uap, how)) {
    369   1.1      fvdl 	case LINUX_SIG_BLOCK:
    370   1.1      fvdl 		p->p_sigmask |= bs & ~sigcantmask;
    371   1.1      fvdl 		break;
    372   1.1      fvdl 
    373   1.1      fvdl 	case LINUX_SIG_UNBLOCK:
    374   1.1      fvdl 		p->p_sigmask &= ~bs;
    375   1.1      fvdl 		break;
    376   1.1      fvdl 
    377   1.1      fvdl 	case LINUX_SIG_SETMASK:
    378   1.1      fvdl 		p->p_sigmask = bs & ~sigcantmask;
    379   1.1      fvdl 		break;
    380   1.1      fvdl 
    381   1.1      fvdl 	default:
    382   1.1      fvdl 		error = EINVAL;
    383   1.1      fvdl 		break;
    384   1.1      fvdl 	}
    385   1.1      fvdl 
    386   1.1      fvdl 	(void) spl0();
    387   1.1      fvdl 
    388   1.1      fvdl 	return error;
    389   1.1      fvdl }
    390   1.1      fvdl 
    391   1.1      fvdl /*
    392   1.1      fvdl  * The functions below really make no distinction between an int
    393   1.1      fvdl  * and [linux_]sigset_t. This is ok for now, but it might break
    394   1.1      fvdl  * sometime. Then again, sigset_t is trusted to be an int everywhere
    395   1.1      fvdl  * else in the kernel too.
    396   1.1      fvdl  */
    397   1.1      fvdl /* ARGSUSED */
    398   1.1      fvdl int
    399   1.9   mycroft linux_sys_siggetmask(p, v, retval)
    400   1.6   mycroft 	register struct proc *p;
    401   1.9   mycroft 	void *v;
    402   1.1      fvdl 	register_t *retval;
    403   1.1      fvdl {
    404   1.6   mycroft 
    405   1.6   mycroft 	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
    406   1.1      fvdl 	return 0;
    407   1.1      fvdl }
    408   1.1      fvdl 
    409   1.1      fvdl /*
    410   1.1      fvdl  * The following three functions fiddle with a process' signal mask.
    411   1.1      fvdl  * Convert the signal masks because of the different signal
    412   1.1      fvdl  * values for Linux. The need for this is the reason why
    413   1.1      fvdl  * they are here, and have not been mapped directly.
    414   1.1      fvdl  */
    415   1.1      fvdl int
    416   1.9   mycroft linux_sys_sigsetmask(p, v, retval)
    417   1.6   mycroft 	register struct proc *p;
    418   1.8   thorpej 	void *v;
    419   1.8   thorpej 	register_t *retval;
    420   1.8   thorpej {
    421   1.9   mycroft 	struct linux_sys_sigsetmask_args /* {
    422   1.1      fvdl 		syscallarg(linux_sigset_t) mask;
    423   1.8   thorpej 	} */ *uap = v;
    424   1.1      fvdl 	linux_sigset_t mask;
    425   1.1      fvdl 	sigset_t bsdsig;
    426   1.1      fvdl 
    427   1.6   mycroft 	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
    428   1.1      fvdl 
    429   1.1      fvdl 	mask = SCARG(uap, mask);
    430  1.10  christos 	bsd_to_linux_sigset(&bsdsig, &mask);
    431   1.1      fvdl 
    432   1.1      fvdl 	splhigh();
    433   1.1      fvdl 	p->p_sigmask = bsdsig & ~sigcantmask;
    434   1.1      fvdl 	spl0();
    435   1.1      fvdl 
    436   1.1      fvdl 	return 0;
    437   1.1      fvdl }
    438   1.1      fvdl 
    439   1.1      fvdl int
    440   1.9   mycroft linux_sys_sigpending(p, v, retval)
    441   1.6   mycroft 	register struct proc *p;
    442   1.8   thorpej 	void *v;
    443   1.8   thorpej 	register_t *retval;
    444   1.8   thorpej {
    445   1.9   mycroft 	struct linux_sys_sigpending_args /* {
    446   1.1      fvdl 		syscallarg(linux_sigset_t *) mask;
    447   1.8   thorpej 	} */ *uap = v;
    448   1.6   mycroft 	sigset_t bs;
    449   1.6   mycroft 	linux_sigset_t ls;
    450   1.1      fvdl 
    451   1.6   mycroft 	bs = p->p_siglist & p->p_sigmask;
    452   1.6   mycroft 	bsd_to_linux_sigset(&bs, &ls);
    453   1.1      fvdl 
    454   1.6   mycroft 	return copyout(&ls, SCARG(uap, mask), sizeof(ls));
    455   1.1      fvdl }
    456   1.1      fvdl 
    457   1.1      fvdl int
    458   1.9   mycroft linux_sys_sigsuspend(p, v, retval)
    459   1.6   mycroft 	register struct proc *p;
    460   1.8   thorpej 	void *v;
    461   1.8   thorpej 	register_t *retval;
    462   1.8   thorpej {
    463   1.9   mycroft 	struct linux_sys_sigsuspend_args /* {
    464   1.3      fvdl 		syscallarg(caddr_t) restart;
    465   1.3      fvdl 		syscallarg(int) oldmask;
    466   1.1      fvdl 		syscallarg(int) mask;
    467   1.8   thorpej 	} */ *uap = v;
    468   1.9   mycroft 	struct sys_sigsuspend_args sa;
    469  1.10  christos 	linux_sigset_t mask = SCARG(uap, mask);
    470   1.1      fvdl 
    471  1.10  christos 	linux_to_bsd_sigset(&mask, &SCARG(&sa, mask));
    472   1.9   mycroft 	return sys_sigsuspend(p, &sa, retval);
    473   1.3      fvdl }
    474   1.3      fvdl 
    475   1.3      fvdl /*
    476   1.3      fvdl  * The deprecated pause(2), which is really just an instance
    477   1.3      fvdl  * of sigsuspend(2).
    478   1.3      fvdl  */
    479   1.3      fvdl int
    480   1.9   mycroft linux_sys_pause(p, v, retval)
    481   1.6   mycroft 	register struct proc *p;
    482   1.9   mycroft 	void *v;
    483   1.3      fvdl 	register_t *retval;
    484   1.3      fvdl {
    485   1.9   mycroft 	struct sys_sigsuspend_args bsa;
    486   1.3      fvdl 
    487   1.3      fvdl 	SCARG(&bsa, mask) = p->p_sigmask;
    488   1.9   mycroft 	return sys_sigsuspend(p, &bsa, retval);
    489   1.1      fvdl }
    490   1.1      fvdl 
    491   1.1      fvdl /*
    492   1.1      fvdl  * Once more: only a signal conversion is needed.
    493   1.1      fvdl  */
    494   1.1      fvdl int
    495   1.9   mycroft linux_sys_kill(p, v, retval)
    496   1.6   mycroft 	register struct proc *p;
    497   1.8   thorpej 	void *v;
    498   1.8   thorpej 	register_t *retval;
    499   1.8   thorpej {
    500   1.9   mycroft 	struct linux_sys_kill_args /* {
    501   1.1      fvdl 		syscallarg(int) pid;
    502   1.1      fvdl 		syscallarg(int) signum;
    503   1.8   thorpej 	} */ *uap = v;
    504   1.9   mycroft 	struct sys_kill_args ka;
    505   1.6   mycroft 
    506   1.6   mycroft 	SCARG(&ka, pid) = SCARG(uap, pid);
    507   1.6   mycroft 	SCARG(&ka, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
    508   1.9   mycroft 	return sys_kill(p, &ka, retval);
    509   1.1      fvdl }
    510