linux_sigarray.c revision 1.11
11.11Sperry/*	$NetBSD: linux_sigarray.c,v 1.11 1998/08/09 20:37:54 perry Exp $	*/
21.1Sfvdl
31.1Sfvdl/*
41.1Sfvdl * Copyright (c) 1995 Frank van der Linden
51.1Sfvdl * All rights reserved.
61.1Sfvdl *
71.1Sfvdl * Redistribution and use in source and binary forms, with or without
81.1Sfvdl * modification, are permitted provided that the following conditions
91.1Sfvdl * are met:
101.1Sfvdl * 1. Redistributions of source code must retain the above copyright
111.1Sfvdl *    notice, this list of conditions and the following disclaimer.
121.1Sfvdl * 2. Redistributions in binary form must reproduce the above copyright
131.1Sfvdl *    notice, this list of conditions and the following disclaimer in the
141.1Sfvdl *    documentation and/or other materials provided with the distribution.
151.1Sfvdl * 3. All advertising materials mentioning features or use of this software
161.1Sfvdl *    must display the following acknowledgement:
171.1Sfvdl *      This product includes software developed for the NetBSD Project
181.1Sfvdl *      by Frank van der Linden
191.1Sfvdl * 4. The name of the author may not be used to endorse or promote products
201.1Sfvdl *    derived from this software without specific prior written permission
211.1Sfvdl *
221.1Sfvdl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
231.1Sfvdl * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
241.1Sfvdl * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
251.1Sfvdl * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
261.1Sfvdl * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
271.1Sfvdl * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
281.1Sfvdl * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
291.1Sfvdl * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
301.1Sfvdl * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
311.1Sfvdl * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
321.1Sfvdl *
331.1Sfvdl * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
341.1Sfvdl */
351.1Sfvdl
361.1Sfvdl#include <sys/param.h>
371.1Sfvdl#include <sys/systm.h>
381.1Sfvdl#include <sys/namei.h>
391.1Sfvdl#include <sys/proc.h>
401.1Sfvdl#include <sys/filedesc.h>
411.1Sfvdl#include <sys/ioctl.h>
421.1Sfvdl#include <sys/mount.h>
431.1Sfvdl#include <sys/kernel.h>
441.1Sfvdl#include <sys/signal.h>
451.1Sfvdl#include <sys/signalvar.h>
461.1Sfvdl#include <sys/malloc.h>
471.1Sfvdl
481.1Sfvdl#include <sys/syscallargs.h>
491.1Sfvdl
501.1Sfvdl#include <compat/linux/linux_types.h>
511.7Smycroft#include <compat/linux/linux_signal.h>
521.1Sfvdl#include <compat/linux/linux_syscallargs.h>
531.1Sfvdl#include <compat/linux/linux_util.h>
541.1Sfvdl
551.11Sperry#define	sigemptyset(s)		memset((s), 0, sizeof(*(s)))
561.6Smycroft#define	sigismember(s, n)	(*(s) & sigmask(n))
571.6Smycroft#define	sigaddset(s, n)		(*(s) |= sigmask(n))
581.6Smycroft
591.6Smycroft#define	linux_sigmask(n)	(1 << ((n) - 1))
601.11Sperry#define	linux_sigemptyset(s)	memset((s), 0, sizeof(*(s)))
611.6Smycroft#define	linux_sigismember(s, n)	(*(s) & linux_sigmask(n))
621.6Smycroft#define	linux_sigaddset(s, n)	(*(s) |= linux_sigmask(n))
631.6Smycroft
641.6Smycroftint bsd_to_linux_sig[] = {
651.6Smycroft	0,
661.6Smycroft	LINUX_SIGHUP,
671.6Smycroft	LINUX_SIGINT,
681.6Smycroft	LINUX_SIGQUIT,
691.6Smycroft	LINUX_SIGILL,
701.6Smycroft	LINUX_SIGTRAP,
711.6Smycroft	LINUX_SIGABRT,
721.6Smycroft	0,
731.6Smycroft	LINUX_SIGFPE,
741.6Smycroft	LINUX_SIGKILL,
751.6Smycroft	LINUX_SIGBUS,
761.6Smycroft	LINUX_SIGSEGV,
771.6Smycroft	0,
781.6Smycroft	LINUX_SIGPIPE,
791.6Smycroft	LINUX_SIGALRM,
801.6Smycroft	LINUX_SIGTERM,
811.6Smycroft	LINUX_SIGURG,
821.6Smycroft	LINUX_SIGSTOP,
831.6Smycroft	LINUX_SIGTSTP,
841.6Smycroft	LINUX_SIGCONT,
851.6Smycroft	LINUX_SIGCHLD,
861.6Smycroft	LINUX_SIGTTIN,
871.6Smycroft	LINUX_SIGTTOU,
881.6Smycroft	LINUX_SIGIO,
891.6Smycroft	LINUX_SIGXCPU,
901.6Smycroft	LINUX_SIGXFSZ,
911.6Smycroft	LINUX_SIGVTALRM,
921.6Smycroft	LINUX_SIGPROF,
931.6Smycroft	LINUX_SIGWINCH,
941.6Smycroft	0,
951.6Smycroft	LINUX_SIGUSR1,
961.6Smycroft	LINUX_SIGUSR2,
971.6Smycroft};
981.6Smycroft
991.6Smycroftint linux_to_bsd_sig[] = {
1001.6Smycroft	0,
1011.6Smycroft	SIGHUP,
1021.6Smycroft	SIGINT,
1031.6Smycroft	SIGQUIT,
1041.6Smycroft	SIGILL,
1051.6Smycroft	SIGTRAP,
1061.6Smycroft	SIGABRT,
1071.6Smycroft	SIGBUS,
1081.6Smycroft	SIGFPE,
1091.6Smycroft	SIGKILL,
1101.6Smycroft	SIGUSR1,
1111.6Smycroft	SIGSEGV,
1121.6Smycroft	SIGUSR2,
1131.6Smycroft	SIGPIPE,
1141.6Smycroft	SIGALRM,
1151.6Smycroft	SIGTERM,
1161.6Smycroft	0,
1171.6Smycroft	SIGCHLD,
1181.6Smycroft	SIGCONT,
1191.6Smycroft	SIGSTOP,
1201.6Smycroft	SIGTSTP,
1211.6Smycroft	SIGTTIN,
1221.6Smycroft	SIGTTOU,
1231.6Smycroft	SIGURG,
1241.6Smycroft	SIGXCPU,
1251.6Smycroft	SIGXFSZ,
1261.6Smycroft	SIGVTALRM,
1271.6Smycroft	SIGPROF,
1281.6Smycroft	SIGWINCH,
1291.6Smycroft	SIGIO,
1301.6Smycroft	0,
1311.6Smycroft	0,
1321.6Smycroft};
1331.1Sfvdl
1341.10Schristos
1351.10Schristos/* linux_signal.c */
1361.10Schristosvoid linux_to_bsd_sigset __P((const linux_sigset_t *, sigset_t *));
1371.10Schristosvoid bsd_to_linux_sigset __P((const sigset_t *, linux_sigset_t *));
1381.10Schristosvoid linux_to_bsd_sigaction __P((struct linux_sigaction *, struct sigaction *));
1391.10Schristosvoid bsd_to_linux_sigaction __P((struct sigaction *, struct linux_sigaction *));
1401.10Schristos
1411.1Sfvdl/*
1421.1Sfvdl * Ok, we know that Linux and BSD signals both are just an unsigned int.
1431.1Sfvdl * Don't bother to use the sigismember() stuff for now.
1441.1Sfvdl */
1451.6Smycroftvoid
1461.1Sfvdllinux_to_bsd_sigset(lss, bss)
1471.1Sfvdl	const linux_sigset_t *lss;
1481.1Sfvdl	sigset_t *bss;
1491.1Sfvdl{
1501.1Sfvdl	int i, newsig;
1511.1Sfvdl
1521.6Smycroft	sigemptyset(bss);
1531.6Smycroft	for (i = 1; i < LINUX_NSIG; i++) {
1541.6Smycroft		if (linux_sigismember(lss, i)) {
1551.6Smycroft			newsig = linux_to_bsd_sig[i];
1561.1Sfvdl			if (newsig)
1571.6Smycroft				sigaddset(bss, newsig);
1581.1Sfvdl		}
1591.1Sfvdl	}
1601.1Sfvdl}
1611.1Sfvdl
1621.1Sfvdlvoid
1631.1Sfvdlbsd_to_linux_sigset(bss, lss)
1641.1Sfvdl	const sigset_t *bss;
1651.1Sfvdl	linux_sigset_t *lss;
1661.1Sfvdl{
1671.1Sfvdl	int i, newsig;
1681.1Sfvdl
1691.6Smycroft	linux_sigemptyset(lss);
1701.6Smycroft	for (i = 1; i < NSIG; i++) {
1711.6Smycroft		if (sigismember(bss, i)) {
1721.6Smycroft			newsig = bsd_to_linux_sig[i];
1731.1Sfvdl			if (newsig)
1741.6Smycroft				linux_sigaddset(lss, newsig);
1751.1Sfvdl		}
1761.1Sfvdl	}
1771.1Sfvdl}
1781.1Sfvdl
1791.1Sfvdl/*
1801.1Sfvdl * Convert between Linux and BSD sigaction structures. Linux has
1811.6Smycroft * one extra field (sa_restorer) which we don't support.
1821.1Sfvdl */
1831.1Sfvdlvoid
1841.1Sfvdllinux_to_bsd_sigaction(lsa, bsa)
1851.1Sfvdl	struct linux_sigaction *lsa;
1861.1Sfvdl	struct sigaction *bsa;
1871.1Sfvdl{
1881.6Smycroft
1891.1Sfvdl	bsa->sa_handler = lsa->sa_handler;
1901.10Schristos	linux_to_bsd_sigset(&lsa->sa_mask, &bsa->sa_mask);
1911.1Sfvdl	bsa->sa_flags = 0;
1921.6Smycroft	if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
1931.6Smycroft		bsa->sa_flags |= SA_ONSTACK;
1941.6Smycroft	if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
1951.6Smycroft		bsa->sa_flags |= SA_RESTART;
1961.6Smycroft	if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
1971.6Smycroft		bsa->sa_flags |= SA_RESETHAND;
1981.6Smycroft	if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
1991.6Smycroft		bsa->sa_flags |= SA_NOCLDSTOP;
2001.6Smycroft	if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
2011.6Smycroft		bsa->sa_flags |= SA_NODEFER;
2021.1Sfvdl}
2031.1Sfvdl
2041.1Sfvdlvoid
2051.1Sfvdlbsd_to_linux_sigaction(bsa, lsa)
2061.1Sfvdl	struct sigaction *bsa;
2071.1Sfvdl	struct linux_sigaction *lsa;
2081.1Sfvdl{
2091.6Smycroft
2101.1Sfvdl	lsa->sa_handler = bsa->sa_handler;
2111.10Schristos	bsd_to_linux_sigset(&bsa->sa_mask, &lsa->sa_mask);
2121.1Sfvdl	lsa->sa_flags = 0;
2131.6Smycroft	if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
2141.6Smycroft		lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
2151.6Smycroft	if ((bsa->sa_flags & SA_ONSTACK) != 0)
2161.6Smycroft		lsa->sa_flags |= LINUX_SA_ONSTACK;
2171.6Smycroft	if ((bsa->sa_flags & SA_RESTART) != 0)
2181.6Smycroft		lsa->sa_flags |= LINUX_SA_RESTART;
2191.6Smycroft	if ((bsa->sa_flags & SA_NODEFER) != 0)
2201.6Smycroft		lsa->sa_flags |= LINUX_SA_NOMASK;
2211.6Smycroft	if ((bsa->sa_flags & SA_RESETHAND) != 0)
2221.6Smycroft		lsa->sa_flags |= LINUX_SA_ONESHOT;
2231.1Sfvdl	lsa->sa_restorer = NULL;
2241.1Sfvdl}
2251.1Sfvdl
2261.1Sfvdl
2271.1Sfvdl/*
2281.1Sfvdl * The Linux sigaction() system call. Do the usual conversions,
2291.1Sfvdl * and just call sigaction(). Some flags and values are silently
2301.1Sfvdl * ignored (see above).
2311.1Sfvdl */
2321.1Sfvdlint
2331.9Smycroftlinux_sys_sigaction(p, v, retval)
2341.1Sfvdl	register struct proc *p;
2351.8Sthorpej	void *v;
2361.8Sthorpej	register_t *retval;
2371.8Sthorpej{
2381.9Smycroft	struct linux_sys_sigaction_args /* {
2391.1Sfvdl		syscallarg(int) signum;
2401.1Sfvdl		syscallarg(struct linux_sigaction *) nsa;
2411.1Sfvdl		syscallarg(struct linux_sigaction *) osa;
2421.8Sthorpej	} */ *uap = v;
2431.1Sfvdl	struct linux_sigaction *nlsa, *olsa, tmplsa;
2441.6Smycroft	struct sigaction *nbsa, *obsa, tmpbsa;
2451.9Smycroft	struct sys_sigaction_args sa;
2461.1Sfvdl	caddr_t sg;
2471.1Sfvdl	int error;
2481.1Sfvdl
2491.5Schristos	sg = stackgap_init(p->p_emul);
2501.6Smycroft	nlsa = SCARG(uap, nsa);
2511.1Sfvdl	olsa = SCARG(uap, osa);
2521.1Sfvdl
2531.1Sfvdl	if (olsa != NULL)
2541.6Smycroft		obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
2551.6Smycroft	else
2561.6Smycroft		obsa = NULL;
2571.1Sfvdl
2581.1Sfvdl	if (nlsa != NULL) {
2591.6Smycroft		nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
2601.6Smycroft		if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
2611.1Sfvdl			return error;
2621.6Smycroft		linux_to_bsd_sigaction(&tmplsa, &tmpbsa);
2631.6Smycroft		if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
2641.1Sfvdl			return error;
2651.6Smycroft	} else
2661.6Smycroft		nbsa = NULL;
2671.1Sfvdl
2681.6Smycroft	SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
2691.6Smycroft	SCARG(&sa, nsa) = nbsa;
2701.6Smycroft	SCARG(&sa, osa) = obsa;
2711.1Sfvdl
2721.9Smycroft	if ((error = sys_sigaction(p, &sa, retval)) != 0)
2731.1Sfvdl		return error;
2741.1Sfvdl
2751.1Sfvdl	if (olsa != NULL) {
2761.6Smycroft		if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
2771.1Sfvdl			return error;
2781.6Smycroft		bsd_to_linux_sigaction(&tmpbsa, &tmplsa);
2791.6Smycroft		if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
2801.1Sfvdl			return error;
2811.1Sfvdl	}
2821.6Smycroft
2831.1Sfvdl	return 0;
2841.1Sfvdl}
2851.1Sfvdl
2861.1Sfvdl/*
2871.1Sfvdl * The Linux signal() system call. I think that the signal() in the C
2881.1Sfvdl * library actually calls sigaction, so I doubt this one is ever used.
2891.1Sfvdl * But hey, it can't hurt having it here. The same restrictions as for
2901.1Sfvdl * sigaction() apply.
2911.1Sfvdl */
2921.1Sfvdlint
2931.9Smycroftlinux_sys_signal(p, v, retval)
2941.1Sfvdl	register struct proc *p;
2951.8Sthorpej	void *v;
2961.8Sthorpej	register_t *retval;
2971.8Sthorpej{
2981.9Smycroft	struct linux_sys_signal_args /* {
2991.1Sfvdl		syscallarg(int) sig;
3001.1Sfvdl		syscallarg(linux_handler_t) handler;
3011.8Sthorpej	} */ *uap = v;
3021.1Sfvdl	caddr_t sg;
3031.9Smycroft	struct sys_sigaction_args sa_args;
3041.1Sfvdl	struct sigaction *osa, *nsa, tmpsa;
3051.1Sfvdl	int error;
3061.1Sfvdl
3071.5Schristos	sg = stackgap_init(p->p_emul);
3081.1Sfvdl	nsa = stackgap_alloc(&sg, sizeof *nsa);
3091.1Sfvdl	osa = stackgap_alloc(&sg, sizeof *osa);
3101.1Sfvdl
3111.1Sfvdl	tmpsa.sa_handler = SCARG(uap, handler);
3121.1Sfvdl	tmpsa.sa_mask = (sigset_t) 0;
3131.6Smycroft	tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
3141.1Sfvdl	if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
3151.1Sfvdl		return error;
3161.1Sfvdl
3171.6Smycroft	SCARG(&sa_args, signum) = linux_to_bsd_sig[SCARG(uap, sig)];
3181.1Sfvdl	SCARG(&sa_args, osa) = osa;
3191.1Sfvdl	SCARG(&sa_args, nsa) = nsa;
3201.9Smycroft	if ((error = sys_sigaction(p, &sa_args, retval)))
3211.1Sfvdl		return error;
3221.1Sfvdl
3231.1Sfvdl	if ((error = copyin(osa, &tmpsa, sizeof *osa)))
3241.1Sfvdl		return error;
3251.1Sfvdl	retval[0] = (register_t) tmpsa.sa_handler;
3261.1Sfvdl
3271.1Sfvdl	return 0;
3281.1Sfvdl}
3291.1Sfvdl
3301.1Sfvdl/*
3311.1Sfvdl * This is just a copy of the svr4 compat one. I feel so creative now.
3321.1Sfvdl */
3331.1Sfvdlint
3341.9Smycroftlinux_sys_sigprocmask(p, v, retval)
3351.1Sfvdl	register struct proc *p;
3361.8Sthorpej	void *v;
3371.8Sthorpej	register_t *retval;
3381.8Sthorpej{
3391.9Smycroft	struct linux_sys_sigprocmask_args /* {
3401.1Sfvdl		syscallarg(int) how;
3411.1Sfvdl		syscallarg(linux_sigset_t *) set;
3421.6Smycroft		syscallarg(linux_sigset_t *) oset;
3431.8Sthorpej	} */ *uap = v;
3441.1Sfvdl	linux_sigset_t ss;
3451.1Sfvdl	sigset_t bs;
3461.1Sfvdl	int error = 0;
3471.1Sfvdl
3481.1Sfvdl	*retval = 0;
3491.1Sfvdl
3501.1Sfvdl	if (SCARG(uap, oset) != NULL) {
3511.1Sfvdl		/* Fix the return value first if needed */
3521.1Sfvdl		bsd_to_linux_sigset(&p->p_sigmask, &ss);
3531.1Sfvdl		if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0)
3541.1Sfvdl			return error;
3551.1Sfvdl	}
3561.1Sfvdl
3571.1Sfvdl	if (SCARG(uap, set) == NULL)
3581.1Sfvdl		/* Just examine */
3591.1Sfvdl		return 0;
3601.1Sfvdl
3611.1Sfvdl	if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0)
3621.1Sfvdl		return error;
3631.1Sfvdl
3641.1Sfvdl	linux_to_bsd_sigset(&ss, &bs);
3651.1Sfvdl
3661.1Sfvdl	(void) splhigh();
3671.1Sfvdl
3681.1Sfvdl	switch (SCARG(uap, how)) {
3691.1Sfvdl	case LINUX_SIG_BLOCK:
3701.1Sfvdl		p->p_sigmask |= bs & ~sigcantmask;
3711.1Sfvdl		break;
3721.1Sfvdl
3731.1Sfvdl	case LINUX_SIG_UNBLOCK:
3741.1Sfvdl		p->p_sigmask &= ~bs;
3751.1Sfvdl		break;
3761.1Sfvdl
3771.1Sfvdl	case LINUX_SIG_SETMASK:
3781.1Sfvdl		p->p_sigmask = bs & ~sigcantmask;
3791.1Sfvdl		break;
3801.1Sfvdl
3811.1Sfvdl	default:
3821.1Sfvdl		error = EINVAL;
3831.1Sfvdl		break;
3841.1Sfvdl	}
3851.1Sfvdl
3861.1Sfvdl	(void) spl0();
3871.1Sfvdl
3881.1Sfvdl	return error;
3891.1Sfvdl}
3901.1Sfvdl
3911.1Sfvdl/*
3921.1Sfvdl * The functions below really make no distinction between an int
3931.1Sfvdl * and [linux_]sigset_t. This is ok for now, but it might break
3941.1Sfvdl * sometime. Then again, sigset_t is trusted to be an int everywhere
3951.1Sfvdl * else in the kernel too.
3961.1Sfvdl */
3971.1Sfvdl/* ARGSUSED */
3981.1Sfvdlint
3991.9Smycroftlinux_sys_siggetmask(p, v, retval)
4001.6Smycroft	register struct proc *p;
4011.9Smycroft	void *v;
4021.1Sfvdl	register_t *retval;
4031.1Sfvdl{
4041.6Smycroft
4051.6Smycroft	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
4061.1Sfvdl	return 0;
4071.1Sfvdl}
4081.1Sfvdl
4091.1Sfvdl/*
4101.1Sfvdl * The following three functions fiddle with a process' signal mask.
4111.1Sfvdl * Convert the signal masks because of the different signal
4121.1Sfvdl * values for Linux. The need for this is the reason why
4131.1Sfvdl * they are here, and have not been mapped directly.
4141.1Sfvdl */
4151.1Sfvdlint
4161.9Smycroftlinux_sys_sigsetmask(p, v, retval)
4171.6Smycroft	register struct proc *p;
4181.8Sthorpej	void *v;
4191.8Sthorpej	register_t *retval;
4201.8Sthorpej{
4211.9Smycroft	struct linux_sys_sigsetmask_args /* {
4221.1Sfvdl		syscallarg(linux_sigset_t) mask;
4231.8Sthorpej	} */ *uap = v;
4241.1Sfvdl	linux_sigset_t mask;
4251.1Sfvdl	sigset_t bsdsig;
4261.1Sfvdl
4271.6Smycroft	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
4281.1Sfvdl
4291.1Sfvdl	mask = SCARG(uap, mask);
4301.10Schristos	bsd_to_linux_sigset(&bsdsig, &mask);
4311.1Sfvdl
4321.1Sfvdl	splhigh();
4331.1Sfvdl	p->p_sigmask = bsdsig & ~sigcantmask;
4341.1Sfvdl	spl0();
4351.1Sfvdl
4361.1Sfvdl	return 0;
4371.1Sfvdl}
4381.1Sfvdl
4391.1Sfvdlint
4401.9Smycroftlinux_sys_sigpending(p, v, retval)
4411.6Smycroft	register struct proc *p;
4421.8Sthorpej	void *v;
4431.8Sthorpej	register_t *retval;
4441.8Sthorpej{
4451.9Smycroft	struct linux_sys_sigpending_args /* {
4461.1Sfvdl		syscallarg(linux_sigset_t *) mask;
4471.8Sthorpej	} */ *uap = v;
4481.6Smycroft	sigset_t bs;
4491.6Smycroft	linux_sigset_t ls;
4501.1Sfvdl
4511.6Smycroft	bs = p->p_siglist & p->p_sigmask;
4521.6Smycroft	bsd_to_linux_sigset(&bs, &ls);
4531.1Sfvdl
4541.6Smycroft	return copyout(&ls, SCARG(uap, mask), sizeof(ls));
4551.1Sfvdl}
4561.1Sfvdl
4571.1Sfvdlint
4581.9Smycroftlinux_sys_sigsuspend(p, v, retval)
4591.6Smycroft	register struct proc *p;
4601.8Sthorpej	void *v;
4611.8Sthorpej	register_t *retval;
4621.8Sthorpej{
4631.9Smycroft	struct linux_sys_sigsuspend_args /* {
4641.3Sfvdl		syscallarg(caddr_t) restart;
4651.3Sfvdl		syscallarg(int) oldmask;
4661.1Sfvdl		syscallarg(int) mask;
4671.8Sthorpej	} */ *uap = v;
4681.9Smycroft	struct sys_sigsuspend_args sa;
4691.10Schristos	linux_sigset_t mask = SCARG(uap, mask);
4701.1Sfvdl
4711.10Schristos	linux_to_bsd_sigset(&mask, &SCARG(&sa, mask));
4721.9Smycroft	return sys_sigsuspend(p, &sa, retval);
4731.3Sfvdl}
4741.3Sfvdl
4751.3Sfvdl/*
4761.3Sfvdl * The deprecated pause(2), which is really just an instance
4771.3Sfvdl * of sigsuspend(2).
4781.3Sfvdl */
4791.3Sfvdlint
4801.9Smycroftlinux_sys_pause(p, v, retval)
4811.6Smycroft	register struct proc *p;
4821.9Smycroft	void *v;
4831.3Sfvdl	register_t *retval;
4841.3Sfvdl{
4851.9Smycroft	struct sys_sigsuspend_args bsa;
4861.3Sfvdl
4871.3Sfvdl	SCARG(&bsa, mask) = p->p_sigmask;
4881.9Smycroft	return sys_sigsuspend(p, &bsa, retval);
4891.1Sfvdl}
4901.1Sfvdl
4911.1Sfvdl/*
4921.1Sfvdl * Once more: only a signal conversion is needed.
4931.1Sfvdl */
4941.1Sfvdlint
4951.9Smycroftlinux_sys_kill(p, v, retval)
4961.6Smycroft	register struct proc *p;
4971.8Sthorpej	void *v;
4981.8Sthorpej	register_t *retval;
4991.8Sthorpej{
5001.9Smycroft	struct linux_sys_kill_args /* {
5011.1Sfvdl		syscallarg(int) pid;
5021.1Sfvdl		syscallarg(int) signum;
5031.8Sthorpej	} */ *uap = v;
5041.9Smycroft	struct sys_kill_args ka;
5051.6Smycroft
5061.6Smycroft	SCARG(&ka, pid) = SCARG(uap, pid);
5071.6Smycroft	SCARG(&ka, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
5081.9Smycroft	return sys_kill(p, &ka, retval);
5091.1Sfvdl}
510