2 * Copyright (c) 1994-1995 Søren Schmidt
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software withough specific prior written permission
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/compat/linux/linux_signal.c,v 1.23.2.3 2001/11/05 19:08:23 marcel Exp $
29 * $DragonFly: src/sys/emulation/linux/linux_signal.c,v 1.14 2007/03/12 21:07:42 corecode Exp $
32 #include <sys/param.h>
33 #include <sys/systm.h>
36 #include <sys/signalvar.h>
37 #include <sys/sysproto.h>
38 #include <sys/kern_syscall.h>
39 #include <sys/thread.h>
41 #include <sys/thread2.h>
42 #include <sys/mplock2.h>
44 #include <arch_linux/linux.h>
45 #include <arch_linux/linux_proto.h>
46 #include "linux_emuldata.h"
47 #include "linux_signal.h"
48 #include "linux_util.h"
51 linux_to_bsd_sigset(l_sigset_t
*lss
, sigset_t
*bss
)
56 bss
->__bits
[0] = lss
->__bits
[0] & ~((1U << LINUX_SIGTBLSZ
) - 1);
57 bss
->__bits
[1] = lss
->__bits
[1];
58 for (l
= 1; l
<= LINUX_SIGTBLSZ
; l
++) {
59 if (LINUX_SIGISMEMBER(*lss
, l
)) {
60 b
= linux_to_bsd_signal
[_SIG_IDX(l
)];
68 bsd_to_linux_sigset(sigset_t
*bss
, l_sigset_t
*lss
)
72 LINUX_SIGEMPTYSET(*lss
);
73 lss
->__bits
[0] = bss
->__bits
[0] & ~((1U << LINUX_SIGTBLSZ
) - 1);
74 lss
->__bits
[1] = bss
->__bits
[1];
75 for (b
= 1; b
<= LINUX_SIGTBLSZ
; b
++) {
76 if (SIGISMEMBER(*bss
, b
)) {
77 l
= bsd_to_linux_signal
[_SIG_IDX(b
)];
79 LINUX_SIGADDSET(*lss
, l
);
85 linux_to_bsd_sigaction(l_sigaction_t
*lsa
, struct sigaction
*bsa
)
88 linux_to_bsd_sigset(&lsa
->lsa_mask
, &bsa
->sa_mask
);
89 bsa
->sa_handler
= lsa
->lsa_handler
;
91 if (lsa
->lsa_flags
& LINUX_SA_NOCLDSTOP
)
92 bsa
->sa_flags
|= SA_NOCLDSTOP
;
93 if (lsa
->lsa_flags
& LINUX_SA_NOCLDWAIT
)
94 bsa
->sa_flags
|= SA_NOCLDWAIT
;
95 if (lsa
->lsa_flags
& LINUX_SA_SIGINFO
)
96 bsa
->sa_flags
|= SA_SIGINFO
;
97 if (lsa
->lsa_flags
& LINUX_SA_ONSTACK
)
98 bsa
->sa_flags
|= SA_ONSTACK
;
99 if (lsa
->lsa_flags
& LINUX_SA_RESTART
)
100 bsa
->sa_flags
|= SA_RESTART
;
101 if (lsa
->lsa_flags
& LINUX_SA_ONESHOT
)
102 bsa
->sa_flags
|= SA_RESETHAND
;
103 if (lsa
->lsa_flags
& LINUX_SA_NOMASK
)
104 bsa
->sa_flags
|= SA_NODEFER
;
108 bsd_to_linux_sigaction(struct sigaction
*bsa
, l_sigaction_t
*lsa
)
111 bsd_to_linux_sigset(&bsa
->sa_mask
, &lsa
->lsa_mask
);
112 lsa
->lsa_handler
= bsa
->sa_handler
;
113 lsa
->lsa_restorer
= NULL
; /* unsupported */
115 if (bsa
->sa_flags
& SA_NOCLDSTOP
)
116 lsa
->lsa_flags
|= LINUX_SA_NOCLDSTOP
;
117 if (bsa
->sa_flags
& SA_NOCLDWAIT
)
118 lsa
->lsa_flags
|= LINUX_SA_NOCLDWAIT
;
119 if (bsa
->sa_flags
& SA_SIGINFO
)
120 lsa
->lsa_flags
|= LINUX_SA_SIGINFO
;
121 if (bsa
->sa_flags
& SA_ONSTACK
)
122 lsa
->lsa_flags
|= LINUX_SA_ONSTACK
;
123 if (bsa
->sa_flags
& SA_RESTART
)
124 lsa
->lsa_flags
|= LINUX_SA_RESTART
;
125 if (bsa
->sa_flags
& SA_RESETHAND
)
126 lsa
->lsa_flags
|= LINUX_SA_ONESHOT
;
127 if (bsa
->sa_flags
& SA_NODEFER
)
128 lsa
->lsa_flags
|= LINUX_SA_NOMASK
;
135 sys_linux_signal(struct linux_signal_args
*args
)
137 l_sigaction_t linux_nsa
, linux_osa
;
138 struct sigaction nsa
, osa
;
143 kprintf(ARGS(signal
, "%d, %p"),
144 args
->sig
, (void *)args
->handler
);
146 linux_nsa
.lsa_handler
= args
->handler
;
147 linux_nsa
.lsa_flags
= LINUX_SA_ONESHOT
| LINUX_SA_NOMASK
;
148 LINUX_SIGEMPTYSET(linux_nsa
.lsa_mask
);
149 linux_to_bsd_sigaction(&linux_nsa
, &nsa
);
150 if (args
->sig
<= LINUX_SIGTBLSZ
) {
151 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->sig
)];
157 error
= kern_sigaction(sig
, &nsa
, &osa
);
160 bsd_to_linux_sigaction(&osa
, &linux_osa
);
161 args
->sysmsg_result
= (int) linux_osa
.lsa_handler
;
169 sys_linux_rt_sigaction(struct linux_rt_sigaction_args
*args
)
171 l_sigaction_t linux_nsa
, linux_osa
;
172 struct sigaction nsa
, osa
;
176 if (ldebug(rt_sigaction
))
177 kprintf(ARGS(rt_sigaction
, "%ld, %p, %p, %ld"),
178 (long)args
->sig
, (void *)args
->act
,
179 (void *)args
->oact
, (long)args
->sigsetsize
);
181 if (args
->sigsetsize
!= sizeof(l_sigset_t
))
185 error
= copyin(args
->act
, &linux_nsa
, sizeof(linux_nsa
));
188 linux_to_bsd_sigaction(&linux_nsa
, &nsa
);
190 if (args
->sig
<= LINUX_SIGTBLSZ
) {
191 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->sig
)];
197 error
= kern_sigaction(sig
, args
->act
? &nsa
: NULL
,
198 args
->oact
? &osa
: NULL
);
201 if (error
== 0 && args
->oact
) {
202 bsd_to_linux_sigaction(&osa
, &linux_osa
);
203 error
= copyout(&linux_osa
, args
->oact
, sizeof(linux_osa
));
210 linux_to_bsd_sigprocmask(int how
)
213 case LINUX_SIG_BLOCK
:
215 case LINUX_SIG_UNBLOCK
:
217 case LINUX_SIG_SETMASK
:
228 sys_linux_sigprocmask(struct linux_sigprocmask_args
*args
)
231 l_sigset_t linux_set
, linux_oset
;
236 if (ldebug(sigprocmask
))
237 kprintf(ARGS(sigprocmask
, "%d, *, *"), args
->how
);
241 error
= copyin(args
->mask
, &mask
, sizeof(l_osigset_t
));
244 LINUX_SIGEMPTYSET(linux_set
);
245 linux_set
.__bits
[0] = mask
;
246 linux_to_bsd_sigset(&linux_set
, &set
);
248 how
= linux_to_bsd_sigprocmask(args
->how
);
251 error
= kern_sigprocmask(how
, args
->mask
? &set
: NULL
,
252 args
->omask
? &oset
: NULL
);
255 if (error
== 0 && args
->omask
) {
256 bsd_to_linux_sigset(&oset
, &linux_oset
);
257 mask
= linux_oset
.__bits
[0];
258 error
= copyout(&mask
, args
->omask
, sizeof(l_osigset_t
));
267 sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args
*args
)
269 l_sigset_t linux_set
, linux_oset
;
274 if (ldebug(rt_sigprocmask
))
275 kprintf(ARGS(rt_sigprocmask
, "%d, %p, %p, %ld"),
276 args
->how
, (void *)args
->mask
,
277 (void *)args
->omask
, (long)args
->sigsetsize
);
280 if (args
->sigsetsize
!= sizeof(l_sigset_t
))
284 error
= copyin(args
->mask
, &linux_set
, sizeof(l_sigset_t
));
287 linux_to_bsd_sigset(&linux_set
, &set
);
289 how
= linux_to_bsd_sigprocmask(args
->how
);
292 error
= kern_sigprocmask(how
, args
->mask
? &set
: NULL
,
293 args
->omask
? &oset
: NULL
);
296 if (error
== 0 && args
->omask
) {
297 bsd_to_linux_sigset(&oset
, &linux_oset
);
298 error
= copyout(&linux_oset
, args
->omask
, sizeof(l_sigset_t
));
308 sys_linux_sgetmask(struct linux_sgetmask_args
*args
)
310 struct lwp
*lp
= curthread
->td_lwp
;
314 if (ldebug(sgetmask
))
315 kprintf(ARGS(sgetmask
, ""));
318 bsd_to_linux_sigset(&lp
->lwp_sigmask
, &mask
);
319 args
->sysmsg_result
= mask
.__bits
[0];
327 sys_linux_ssetmask(struct linux_ssetmask_args
*args
)
329 struct lwp
*lp
= curthread
->td_lwp
;
334 if (ldebug(ssetmask
))
335 kprintf(ARGS(ssetmask
, "%08lx"), (unsigned long)args
->mask
);
338 bsd_to_linux_sigset(&lp
->lwp_sigmask
, &lset
);
339 args
->sysmsg_result
= lset
.__bits
[0];
340 LINUX_SIGEMPTYSET(lset
);
341 lset
.__bits
[0] = args
->mask
;
342 linux_to_bsd_sigset(&lset
, &bset
);
344 lp
->lwp_sigmask
= bset
;
345 SIG_CANTMASK(lp
->lwp_sigmask
);
354 sys_linux_sigpending(struct linux_sigpending_args
*args
)
356 struct thread
*td
= curthread
;
357 struct lwp
*lp
= td
->td_lwp
;
359 l_sigset_t linux_set
;
364 if (ldebug(sigpending
))
365 kprintf(ARGS(sigpending
, "*"));
368 error
= kern_sigpending(&set
);
371 SIGSETAND(set
, lp
->lwp_sigmask
);
372 bsd_to_linux_sigset(&set
, &linux_set
);
373 mask
= linux_set
.__bits
[0];
374 error
= copyout(&mask
, args
->mask
, sizeof(mask
));
383 sys_linux_kill(struct linux_kill_args
*args
)
389 kprintf(ARGS(kill
, "%d, %d"), args
->pid
, args
->signum
);
392 * Allow signal 0 as a means to check for privileges
394 if (args
->signum
< 0 || args
->signum
> LINUX_NSIG
)
397 if (args
->signum
> 0 && args
->signum
<= LINUX_SIGTBLSZ
)
398 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->signum
)];
403 error
= kern_kill(sig
, args
->pid
, -1);
411 linux_do_tkill(l_int tgid
, l_int pid
, l_int sig
)
413 struct linux_emuldata
*em
;
418 * Allow signal 0 as a means to check for privileges
420 if (sig
< 0 || sig
> LINUX_NSIG
)
423 if (sig
> 0 && sig
<= LINUX_SIGTBLSZ
)
424 sig
= linux_to_bsd_signal
[_SIG_IDX(sig
)];
427 if ((p
= pfind(pid
)) == NULL
) {
428 if ((p
= zpfind(pid
)) == NULL
) {
435 em
= emuldata_get(p
);
443 if (tgid
> 0 && em
->s
->group_pid
!= tgid
) {
450 error
= kern_kill(sig
, pid
, -1);
457 sys_linux_tgkill(struct linux_tgkill_args
*args
)
462 kprintf(ARGS(tgkill
, "%d, %d, %d"), args
->tgid
, args
->pid
, args
->sig
);
464 if (args
->pid
<= 0 || args
->tgid
<= 0)
467 return (linux_do_tkill(args
->tgid
, args
->pid
, args
->sig
));
471 sys_linux_tkill(struct linux_tkill_args
*args
)
475 kprintf(ARGS(tkill
, "%i, %i"), args
->tid
, args
->sig
);
480 return (linux_do_tkill(0, args
->tid
, args
->sig
));