xref: /freebsd/sys/compat/linux/linux_signal.c (revision 647422169863e23cfe3a0c64f0491649f293d664)
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  */
28c21dee17SSøren Schmidt 
2916dbc7f2SDavid E. O'Brien #include <sys/cdefs.h>
301e8d246eSNate Lawson __FBSDID("$FreeBSD$");
3116dbc7f2SDavid E. O'Brien 
32c21dee17SSøren Schmidt #include <sys/param.h>
33c21dee17SSøren Schmidt #include <sys/systm.h>
34fb919e4dSMark Murray #include <sys/lock.h>
35fb919e4dSMark Murray #include <sys/mutex.h>
3629ddc19bSAlexander Leidinger #include <sys/sx.h>
37c21dee17SSøren Schmidt #include <sys/proc.h>
38c21dee17SSøren Schmidt #include <sys/signalvar.h>
39206a5d3aSIan Dowse #include <sys/syscallsubr.h>
40fb919e4dSMark Murray #include <sys/sysproto.h>
41c21dee17SSøren Schmidt 
42aefce619SRuslan Ermilov #include "opt_compat.h"
43aefce619SRuslan Ermilov 
441997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32
454af27623STim J. Robbins #include <machine/../linux32/linux.h>
464af27623STim J. Robbins #include <machine/../linux32/linux32_proto.h>
471997c537SDavid E. O'Brien #else
481997c537SDavid E. O'Brien #include <machine/../linux/linux.h>
491997c537SDavid E. O'Brien #include <machine/../linux/linux_proto.h>
504af27623STim J. Robbins #endif
51ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_signal.h>
52ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_util.h>
539b44bfc5SAlexander Leidinger #include <compat/linux/linux_emul.h>
549b44bfc5SAlexander Leidinger 
55ba9ef45bSMarcel Moolenaar void
565002a60fSMarcel Moolenaar linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
57956d3333SMarcel Moolenaar {
58d66a5066SPeter Wemm 	int b, l;
59c21dee17SSøren Schmidt 
60956d3333SMarcel Moolenaar 	SIGEMPTYSET(*bss);
61956d3333SMarcel Moolenaar 	bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
62956d3333SMarcel Moolenaar 	bss->__bits[1] = lss->__bits[1];
63956d3333SMarcel Moolenaar 	for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
64956d3333SMarcel Moolenaar 		if (LINUX_SIGISMEMBER(*lss, l)) {
65956d3333SMarcel Moolenaar 			b = linux_to_bsd_signal[_SIG_IDX(l)];
66956d3333SMarcel Moolenaar 			if (b)
67956d3333SMarcel Moolenaar 				SIGADDSET(*bss, b);
68d66a5066SPeter Wemm 		}
69d66a5066SPeter Wemm 	}
70c21dee17SSøren Schmidt }
71c21dee17SSøren Schmidt 
7279363394SAndrew Gallatin void
735002a60fSMarcel Moolenaar bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
74956d3333SMarcel Moolenaar {
75d66a5066SPeter Wemm 	int b, l;
76c21dee17SSøren Schmidt 
77956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(*lss);
78956d3333SMarcel Moolenaar 	lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
79956d3333SMarcel Moolenaar 	lss->__bits[1] = bss->__bits[1];
80956d3333SMarcel Moolenaar 	for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
81956d3333SMarcel Moolenaar 		if (SIGISMEMBER(*bss, b)) {
82956d3333SMarcel Moolenaar 			l = bsd_to_linux_signal[_SIG_IDX(b)];
83956d3333SMarcel Moolenaar 			if (l)
84956d3333SMarcel Moolenaar 				LINUX_SIGADDSET(*lss, l);
85d66a5066SPeter Wemm 		}
86d66a5066SPeter Wemm 	}
87c21dee17SSøren Schmidt }
88c21dee17SSøren Schmidt 
89a1ebcbfbSPeter Wemm static void
905002a60fSMarcel Moolenaar linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
91d66a5066SPeter Wemm {
92956d3333SMarcel Moolenaar 
93956d3333SMarcel Moolenaar 	linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
944af27623STim J. Robbins 	bsa->sa_handler = PTRIN(lsa->lsa_handler);
95d66a5066SPeter Wemm 	bsa->sa_flags = 0;
968f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)
97d66a5066SPeter Wemm 		bsa->sa_flags |= SA_NOCLDSTOP;
9806ebbe77SMarcel Moolenaar 	if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT)
9906ebbe77SMarcel Moolenaar 		bsa->sa_flags |= SA_NOCLDWAIT;
10006ebbe77SMarcel Moolenaar 	if (lsa->lsa_flags & LINUX_SA_SIGINFO)
10106ebbe77SMarcel Moolenaar 		bsa->sa_flags |= SA_SIGINFO;
1028f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_ONSTACK)
103d66a5066SPeter Wemm 		bsa->sa_flags |= SA_ONSTACK;
1048f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_RESTART)
105d66a5066SPeter Wemm 		bsa->sa_flags |= SA_RESTART;
1068f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_ONESHOT)
107d66a5066SPeter Wemm 		bsa->sa_flags |= SA_RESETHAND;
1088f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_NOMASK)
109d66a5066SPeter Wemm 		bsa->sa_flags |= SA_NODEFER;
110d66a5066SPeter Wemm }
111d66a5066SPeter Wemm 
112a1ebcbfbSPeter Wemm static void
1135002a60fSMarcel Moolenaar bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
114d66a5066SPeter Wemm {
115956d3333SMarcel Moolenaar 
116956d3333SMarcel Moolenaar 	bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
1171997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32
1184af27623STim J. Robbins 	lsa->lsa_handler = (uintptr_t)bsa->sa_handler;
1194af27623STim J. Robbins #else
1208f437f44SMartin Cracauer 	lsa->lsa_handler = bsa->sa_handler;
1214af27623STim J. Robbins #endif
1224af27623STim J. Robbins 	lsa->lsa_restorer = 0;		/* unsupported */
1238f437f44SMartin Cracauer 	lsa->lsa_flags = 0;
124d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_NOCLDSTOP)
1258f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
12606ebbe77SMarcel Moolenaar 	if (bsa->sa_flags & SA_NOCLDWAIT)
12706ebbe77SMarcel Moolenaar 		lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
12806ebbe77SMarcel Moolenaar 	if (bsa->sa_flags & SA_SIGINFO)
12906ebbe77SMarcel Moolenaar 		lsa->lsa_flags |= LINUX_SA_SIGINFO;
130d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_ONSTACK)
1318f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_ONSTACK;
132d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_RESTART)
1338f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_RESTART;
134d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_RESETHAND)
1358f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_ONESHOT;
136d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_NODEFER)
1378f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_NOMASK;
138d66a5066SPeter Wemm }
139c21dee17SSøren Schmidt 
140ba9ef45bSMarcel Moolenaar int
141b40ce416SJulian Elischer linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
1425002a60fSMarcel Moolenaar 		   l_sigaction_t *linux_osa)
14306ebbe77SMarcel Moolenaar {
144206a5d3aSIan Dowse 	struct sigaction act, oact, *nsa, *osa;
145206a5d3aSIan Dowse 	int error, sig;
14606ebbe77SMarcel Moolenaar 
147687c23beSAlexander Leidinger 	if (!LINUX_SIG_VALID(linux_sig))
148956d3333SMarcel Moolenaar 		return (EINVAL);
14906ebbe77SMarcel Moolenaar 
150206a5d3aSIan Dowse 	osa = (linux_osa != NULL) ? &oact : NULL;
151956d3333SMarcel Moolenaar 	if (linux_nsa != NULL) {
152206a5d3aSIan Dowse 		nsa = &act;
153ec99e322SMarcel Moolenaar 		linux_to_bsd_sigaction(linux_nsa, nsa);
154206a5d3aSIan Dowse 	} else
15506ebbe77SMarcel Moolenaar 		nsa = NULL;
15606ebbe77SMarcel Moolenaar 
157956d3333SMarcel Moolenaar 	if (linux_sig <= LINUX_SIGTBLSZ)
158206a5d3aSIan Dowse 		sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
159956d3333SMarcel Moolenaar 	else
160206a5d3aSIan Dowse 		sig = linux_sig;
161956d3333SMarcel Moolenaar 
162206a5d3aSIan Dowse 	error = kern_sigaction(td, sig, nsa, osa, 0);
16306ebbe77SMarcel Moolenaar 	if (error)
164956d3333SMarcel Moolenaar 		return (error);
16506ebbe77SMarcel Moolenaar 
166ec99e322SMarcel Moolenaar 	if (linux_osa != NULL)
167ec99e322SMarcel Moolenaar 		bsd_to_linux_sigaction(osa, linux_osa);
16806ebbe77SMarcel Moolenaar 
169956d3333SMarcel Moolenaar 	return (0);
17006ebbe77SMarcel Moolenaar }
17106ebbe77SMarcel Moolenaar 
1725231fb20SDavid E. O'Brien 
173c21dee17SSøren Schmidt int
174b40ce416SJulian Elischer linux_signal(struct thread *td, struct linux_signal_args *args)
175d66a5066SPeter Wemm {
1765002a60fSMarcel Moolenaar 	l_sigaction_t nsa, osa;
177d66a5066SPeter Wemm 	int error;
178d66a5066SPeter Wemm 
179d66a5066SPeter Wemm #ifdef DEBUG
18024593369SJonathan Lemon 	if (ldebug(signal))
18124593369SJonathan Lemon 		printf(ARGS(signal, "%d, %p"),
182b61c60d4SDavid E. O'Brien 		    args->sig, (void *)(uintptr_t)args->handler);
183d66a5066SPeter Wemm #endif
184d66a5066SPeter Wemm 
18506ebbe77SMarcel Moolenaar 	nsa.lsa_handler = args->handler;
18606ebbe77SMarcel Moolenaar 	nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
187956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(nsa.lsa_mask);
188d66a5066SPeter Wemm 
189b40ce416SJulian Elischer 	error = linux_do_sigaction(td, args->sig, &nsa, &osa);
1904af27623STim J. Robbins 	td->td_retval[0] = (int)(intptr_t)osa.lsa_handler;
191d66a5066SPeter Wemm 
192956d3333SMarcel Moolenaar 	return (error);
193d66a5066SPeter Wemm }
194d66a5066SPeter Wemm 
195c21dee17SSøren Schmidt int
196b40ce416SJulian Elischer linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
197c21dee17SSøren Schmidt {
1985002a60fSMarcel Moolenaar 	l_sigaction_t nsa, osa;
19906ebbe77SMarcel Moolenaar 	int error;
200c21dee17SSøren Schmidt 
201c21dee17SSøren Schmidt #ifdef DEBUG
20224593369SJonathan Lemon 	if (ldebug(rt_sigaction))
20324593369SJonathan Lemon 		printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"),
20424593369SJonathan Lemon 		    (long)args->sig, (void *)args->act,
2055231fb20SDavid E. O'Brien 		    (void *)args->oact, (long)args->sigsetsize);
206c21dee17SSøren Schmidt #endif
207d66a5066SPeter Wemm 
2085002a60fSMarcel Moolenaar 	if (args->sigsetsize != sizeof(l_sigset_t))
209956d3333SMarcel Moolenaar 		return (EINVAL);
21006ebbe77SMarcel Moolenaar 
211956d3333SMarcel Moolenaar 	if (args->act != NULL) {
2125002a60fSMarcel Moolenaar 		error = copyin(args->act, &nsa, sizeof(l_sigaction_t));
21306ebbe77SMarcel Moolenaar 		if (error)
214956d3333SMarcel Moolenaar 			return (error);
21506ebbe77SMarcel Moolenaar 	}
21606ebbe77SMarcel Moolenaar 
217b40ce416SJulian Elischer 	error = linux_do_sigaction(td, args->sig,
21806ebbe77SMarcel Moolenaar 				   args->act ? &nsa : NULL,
21906ebbe77SMarcel Moolenaar 				   args->oact ? &osa : NULL);
22006ebbe77SMarcel Moolenaar 
221956d3333SMarcel Moolenaar 	if (args->oact != NULL && !error) {
2225002a60fSMarcel Moolenaar 		error = copyout(&osa, args->oact, sizeof(l_sigaction_t));
22306ebbe77SMarcel Moolenaar 	}
22406ebbe77SMarcel Moolenaar 
225956d3333SMarcel Moolenaar 	return (error);
22606ebbe77SMarcel Moolenaar }
22706ebbe77SMarcel Moolenaar 
22806ebbe77SMarcel Moolenaar static int
229b40ce416SJulian Elischer linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
2305002a60fSMarcel Moolenaar 		     l_sigset_t *old)
23106ebbe77SMarcel Moolenaar {
232fe8cdcaeSJohn Baldwin 	sigset_t omask, nmask;
233fe8cdcaeSJohn Baldwin 	sigset_t *nmaskp;
234216af822SJohn Baldwin 	int error;
23506ebbe77SMarcel Moolenaar 
236b40ce416SJulian Elischer 	td->td_retval[0] = 0;
237d66a5066SPeter Wemm 
23819dde5cdSJohn Baldwin 	switch (how) {
23919dde5cdSJohn Baldwin 	case LINUX_SIG_BLOCK:
24019dde5cdSJohn Baldwin 		how = SIG_BLOCK;
24119dde5cdSJohn Baldwin 		break;
24219dde5cdSJohn Baldwin 	case LINUX_SIG_UNBLOCK:
24319dde5cdSJohn Baldwin 		how = SIG_UNBLOCK;
24419dde5cdSJohn Baldwin 		break;
24519dde5cdSJohn Baldwin 	case LINUX_SIG_SETMASK:
24619dde5cdSJohn Baldwin 		how = SIG_SETMASK;
24719dde5cdSJohn Baldwin 		break;
24819dde5cdSJohn Baldwin 	default:
24919dde5cdSJohn Baldwin 		return (EINVAL);
25019dde5cdSJohn Baldwin 	}
25106ebbe77SMarcel Moolenaar 	if (new != NULL) {
252fe8cdcaeSJohn Baldwin 		linux_to_bsd_sigset(new, &nmask);
253fe8cdcaeSJohn Baldwin 		nmaskp = &nmask;
254fe8cdcaeSJohn Baldwin 	} else
255fe8cdcaeSJohn Baldwin 		nmaskp = NULL;
25619dde5cdSJohn Baldwin 	error = kern_sigprocmask(td, how, nmaskp, &omask, 0);
2572f7ed219SJohn Baldwin 	if (error == 0 && old != NULL)
258fe8cdcaeSJohn Baldwin 		bsd_to_linux_sigset(&omask, old);
25906ebbe77SMarcel Moolenaar 
260956d3333SMarcel Moolenaar 	return (error);
26106ebbe77SMarcel Moolenaar }
26206ebbe77SMarcel Moolenaar 
26306ebbe77SMarcel Moolenaar int
264b40ce416SJulian Elischer linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
26506ebbe77SMarcel Moolenaar {
2665002a60fSMarcel Moolenaar 	l_osigset_t mask;
2675002a60fSMarcel Moolenaar 	l_sigset_t set, oset;
26806ebbe77SMarcel Moolenaar 	int error;
26906ebbe77SMarcel Moolenaar 
27006ebbe77SMarcel Moolenaar #ifdef DEBUG
27124593369SJonathan Lemon 	if (ldebug(sigprocmask))
27224593369SJonathan Lemon 		printf(ARGS(sigprocmask, "%d, *, *"), args->how);
27306ebbe77SMarcel Moolenaar #endif
27406ebbe77SMarcel Moolenaar 
27506ebbe77SMarcel Moolenaar 	if (args->mask != NULL) {
2765002a60fSMarcel Moolenaar 		error = copyin(args->mask, &mask, sizeof(l_osigset_t));
27706ebbe77SMarcel Moolenaar 		if (error)
278956d3333SMarcel Moolenaar 			return (error);
279956d3333SMarcel Moolenaar 		LINUX_SIGEMPTYSET(set);
280956d3333SMarcel Moolenaar 		set.__bits[0] = mask;
28106ebbe77SMarcel Moolenaar 	}
28206ebbe77SMarcel Moolenaar 
283b40ce416SJulian Elischer 	error = linux_do_sigprocmask(td, args->how,
284956d3333SMarcel Moolenaar 				     args->mask ? &set : NULL,
285956d3333SMarcel Moolenaar 				     args->omask ? &oset : NULL);
28606ebbe77SMarcel Moolenaar 
287956d3333SMarcel Moolenaar 	if (args->omask != NULL && !error) {
288956d3333SMarcel Moolenaar 		mask = oset.__bits[0];
2895002a60fSMarcel Moolenaar 		error = copyout(&mask, args->omask, sizeof(l_osigset_t));
29006ebbe77SMarcel Moolenaar 	}
29106ebbe77SMarcel Moolenaar 
292956d3333SMarcel Moolenaar 	return (error);
29306ebbe77SMarcel Moolenaar }
29406ebbe77SMarcel Moolenaar 
29506ebbe77SMarcel Moolenaar int
296b40ce416SJulian Elischer linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
29706ebbe77SMarcel Moolenaar {
2985002a60fSMarcel Moolenaar 	l_sigset_t set, oset;
29906ebbe77SMarcel Moolenaar 	int error;
30006ebbe77SMarcel Moolenaar 
30106ebbe77SMarcel Moolenaar #ifdef DEBUG
30224593369SJonathan Lemon 	if (ldebug(rt_sigprocmask))
30324593369SJonathan Lemon 		printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"),
30424593369SJonathan Lemon 		    args->how, (void *)args->mask,
3055231fb20SDavid E. O'Brien 		    (void *)args->omask, (long)args->sigsetsize);
30606ebbe77SMarcel Moolenaar #endif
30706ebbe77SMarcel Moolenaar 
3085002a60fSMarcel Moolenaar 	if (args->sigsetsize != sizeof(l_sigset_t))
30906ebbe77SMarcel Moolenaar 		return EINVAL;
31006ebbe77SMarcel Moolenaar 
31106ebbe77SMarcel Moolenaar 	if (args->mask != NULL) {
3125002a60fSMarcel Moolenaar 		error = copyin(args->mask, &set, sizeof(l_sigset_t));
31306ebbe77SMarcel Moolenaar 		if (error)
314956d3333SMarcel Moolenaar 			return (error);
31506ebbe77SMarcel Moolenaar 	}
31606ebbe77SMarcel Moolenaar 
317b40ce416SJulian Elischer 	error = linux_do_sigprocmask(td, args->how,
318956d3333SMarcel Moolenaar 				     args->mask ? &set : NULL,
319956d3333SMarcel Moolenaar 				     args->omask ? &oset : NULL);
32006ebbe77SMarcel Moolenaar 
321956d3333SMarcel Moolenaar 	if (args->omask != NULL && !error) {
3225002a60fSMarcel Moolenaar 		error = copyout(&oset, args->omask, sizeof(l_sigset_t));
32306ebbe77SMarcel Moolenaar 	}
32406ebbe77SMarcel Moolenaar 
325956d3333SMarcel Moolenaar 	return (error);
326c21dee17SSøren Schmidt }
327c21dee17SSøren Schmidt 
328c21dee17SSøren Schmidt int
329b40ce416SJulian Elischer linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
330c21dee17SSøren Schmidt {
331b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
3325002a60fSMarcel Moolenaar 	l_sigset_t mask;
333956d3333SMarcel Moolenaar 
334c21dee17SSøren Schmidt #ifdef DEBUG
3355002a60fSMarcel Moolenaar 	if (ldebug(sgetmask))
3365002a60fSMarcel Moolenaar 		printf(ARGS(sgetmask, ""));
337c21dee17SSøren Schmidt #endif
338956d3333SMarcel Moolenaar 
339216af822SJohn Baldwin 	PROC_LOCK(p);
3404093529dSJeff Roberson 	bsd_to_linux_sigset(&td->td_sigmask, &mask);
341216af822SJohn Baldwin 	PROC_UNLOCK(p);
342b40ce416SJulian Elischer 	td->td_retval[0] = mask.__bits[0];
343956d3333SMarcel Moolenaar 	return (0);
344c21dee17SSøren Schmidt }
345c21dee17SSøren Schmidt 
346c21dee17SSøren Schmidt int
347b40ce416SJulian Elischer linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
348c21dee17SSøren Schmidt {
349b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
3505002a60fSMarcel Moolenaar 	l_sigset_t lset;
351956d3333SMarcel Moolenaar 	sigset_t bset;
352c21dee17SSøren Schmidt 
353c21dee17SSøren Schmidt #ifdef DEBUG
3545002a60fSMarcel Moolenaar 	if (ldebug(ssetmask))
3555002a60fSMarcel Moolenaar 		printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
356c21dee17SSøren Schmidt #endif
357d66a5066SPeter Wemm 
358216af822SJohn Baldwin 	PROC_LOCK(p);
3594093529dSJeff Roberson 	bsd_to_linux_sigset(&td->td_sigmask, &lset);
360b40ce416SJulian Elischer 	td->td_retval[0] = lset.__bits[0];
361956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(lset);
362956d3333SMarcel Moolenaar 	lset.__bits[0] = args->mask;
363956d3333SMarcel Moolenaar 	linux_to_bsd_sigset(&lset, &bset);
3644093529dSJeff Roberson 	td->td_sigmask = bset;
3654093529dSJeff Roberson 	SIG_CANTMASK(td->td_sigmask);
3664093529dSJeff Roberson 	signotify(td);
367216af822SJohn Baldwin 	PROC_UNLOCK(p);
368956d3333SMarcel Moolenaar 	return (0);
369c21dee17SSøren Schmidt }
370c21dee17SSøren Schmidt 
3715d58e285STim J. Robbins /*
3725d58e285STim J. Robbins  * MPSAFE
3735d58e285STim J. Robbins  */
374c21dee17SSøren Schmidt int
375b40ce416SJulian Elischer linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
376c21dee17SSøren Schmidt {
377b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
378956d3333SMarcel Moolenaar 	sigset_t bset;
3795002a60fSMarcel Moolenaar 	l_sigset_t lset;
3805002a60fSMarcel Moolenaar 	l_osigset_t mask;
381c21dee17SSøren Schmidt 
382c21dee17SSøren Schmidt #ifdef DEBUG
38324593369SJonathan Lemon 	if (ldebug(sigpending))
38424593369SJonathan Lemon 		printf(ARGS(sigpending, "*"));
385c21dee17SSøren Schmidt #endif
386956d3333SMarcel Moolenaar 
387216af822SJohn Baldwin 	PROC_LOCK(p);
3881d9c5696SJuli Mallett 	bset = p->p_siglist;
3894093529dSJeff Roberson 	SIGSETOR(bset, td->td_siglist);
3904093529dSJeff Roberson 	SIGSETAND(bset, td->td_sigmask);
391216af822SJohn Baldwin 	PROC_UNLOCK(p);
3929d8643ecSJohn Baldwin 	bsd_to_linux_sigset(&bset, &lset);
393956d3333SMarcel Moolenaar 	mask = lset.__bits[0];
394956d3333SMarcel Moolenaar 	return (copyout(&mask, args->mask, sizeof(mask)));
395c21dee17SSøren Schmidt }
39617138b61SAlexander Leidinger 
39717138b61SAlexander Leidinger /*
39817138b61SAlexander Leidinger  * MPSAFE
39917138b61SAlexander Leidinger  */
40017138b61SAlexander Leidinger int
40117138b61SAlexander Leidinger linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
40217138b61SAlexander Leidinger {
40317138b61SAlexander Leidinger 	struct proc *p = td->td_proc;
40417138b61SAlexander Leidinger 	sigset_t bset;
40517138b61SAlexander Leidinger 	l_sigset_t lset;
40617138b61SAlexander Leidinger 
40717138b61SAlexander Leidinger 	if (args->sigsetsize > sizeof(lset))
40817138b61SAlexander Leidinger 		return EINVAL;
40917138b61SAlexander Leidinger 		/* NOT REACHED */
41017138b61SAlexander Leidinger 
41117138b61SAlexander Leidinger #ifdef DEBUG
41217138b61SAlexander Leidinger 	if (ldebug(rt_sigpending))
41317138b61SAlexander Leidinger 		printf(ARGS(rt_sigpending, "*"));
41417138b61SAlexander Leidinger #endif
41517138b61SAlexander Leidinger 
41617138b61SAlexander Leidinger 	PROC_LOCK(p);
41717138b61SAlexander Leidinger 	bset = p->p_siglist;
41817138b61SAlexander Leidinger 	SIGSETOR(bset, td->td_siglist);
41917138b61SAlexander Leidinger 	SIGSETAND(bset, td->td_sigmask);
42017138b61SAlexander Leidinger 	PROC_UNLOCK(p);
42117138b61SAlexander Leidinger 	bsd_to_linux_sigset(&bset, &lset);
42217138b61SAlexander Leidinger 	return (copyout(&lset, args->set, args->sigsetsize));
42317138b61SAlexander Leidinger }
424c21dee17SSøren Schmidt 
425c21dee17SSøren Schmidt int
426b40ce416SJulian Elischer linux_kill(struct thread *td, struct linux_kill_args *args)
427c21dee17SSøren Schmidt {
428ef04503dSPeter Wemm 	struct kill_args /* {
429c21dee17SSøren Schmidt 	    int pid;
430c21dee17SSøren Schmidt 	    int signum;
431ef04503dSPeter Wemm 	} */ tmp;
432c21dee17SSøren Schmidt 
433c21dee17SSøren Schmidt #ifdef DEBUG
43424593369SJonathan Lemon 	if (ldebug(kill))
43524593369SJonathan Lemon 		printf(ARGS(kill, "%d, %d"), args->pid, args->signum);
436c21dee17SSøren Schmidt #endif
437956d3333SMarcel Moolenaar 
438956d3333SMarcel Moolenaar 	/*
439956d3333SMarcel Moolenaar 	 * Allow signal 0 as a means to check for privileges
440956d3333SMarcel Moolenaar 	 */
44164742216SAlexander Leidinger 	if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
4422116e6abSJohn Polstra 		return EINVAL;
443956d3333SMarcel Moolenaar 
444956d3333SMarcel Moolenaar 	if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
445956d3333SMarcel Moolenaar 		tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
446956d3333SMarcel Moolenaar 	else
447956d3333SMarcel Moolenaar 		tmp.signum = args->signum;
448956d3333SMarcel Moolenaar 
449c21dee17SSøren Schmidt 	tmp.pid = args->pid;
4501a88a252SMaxim Sobolev 	return (kill(td, &tmp));
451c21dee17SSøren Schmidt }
4529b44bfc5SAlexander Leidinger 
4539b44bfc5SAlexander Leidinger int
4549b44bfc5SAlexander Leidinger linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
4559b44bfc5SAlexander Leidinger {
4569b44bfc5SAlexander Leidinger    	struct linux_emuldata *em;
4579b44bfc5SAlexander Leidinger 	struct linux_kill_args ka;
4589b44bfc5SAlexander Leidinger 	struct proc *p;
4599b44bfc5SAlexander Leidinger 
4609b44bfc5SAlexander Leidinger #ifdef DEBUG
4619b44bfc5SAlexander Leidinger 	if (ldebug(tgkill))
4629b44bfc5SAlexander Leidinger 		printf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig);
4639b44bfc5SAlexander Leidinger #endif
4649b44bfc5SAlexander Leidinger 
4659b44bfc5SAlexander Leidinger 	ka.pid = args->pid;
4669b44bfc5SAlexander Leidinger 	ka.signum = args->sig;
4679b44bfc5SAlexander Leidinger 
4689b44bfc5SAlexander Leidinger 	if (args->tgid == -1)
4699b44bfc5SAlexander Leidinger 	   	return linux_kill(td, &ka);
4709b44bfc5SAlexander Leidinger 
4719b44bfc5SAlexander Leidinger 	if ((p = pfind(args->pid)) == NULL)
4729b44bfc5SAlexander Leidinger 	      	return ESRCH;
4739b44bfc5SAlexander Leidinger 
4749b44bfc5SAlexander Leidinger 	if (p->p_sysent != &elf_linux_sysvec)
4759b44bfc5SAlexander Leidinger 		return ESRCH;
4769b44bfc5SAlexander Leidinger 
4779b44bfc5SAlexander Leidinger 	PROC_UNLOCK(p);
4789b44bfc5SAlexander Leidinger 
4799b44bfc5SAlexander Leidinger 	em = em_find(p, EMUL_UNLOCKED);
4809b44bfc5SAlexander Leidinger 
4819b44bfc5SAlexander Leidinger 	if (em == NULL) {
4829b44bfc5SAlexander Leidinger #ifdef DEBUG
4839b44bfc5SAlexander Leidinger 		printf("emuldata not found in tgkill.\n");
4849b44bfc5SAlexander Leidinger #endif
4859b44bfc5SAlexander Leidinger 		return ESRCH;
4869b44bfc5SAlexander Leidinger 	}
4879b44bfc5SAlexander Leidinger 
4889b44bfc5SAlexander Leidinger 	if (em->shared->group_pid != args->tgid)
4899b44bfc5SAlexander Leidinger 	   	return ESRCH;
4909b44bfc5SAlexander Leidinger 
4919b44bfc5SAlexander Leidinger 	EMUL_UNLOCK(&emul_lock);
4929b44bfc5SAlexander Leidinger 
4939b44bfc5SAlexander Leidinger 	return linux_kill(td, &ka);
4949b44bfc5SAlexander Leidinger }
4959b44bfc5SAlexander Leidinger 
4969b44bfc5SAlexander Leidinger int
4979b44bfc5SAlexander Leidinger linux_tkill(struct thread *td, struct linux_tkill_args *args)
4989b44bfc5SAlexander Leidinger {
4999b44bfc5SAlexander Leidinger #ifdef DEBUG
5009b44bfc5SAlexander Leidinger 	if (ldebug(tkill))
5019b44bfc5SAlexander Leidinger 		printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
5029b44bfc5SAlexander Leidinger #endif
5039b44bfc5SAlexander Leidinger 
5049b44bfc5SAlexander Leidinger 	return (linux_kill(td, (struct linux_kill_args *) args));
5059b44bfc5SAlexander Leidinger }
506