xref: /freebsd/sys/compat/linux/linux_signal.c (revision 1d9c56964d81bb47d6c0787d316f09984b064b5b)
1c21dee17SSøren Schmidt /*-
2c21dee17SSøren Schmidt  * Copyright (c) 1994-1995 S�ren Schmidt
3c21dee17SSøren Schmidt  * All rights reserved.
4c21dee17SSøren Schmidt  *
5c21dee17SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
6c21dee17SSøren Schmidt  * modification, are permitted provided that the following conditions
7c21dee17SSøren Schmidt  * are met:
8c21dee17SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
9c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer
10c21dee17SSøren Schmidt  *    in this position and unchanged.
11c21dee17SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
12c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
13c21dee17SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
14c21dee17SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
1521dc7d4fSJens Schweikhardt  *    derived from this software without specific prior written permission
16c21dee17SSøren Schmidt  *
17c21dee17SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18c21dee17SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19c21dee17SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20c21dee17SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21c21dee17SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22c21dee17SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23c21dee17SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24c21dee17SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25c21dee17SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26c21dee17SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27c21dee17SSøren Schmidt  *
28c3aac50fSPeter Wemm  * $FreeBSD$
29c21dee17SSøren Schmidt  */
30c21dee17SSøren Schmidt 
31c21dee17SSøren Schmidt #include <sys/param.h>
32c21dee17SSøren Schmidt #include <sys/systm.h>
33fb919e4dSMark Murray #include <sys/lock.h>
34fb919e4dSMark Murray #include <sys/mutex.h>
35c21dee17SSøren Schmidt #include <sys/proc.h>
36c21dee17SSøren Schmidt #include <sys/signalvar.h>
37206a5d3aSIan Dowse #include <sys/syscallsubr.h>
38fb919e4dSMark Murray #include <sys/sysproto.h>
39c21dee17SSøren Schmidt 
40ba9ef45bSMarcel Moolenaar #include <machine/../linux/linux.h>
41ebea8660SMarcel Moolenaar #include <machine/../linux/linux_proto.h>
42ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_signal.h>
43ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_util.h>
44c21dee17SSøren Schmidt 
45ba9ef45bSMarcel Moolenaar void
465002a60fSMarcel Moolenaar linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
47956d3333SMarcel Moolenaar {
48d66a5066SPeter Wemm 	int b, l;
49c21dee17SSøren Schmidt 
50956d3333SMarcel Moolenaar 	SIGEMPTYSET(*bss);
51956d3333SMarcel Moolenaar 	bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
52956d3333SMarcel Moolenaar 	bss->__bits[1] = lss->__bits[1];
53956d3333SMarcel Moolenaar 	for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
54956d3333SMarcel Moolenaar 		if (LINUX_SIGISMEMBER(*lss, l)) {
555231fb20SDavid E. O'Brien #ifdef __alpha__
565231fb20SDavid E. O'Brien 			b = _SIG_IDX(l);
575231fb20SDavid E. O'Brien #else
58956d3333SMarcel Moolenaar 			b = linux_to_bsd_signal[_SIG_IDX(l)];
595231fb20SDavid E. O'Brien #endif
60956d3333SMarcel Moolenaar 			if (b)
61956d3333SMarcel Moolenaar 				SIGADDSET(*bss, b);
62d66a5066SPeter Wemm 		}
63d66a5066SPeter Wemm 	}
64c21dee17SSøren Schmidt }
65c21dee17SSøren Schmidt 
6679363394SAndrew Gallatin void
675002a60fSMarcel Moolenaar bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
68956d3333SMarcel Moolenaar {
69d66a5066SPeter Wemm 	int b, l;
70c21dee17SSøren Schmidt 
71956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(*lss);
72956d3333SMarcel Moolenaar 	lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
73956d3333SMarcel Moolenaar 	lss->__bits[1] = bss->__bits[1];
74956d3333SMarcel Moolenaar 	for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
75956d3333SMarcel Moolenaar 		if (SIGISMEMBER(*bss, b)) {
765231fb20SDavid E. O'Brien #if __alpha__
775231fb20SDavid E. O'Brien 			l = _SIG_IDX(b);
785231fb20SDavid E. O'Brien #else
79956d3333SMarcel Moolenaar 			l = bsd_to_linux_signal[_SIG_IDX(b)];
805231fb20SDavid E. O'Brien #endif
81956d3333SMarcel Moolenaar 			if (l)
82956d3333SMarcel Moolenaar 				LINUX_SIGADDSET(*lss, l);
83d66a5066SPeter Wemm 		}
84d66a5066SPeter Wemm 	}
85c21dee17SSøren Schmidt }
86c21dee17SSøren Schmidt 
87a1ebcbfbSPeter Wemm static void
885002a60fSMarcel Moolenaar linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
89d66a5066SPeter Wemm {
90956d3333SMarcel Moolenaar 
91956d3333SMarcel Moolenaar 	linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
928f437f44SMartin Cracauer 	bsa->sa_handler = lsa->lsa_handler;
93d66a5066SPeter Wemm 	bsa->sa_flags = 0;
948f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)
95d66a5066SPeter Wemm 		bsa->sa_flags |= SA_NOCLDSTOP;
9606ebbe77SMarcel Moolenaar 	if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT)
9706ebbe77SMarcel Moolenaar 		bsa->sa_flags |= SA_NOCLDWAIT;
9806ebbe77SMarcel Moolenaar 	if (lsa->lsa_flags & LINUX_SA_SIGINFO)
9906ebbe77SMarcel Moolenaar 		bsa->sa_flags |= SA_SIGINFO;
1008f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_ONSTACK)
101d66a5066SPeter Wemm 		bsa->sa_flags |= SA_ONSTACK;
1028f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_RESTART)
103d66a5066SPeter Wemm 		bsa->sa_flags |= SA_RESTART;
1048f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_ONESHOT)
105d66a5066SPeter Wemm 		bsa->sa_flags |= SA_RESETHAND;
1068f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_NOMASK)
107d66a5066SPeter Wemm 		bsa->sa_flags |= SA_NODEFER;
108d66a5066SPeter Wemm }
109d66a5066SPeter Wemm 
110a1ebcbfbSPeter Wemm static void
1115002a60fSMarcel Moolenaar bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
112d66a5066SPeter Wemm {
113956d3333SMarcel Moolenaar 
114956d3333SMarcel Moolenaar 	bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
1158f437f44SMartin Cracauer 	lsa->lsa_handler = bsa->sa_handler;
1168f437f44SMartin Cracauer 	lsa->lsa_restorer = NULL;	/* unsupported */
1178f437f44SMartin Cracauer 	lsa->lsa_flags = 0;
118d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_NOCLDSTOP)
1198f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
12006ebbe77SMarcel Moolenaar 	if (bsa->sa_flags & SA_NOCLDWAIT)
12106ebbe77SMarcel Moolenaar 		lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
12206ebbe77SMarcel Moolenaar 	if (bsa->sa_flags & SA_SIGINFO)
12306ebbe77SMarcel Moolenaar 		lsa->lsa_flags |= LINUX_SA_SIGINFO;
124d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_ONSTACK)
1258f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_ONSTACK;
126d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_RESTART)
1278f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_RESTART;
128d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_RESETHAND)
1298f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_ONESHOT;
130d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_NODEFER)
1318f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_NOMASK;
132d66a5066SPeter Wemm }
133c21dee17SSøren Schmidt 
134ba9ef45bSMarcel Moolenaar int
135b40ce416SJulian Elischer linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
1365002a60fSMarcel Moolenaar 		   l_sigaction_t *linux_osa)
13706ebbe77SMarcel Moolenaar {
138206a5d3aSIan Dowse 	struct sigaction act, oact, *nsa, *osa;
139206a5d3aSIan Dowse 	int error, sig;
14006ebbe77SMarcel Moolenaar 
141956d3333SMarcel Moolenaar 	if (linux_sig <= 0 || linux_sig > LINUX_NSIG)
142956d3333SMarcel Moolenaar 		return (EINVAL);
14306ebbe77SMarcel Moolenaar 
144206a5d3aSIan Dowse 	osa = (linux_osa != NULL) ? &oact : NULL;
145956d3333SMarcel Moolenaar 	if (linux_nsa != NULL) {
146206a5d3aSIan Dowse 		nsa = &act;
147ec99e322SMarcel Moolenaar 		linux_to_bsd_sigaction(linux_nsa, nsa);
148206a5d3aSIan Dowse 	} else
14906ebbe77SMarcel Moolenaar 		nsa = NULL;
15006ebbe77SMarcel Moolenaar 
1515231fb20SDavid E. O'Brien #ifndef __alpha__
152956d3333SMarcel Moolenaar 	if (linux_sig <= LINUX_SIGTBLSZ)
153206a5d3aSIan Dowse 		sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
154956d3333SMarcel Moolenaar 	else
1555231fb20SDavid E. O'Brien #endif
156206a5d3aSIan Dowse 		sig = linux_sig;
157956d3333SMarcel Moolenaar 
158206a5d3aSIan Dowse 	error = kern_sigaction(td, sig, nsa, osa, 0);
15906ebbe77SMarcel Moolenaar 	if (error)
160956d3333SMarcel Moolenaar 		return (error);
16106ebbe77SMarcel Moolenaar 
162ec99e322SMarcel Moolenaar 	if (linux_osa != NULL)
163ec99e322SMarcel Moolenaar 		bsd_to_linux_sigaction(osa, linux_osa);
16406ebbe77SMarcel Moolenaar 
165956d3333SMarcel Moolenaar 	return (0);
16606ebbe77SMarcel Moolenaar }
16706ebbe77SMarcel Moolenaar 
1685231fb20SDavid E. O'Brien 
1695231fb20SDavid E. O'Brien #ifndef __alpha__
170c21dee17SSøren Schmidt int
171b40ce416SJulian Elischer linux_signal(struct thread *td, struct linux_signal_args *args)
172d66a5066SPeter Wemm {
1735002a60fSMarcel Moolenaar 	l_sigaction_t nsa, osa;
174d66a5066SPeter Wemm 	int error;
175d66a5066SPeter Wemm 
176d66a5066SPeter Wemm #ifdef DEBUG
17724593369SJonathan Lemon 	if (ldebug(signal))
17824593369SJonathan Lemon 		printf(ARGS(signal, "%d, %p"),
17924593369SJonathan Lemon 		    args->sig, (void *)args->handler);
180d66a5066SPeter Wemm #endif
181d66a5066SPeter Wemm 
18206ebbe77SMarcel Moolenaar 	nsa.lsa_handler = args->handler;
18306ebbe77SMarcel Moolenaar 	nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
184956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(nsa.lsa_mask);
185d66a5066SPeter Wemm 
186b40ce416SJulian Elischer 	error = linux_do_sigaction(td, args->sig, &nsa, &osa);
187b40ce416SJulian Elischer 	td->td_retval[0] = (int)osa.lsa_handler;
188d66a5066SPeter Wemm 
189956d3333SMarcel Moolenaar 	return (error);
190d66a5066SPeter Wemm }
1915231fb20SDavid E. O'Brien #endif	/*!__alpha__*/
192d66a5066SPeter Wemm 
193c21dee17SSøren Schmidt int
194b40ce416SJulian Elischer linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
195c21dee17SSøren Schmidt {
1965002a60fSMarcel Moolenaar 	l_sigaction_t nsa, osa;
19706ebbe77SMarcel Moolenaar 	int error;
198c21dee17SSøren Schmidt 
199c21dee17SSøren Schmidt #ifdef DEBUG
20024593369SJonathan Lemon 	if (ldebug(rt_sigaction))
20124593369SJonathan Lemon 		printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"),
20224593369SJonathan Lemon 		    (long)args->sig, (void *)args->act,
2035231fb20SDavid E. O'Brien 		    (void *)args->oact, (long)args->sigsetsize);
204c21dee17SSøren Schmidt #endif
205d66a5066SPeter Wemm 
2065002a60fSMarcel Moolenaar 	if (args->sigsetsize != sizeof(l_sigset_t))
207956d3333SMarcel Moolenaar 		return (EINVAL);
20806ebbe77SMarcel Moolenaar 
209956d3333SMarcel Moolenaar 	if (args->act != NULL) {
2105002a60fSMarcel Moolenaar 		error = copyin(args->act, &nsa, sizeof(l_sigaction_t));
21106ebbe77SMarcel Moolenaar 		if (error)
212956d3333SMarcel Moolenaar 			return (error);
21306ebbe77SMarcel Moolenaar 	}
21406ebbe77SMarcel Moolenaar 
215b40ce416SJulian Elischer 	error = linux_do_sigaction(td, args->sig,
21606ebbe77SMarcel Moolenaar 				   args->act ? &nsa : NULL,
21706ebbe77SMarcel Moolenaar 				   args->oact ? &osa : NULL);
21806ebbe77SMarcel Moolenaar 
219956d3333SMarcel Moolenaar 	if (args->oact != NULL && !error) {
2205002a60fSMarcel Moolenaar 		error = copyout(&osa, args->oact, sizeof(l_sigaction_t));
22106ebbe77SMarcel Moolenaar 	}
22206ebbe77SMarcel Moolenaar 
223956d3333SMarcel Moolenaar 	return (error);
22406ebbe77SMarcel Moolenaar }
22506ebbe77SMarcel Moolenaar 
22606ebbe77SMarcel Moolenaar static int
227b40ce416SJulian Elischer linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
2285002a60fSMarcel Moolenaar 		     l_sigset_t *old)
22906ebbe77SMarcel Moolenaar {
230216af822SJohn Baldwin 	int error;
23106ebbe77SMarcel Moolenaar 	sigset_t mask;
232b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
23306ebbe77SMarcel Moolenaar 
234956d3333SMarcel Moolenaar 	error = 0;
235b40ce416SJulian Elischer 	td->td_retval[0] = 0;
236d66a5066SPeter Wemm 
237216af822SJohn Baldwin 	PROC_LOCK(p);
23806ebbe77SMarcel Moolenaar 	if (old != NULL)
239956d3333SMarcel Moolenaar 		bsd_to_linux_sigset(&p->p_sigmask, old);
240c21dee17SSøren Schmidt 
24106ebbe77SMarcel Moolenaar 	if (new != NULL) {
242956d3333SMarcel Moolenaar 		linux_to_bsd_sigset(new, &mask);
24306ebbe77SMarcel Moolenaar 
24406ebbe77SMarcel Moolenaar 		switch (how) {
245c21dee17SSøren Schmidt 		case LINUX_SIG_BLOCK:
246956d3333SMarcel Moolenaar 			SIGSETOR(p->p_sigmask, mask);
247956d3333SMarcel Moolenaar 			SIG_CANTMASK(p->p_sigmask);
248c21dee17SSøren Schmidt 			break;
249c21dee17SSøren Schmidt 		case LINUX_SIG_UNBLOCK:
250956d3333SMarcel Moolenaar 			SIGSETNAND(p->p_sigmask, mask);
25179065dbaSBruce Evans 			signotify(p);
252c21dee17SSøren Schmidt 			break;
253c21dee17SSøren Schmidt 		case LINUX_SIG_SETMASK:
254956d3333SMarcel Moolenaar 			p->p_sigmask = mask;
255956d3333SMarcel Moolenaar 			SIG_CANTMASK(p->p_sigmask);
25679065dbaSBruce Evans 			signotify(p);
257c21dee17SSøren Schmidt 			break;
258c21dee17SSøren Schmidt 		default:
259c21dee17SSøren Schmidt 			error = EINVAL;
260c21dee17SSøren Schmidt 			break;
261c21dee17SSøren Schmidt 		}
26206ebbe77SMarcel Moolenaar 	}
263216af822SJohn Baldwin 	PROC_UNLOCK(p);
26406ebbe77SMarcel Moolenaar 
265956d3333SMarcel Moolenaar 	return (error);
26606ebbe77SMarcel Moolenaar }
26706ebbe77SMarcel Moolenaar 
2685231fb20SDavid E. O'Brien #ifndef __alpha__
26906ebbe77SMarcel Moolenaar int
270b40ce416SJulian Elischer linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
27106ebbe77SMarcel Moolenaar {
2725002a60fSMarcel Moolenaar 	l_osigset_t mask;
2735002a60fSMarcel Moolenaar 	l_sigset_t set, oset;
27406ebbe77SMarcel Moolenaar 	int error;
27506ebbe77SMarcel Moolenaar 
27606ebbe77SMarcel Moolenaar #ifdef DEBUG
27724593369SJonathan Lemon 	if (ldebug(sigprocmask))
27824593369SJonathan Lemon 		printf(ARGS(sigprocmask, "%d, *, *"), args->how);
27906ebbe77SMarcel Moolenaar #endif
28006ebbe77SMarcel Moolenaar 
28106ebbe77SMarcel Moolenaar 	if (args->mask != NULL) {
2825002a60fSMarcel Moolenaar 		error = copyin(args->mask, &mask, sizeof(l_osigset_t));
28306ebbe77SMarcel Moolenaar 		if (error)
284956d3333SMarcel Moolenaar 			return (error);
285956d3333SMarcel Moolenaar 		LINUX_SIGEMPTYSET(set);
286956d3333SMarcel Moolenaar 		set.__bits[0] = mask;
28706ebbe77SMarcel Moolenaar 	}
28806ebbe77SMarcel Moolenaar 
289b40ce416SJulian Elischer 	error = linux_do_sigprocmask(td, args->how,
290956d3333SMarcel Moolenaar 				     args->mask ? &set : NULL,
291956d3333SMarcel Moolenaar 				     args->omask ? &oset : NULL);
29206ebbe77SMarcel Moolenaar 
293956d3333SMarcel Moolenaar 	if (args->omask != NULL && !error) {
294956d3333SMarcel Moolenaar 		mask = oset.__bits[0];
2955002a60fSMarcel Moolenaar 		error = copyout(&mask, args->omask, sizeof(l_osigset_t));
29606ebbe77SMarcel Moolenaar 	}
29706ebbe77SMarcel Moolenaar 
298956d3333SMarcel Moolenaar 	return (error);
29906ebbe77SMarcel Moolenaar }
3005231fb20SDavid E. O'Brien #endif	/*!__alpha__*/
30106ebbe77SMarcel Moolenaar 
30206ebbe77SMarcel Moolenaar int
303b40ce416SJulian Elischer linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
30406ebbe77SMarcel Moolenaar {
3055002a60fSMarcel Moolenaar 	l_sigset_t set, oset;
30606ebbe77SMarcel Moolenaar 	int error;
30706ebbe77SMarcel Moolenaar 
30806ebbe77SMarcel Moolenaar #ifdef DEBUG
30924593369SJonathan Lemon 	if (ldebug(rt_sigprocmask))
31024593369SJonathan Lemon 		printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"),
31124593369SJonathan Lemon 		    args->how, (void *)args->mask,
3125231fb20SDavid E. O'Brien 		    (void *)args->omask, (long)args->sigsetsize);
31306ebbe77SMarcel Moolenaar #endif
31406ebbe77SMarcel Moolenaar 
3155002a60fSMarcel Moolenaar 	if (args->sigsetsize != sizeof(l_sigset_t))
31606ebbe77SMarcel Moolenaar 		return EINVAL;
31706ebbe77SMarcel Moolenaar 
31806ebbe77SMarcel Moolenaar 	if (args->mask != NULL) {
3195002a60fSMarcel Moolenaar 		error = copyin(args->mask, &set, sizeof(l_sigset_t));
32006ebbe77SMarcel Moolenaar 		if (error)
321956d3333SMarcel Moolenaar 			return (error);
32206ebbe77SMarcel Moolenaar 	}
32306ebbe77SMarcel Moolenaar 
324b40ce416SJulian Elischer 	error = linux_do_sigprocmask(td, args->how,
325956d3333SMarcel Moolenaar 				     args->mask ? &set : NULL,
326956d3333SMarcel Moolenaar 				     args->omask ? &oset : NULL);
32706ebbe77SMarcel Moolenaar 
328956d3333SMarcel Moolenaar 	if (args->omask != NULL && !error) {
3295002a60fSMarcel Moolenaar 		error = copyout(&oset, args->omask, sizeof(l_sigset_t));
33006ebbe77SMarcel Moolenaar 	}
33106ebbe77SMarcel Moolenaar 
332956d3333SMarcel Moolenaar 	return (error);
333c21dee17SSøren Schmidt }
334c21dee17SSøren Schmidt 
3355231fb20SDavid E. O'Brien #ifndef __alpha__
336c21dee17SSøren Schmidt int
337b40ce416SJulian Elischer linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
338c21dee17SSøren Schmidt {
339b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
3405002a60fSMarcel Moolenaar 	l_sigset_t mask;
341956d3333SMarcel Moolenaar 
342c21dee17SSøren Schmidt #ifdef DEBUG
3435002a60fSMarcel Moolenaar 	if (ldebug(sgetmask))
3445002a60fSMarcel Moolenaar 		printf(ARGS(sgetmask, ""));
345c21dee17SSøren Schmidt #endif
346956d3333SMarcel Moolenaar 
347216af822SJohn Baldwin 	PROC_LOCK(p);
348956d3333SMarcel Moolenaar 	bsd_to_linux_sigset(&p->p_sigmask, &mask);
349216af822SJohn Baldwin 	PROC_UNLOCK(p);
350b40ce416SJulian Elischer 	td->td_retval[0] = mask.__bits[0];
351956d3333SMarcel Moolenaar 	return (0);
352c21dee17SSøren Schmidt }
353c21dee17SSøren Schmidt 
354c21dee17SSøren Schmidt int
355b40ce416SJulian Elischer linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
356c21dee17SSøren Schmidt {
357b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
3585002a60fSMarcel Moolenaar 	l_sigset_t lset;
359956d3333SMarcel Moolenaar 	sigset_t bset;
360c21dee17SSøren Schmidt 
361c21dee17SSøren Schmidt #ifdef DEBUG
3625002a60fSMarcel Moolenaar 	if (ldebug(ssetmask))
3635002a60fSMarcel Moolenaar 		printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
364c21dee17SSøren Schmidt #endif
365d66a5066SPeter Wemm 
366216af822SJohn Baldwin 	PROC_LOCK(p);
367956d3333SMarcel Moolenaar 	bsd_to_linux_sigset(&p->p_sigmask, &lset);
368b40ce416SJulian Elischer 	td->td_retval[0] = lset.__bits[0];
369956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(lset);
370956d3333SMarcel Moolenaar 	lset.__bits[0] = args->mask;
371956d3333SMarcel Moolenaar 	linux_to_bsd_sigset(&lset, &bset);
372956d3333SMarcel Moolenaar 	p->p_sigmask = bset;
373956d3333SMarcel Moolenaar 	SIG_CANTMASK(p->p_sigmask);
37479065dbaSBruce Evans 	signotify(p);
375216af822SJohn Baldwin 	PROC_UNLOCK(p);
376956d3333SMarcel Moolenaar 	return (0);
377c21dee17SSøren Schmidt }
378c21dee17SSøren Schmidt 
379c21dee17SSøren Schmidt int
380b40ce416SJulian Elischer linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
381c21dee17SSøren Schmidt {
382b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
383956d3333SMarcel Moolenaar 	sigset_t bset;
3845002a60fSMarcel Moolenaar 	l_sigset_t lset;
3855002a60fSMarcel Moolenaar 	l_osigset_t mask;
386c21dee17SSøren Schmidt 
387c21dee17SSøren Schmidt #ifdef DEBUG
38824593369SJonathan Lemon 	if (ldebug(sigpending))
38924593369SJonathan Lemon 		printf(ARGS(sigpending, "*"));
390c21dee17SSøren Schmidt #endif
391956d3333SMarcel Moolenaar 
392216af822SJohn Baldwin 	PROC_LOCK(p);
3931d9c5696SJuli Mallett 	bset = p->p_siglist;
394956d3333SMarcel Moolenaar 	SIGSETAND(bset, p->p_sigmask);
395956d3333SMarcel Moolenaar 	bsd_to_linux_sigset(&bset, &lset);
396216af822SJohn Baldwin 	PROC_UNLOCK(p);
397956d3333SMarcel Moolenaar 	mask = lset.__bits[0];
398956d3333SMarcel Moolenaar 	return (copyout(&mask, args->mask, sizeof(mask)));
399c21dee17SSøren Schmidt }
4005231fb20SDavid E. O'Brien #endif	/*!__alpha__*/
401c21dee17SSøren Schmidt 
402c21dee17SSøren Schmidt int
403b40ce416SJulian Elischer linux_kill(struct thread *td, struct linux_kill_args *args)
404c21dee17SSøren Schmidt {
405ef04503dSPeter Wemm 	struct kill_args /* {
406c21dee17SSøren Schmidt 	    int pid;
407c21dee17SSøren Schmidt 	    int signum;
408ef04503dSPeter Wemm 	} */ tmp;
409c21dee17SSøren Schmidt 
410c21dee17SSøren Schmidt #ifdef DEBUG
41124593369SJonathan Lemon 	if (ldebug(kill))
41224593369SJonathan Lemon 		printf(ARGS(kill, "%d, %d"), args->pid, args->signum);
413c21dee17SSøren Schmidt #endif
414956d3333SMarcel Moolenaar 
415956d3333SMarcel Moolenaar 	/*
416956d3333SMarcel Moolenaar 	 * Allow signal 0 as a means to check for privileges
417956d3333SMarcel Moolenaar 	 */
418956d3333SMarcel Moolenaar 	if (args->signum < 0 || args->signum > LINUX_NSIG)
4192116e6abSJohn Polstra 		return EINVAL;
420956d3333SMarcel Moolenaar 
4215231fb20SDavid E. O'Brien #ifndef __alpha__
422956d3333SMarcel Moolenaar 	if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
423956d3333SMarcel Moolenaar 		tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
424956d3333SMarcel Moolenaar 	else
4255231fb20SDavid E. O'Brien #endif
426956d3333SMarcel Moolenaar 		tmp.signum = args->signum;
427956d3333SMarcel Moolenaar 
428c21dee17SSøren Schmidt 	tmp.pid = args->pid;
429b40ce416SJulian Elischer 	return (kill(td, &tmp));
430c21dee17SSøren Schmidt }
431