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_signal.h"
47 #include "linux_util.h"
50 linux_to_bsd_sigset(l_sigset_t
*lss
, sigset_t
*bss
)
55 bss
->__bits
[0] = lss
->__bits
[0] & ~((1U << LINUX_SIGTBLSZ
) - 1);
56 bss
->__bits
[1] = lss
->__bits
[1];
57 for (l
= 1; l
<= LINUX_SIGTBLSZ
; l
++) {
58 if (LINUX_SIGISMEMBER(*lss
, l
)) {
59 b
= linux_to_bsd_signal
[_SIG_IDX(l
)];
67 bsd_to_linux_sigset(sigset_t
*bss
, l_sigset_t
*lss
)
71 LINUX_SIGEMPTYSET(*lss
);
72 lss
->__bits
[0] = bss
->__bits
[0] & ~((1U << LINUX_SIGTBLSZ
) - 1);
73 lss
->__bits
[1] = bss
->__bits
[1];
74 for (b
= 1; b
<= LINUX_SIGTBLSZ
; b
++) {
75 if (SIGISMEMBER(*bss
, b
)) {
76 l
= bsd_to_linux_signal
[_SIG_IDX(b
)];
78 LINUX_SIGADDSET(*lss
, l
);
84 linux_to_bsd_sigaction(l_sigaction_t
*lsa
, struct sigaction
*bsa
)
87 linux_to_bsd_sigset(&lsa
->lsa_mask
, &bsa
->sa_mask
);
88 bsa
->sa_handler
= lsa
->lsa_handler
;
90 if (lsa
->lsa_flags
& LINUX_SA_NOCLDSTOP
)
91 bsa
->sa_flags
|= SA_NOCLDSTOP
;
92 if (lsa
->lsa_flags
& LINUX_SA_NOCLDWAIT
)
93 bsa
->sa_flags
|= SA_NOCLDWAIT
;
94 if (lsa
->lsa_flags
& LINUX_SA_SIGINFO
)
95 bsa
->sa_flags
|= SA_SIGINFO
;
96 if (lsa
->lsa_flags
& LINUX_SA_ONSTACK
)
97 bsa
->sa_flags
|= SA_ONSTACK
;
98 if (lsa
->lsa_flags
& LINUX_SA_RESTART
)
99 bsa
->sa_flags
|= SA_RESTART
;
100 if (lsa
->lsa_flags
& LINUX_SA_ONESHOT
)
101 bsa
->sa_flags
|= SA_RESETHAND
;
102 if (lsa
->lsa_flags
& LINUX_SA_NOMASK
)
103 bsa
->sa_flags
|= SA_NODEFER
;
107 bsd_to_linux_sigaction(struct sigaction
*bsa
, l_sigaction_t
*lsa
)
110 bsd_to_linux_sigset(&bsa
->sa_mask
, &lsa
->lsa_mask
);
111 lsa
->lsa_handler
= bsa
->sa_handler
;
112 lsa
->lsa_restorer
= NULL
; /* unsupported */
114 if (bsa
->sa_flags
& SA_NOCLDSTOP
)
115 lsa
->lsa_flags
|= LINUX_SA_NOCLDSTOP
;
116 if (bsa
->sa_flags
& SA_NOCLDWAIT
)
117 lsa
->lsa_flags
|= LINUX_SA_NOCLDWAIT
;
118 if (bsa
->sa_flags
& SA_SIGINFO
)
119 lsa
->lsa_flags
|= LINUX_SA_SIGINFO
;
120 if (bsa
->sa_flags
& SA_ONSTACK
)
121 lsa
->lsa_flags
|= LINUX_SA_ONSTACK
;
122 if (bsa
->sa_flags
& SA_RESTART
)
123 lsa
->lsa_flags
|= LINUX_SA_RESTART
;
124 if (bsa
->sa_flags
& SA_RESETHAND
)
125 lsa
->lsa_flags
|= LINUX_SA_ONESHOT
;
126 if (bsa
->sa_flags
& SA_NODEFER
)
127 lsa
->lsa_flags
|= LINUX_SA_NOMASK
;
134 sys_linux_signal(struct linux_signal_args
*args
)
136 l_sigaction_t linux_nsa
, linux_osa
;
137 struct sigaction nsa
, osa
;
142 kprintf(ARGS(signal
, "%d, %p"),
143 args
->sig
, (void *)args
->handler
);
145 linux_nsa
.lsa_handler
= args
->handler
;
146 linux_nsa
.lsa_flags
= LINUX_SA_ONESHOT
| LINUX_SA_NOMASK
;
147 LINUX_SIGEMPTYSET(linux_nsa
.lsa_mask
);
148 linux_to_bsd_sigaction(&linux_nsa
, &nsa
);
149 if (args
->sig
<= LINUX_SIGTBLSZ
) {
150 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->sig
)];
156 error
= kern_sigaction(sig
, &nsa
, &osa
);
159 bsd_to_linux_sigaction(&osa
, &linux_osa
);
160 args
->sysmsg_result
= (int) linux_osa
.lsa_handler
;
168 sys_linux_rt_sigaction(struct linux_rt_sigaction_args
*args
)
170 l_sigaction_t linux_nsa
, linux_osa
;
171 struct sigaction nsa
, osa
;
175 if (ldebug(rt_sigaction
))
176 kprintf(ARGS(rt_sigaction
, "%ld, %p, %p, %ld"),
177 (long)args
->sig
, (void *)args
->act
,
178 (void *)args
->oact
, (long)args
->sigsetsize
);
180 if (args
->sigsetsize
!= sizeof(l_sigset_t
))
184 error
= copyin(args
->act
, &linux_nsa
, sizeof(linux_nsa
));
187 linux_to_bsd_sigaction(&linux_nsa
, &nsa
);
189 if (args
->sig
<= LINUX_SIGTBLSZ
) {
190 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->sig
)];
196 error
= kern_sigaction(sig
, args
->act
? &nsa
: NULL
,
197 args
->oact
? &osa
: NULL
);
200 if (error
== 0 && args
->oact
) {
201 bsd_to_linux_sigaction(&osa
, &linux_osa
);
202 error
= copyout(&linux_osa
, args
->oact
, sizeof(linux_osa
));
209 linux_to_bsd_sigprocmask(int how
)
212 case LINUX_SIG_BLOCK
:
214 case LINUX_SIG_UNBLOCK
:
216 case LINUX_SIG_SETMASK
:
227 sys_linux_sigprocmask(struct linux_sigprocmask_args
*args
)
230 l_sigset_t linux_set
, linux_oset
;
235 if (ldebug(sigprocmask
))
236 kprintf(ARGS(sigprocmask
, "%d, *, *"), args
->how
);
240 error
= copyin(args
->mask
, &mask
, sizeof(l_osigset_t
));
243 LINUX_SIGEMPTYSET(linux_set
);
244 linux_set
.__bits
[0] = mask
;
245 linux_to_bsd_sigset(&linux_set
, &set
);
247 how
= linux_to_bsd_sigprocmask(args
->how
);
250 error
= kern_sigprocmask(how
, args
->mask
? &set
: NULL
,
251 args
->omask
? &oset
: NULL
);
254 if (error
== 0 && args
->omask
) {
255 bsd_to_linux_sigset(&oset
, &linux_oset
);
256 mask
= linux_oset
.__bits
[0];
257 error
= copyout(&mask
, args
->omask
, sizeof(l_osigset_t
));
266 sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args
*args
)
268 l_sigset_t linux_set
, linux_oset
;
273 if (ldebug(rt_sigprocmask
))
274 kprintf(ARGS(rt_sigprocmask
, "%d, %p, %p, %ld"),
275 args
->how
, (void *)args
->mask
,
276 (void *)args
->omask
, (long)args
->sigsetsize
);
279 if (args
->sigsetsize
!= sizeof(l_sigset_t
))
283 error
= copyin(args
->mask
, &linux_set
, sizeof(l_sigset_t
));
286 linux_to_bsd_sigset(&linux_set
, &set
);
288 how
= linux_to_bsd_sigprocmask(args
->how
);
291 error
= kern_sigprocmask(how
, args
->mask
? &set
: NULL
,
292 args
->omask
? &oset
: NULL
);
295 if (error
== 0 && args
->omask
) {
296 bsd_to_linux_sigset(&oset
, &linux_oset
);
297 error
= copyout(&linux_oset
, args
->omask
, sizeof(l_sigset_t
));
307 sys_linux_sgetmask(struct linux_sgetmask_args
*args
)
309 struct lwp
*lp
= curthread
->td_lwp
;
313 if (ldebug(sgetmask
))
314 kprintf(ARGS(sgetmask
, ""));
317 bsd_to_linux_sigset(&lp
->lwp_sigmask
, &mask
);
318 args
->sysmsg_result
= mask
.__bits
[0];
326 sys_linux_ssetmask(struct linux_ssetmask_args
*args
)
328 struct lwp
*lp
= curthread
->td_lwp
;
333 if (ldebug(ssetmask
))
334 kprintf(ARGS(ssetmask
, "%08lx"), (unsigned long)args
->mask
);
337 bsd_to_linux_sigset(&lp
->lwp_sigmask
, &lset
);
338 args
->sysmsg_result
= lset
.__bits
[0];
339 LINUX_SIGEMPTYSET(lset
);
340 lset
.__bits
[0] = args
->mask
;
341 linux_to_bsd_sigset(&lset
, &bset
);
343 lp
->lwp_sigmask
= bset
;
344 SIG_CANTMASK(lp
->lwp_sigmask
);
353 sys_linux_sigpending(struct linux_sigpending_args
*args
)
355 struct thread
*td
= curthread
;
356 struct lwp
*lp
= td
->td_lwp
;
358 l_sigset_t linux_set
;
363 if (ldebug(sigpending
))
364 kprintf(ARGS(sigpending
, "*"));
367 error
= kern_sigpending(&set
);
370 SIGSETAND(set
, lp
->lwp_sigmask
);
371 bsd_to_linux_sigset(&set
, &linux_set
);
372 mask
= linux_set
.__bits
[0];
373 error
= copyout(&mask
, args
->mask
, sizeof(mask
));
382 sys_linux_kill(struct linux_kill_args
*args
)
388 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);