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>
40 #include <arch_linux/linux.h>
41 #include <arch_linux/linux_proto.h>
42 #include "linux_signal.h"
43 #include "linux_util.h"
46 linux_to_bsd_sigset(l_sigset_t
*lss
, sigset_t
*bss
)
51 bss
->__bits
[0] = lss
->__bits
[0] & ~((1U << LINUX_SIGTBLSZ
) - 1);
52 bss
->__bits
[1] = lss
->__bits
[1];
53 for (l
= 1; l
<= LINUX_SIGTBLSZ
; l
++) {
54 if (LINUX_SIGISMEMBER(*lss
, l
)) {
55 b
= linux_to_bsd_signal
[_SIG_IDX(l
)];
63 bsd_to_linux_sigset(sigset_t
*bss
, l_sigset_t
*lss
)
67 LINUX_SIGEMPTYSET(*lss
);
68 lss
->__bits
[0] = bss
->__bits
[0] & ~((1U << LINUX_SIGTBLSZ
) - 1);
69 lss
->__bits
[1] = bss
->__bits
[1];
70 for (b
= 1; b
<= LINUX_SIGTBLSZ
; b
++) {
71 if (SIGISMEMBER(*bss
, b
)) {
72 l
= bsd_to_linux_signal
[_SIG_IDX(b
)];
74 LINUX_SIGADDSET(*lss
, l
);
80 linux_to_bsd_sigaction(l_sigaction_t
*lsa
, struct sigaction
*bsa
)
83 linux_to_bsd_sigset(&lsa
->lsa_mask
, &bsa
->sa_mask
);
84 bsa
->sa_handler
= lsa
->lsa_handler
;
86 if (lsa
->lsa_flags
& LINUX_SA_NOCLDSTOP
)
87 bsa
->sa_flags
|= SA_NOCLDSTOP
;
88 if (lsa
->lsa_flags
& LINUX_SA_NOCLDWAIT
)
89 bsa
->sa_flags
|= SA_NOCLDWAIT
;
90 if (lsa
->lsa_flags
& LINUX_SA_SIGINFO
)
91 bsa
->sa_flags
|= SA_SIGINFO
;
92 if (lsa
->lsa_flags
& LINUX_SA_ONSTACK
)
93 bsa
->sa_flags
|= SA_ONSTACK
;
94 if (lsa
->lsa_flags
& LINUX_SA_RESTART
)
95 bsa
->sa_flags
|= SA_RESTART
;
96 if (lsa
->lsa_flags
& LINUX_SA_ONESHOT
)
97 bsa
->sa_flags
|= SA_RESETHAND
;
98 if (lsa
->lsa_flags
& LINUX_SA_NOMASK
)
99 bsa
->sa_flags
|= SA_NODEFER
;
103 bsd_to_linux_sigaction(struct sigaction
*bsa
, l_sigaction_t
*lsa
)
106 bsd_to_linux_sigset(&bsa
->sa_mask
, &lsa
->lsa_mask
);
107 lsa
->lsa_handler
= bsa
->sa_handler
;
108 lsa
->lsa_restorer
= NULL
; /* unsupported */
110 if (bsa
->sa_flags
& SA_NOCLDSTOP
)
111 lsa
->lsa_flags
|= LINUX_SA_NOCLDSTOP
;
112 if (bsa
->sa_flags
& SA_NOCLDWAIT
)
113 lsa
->lsa_flags
|= LINUX_SA_NOCLDWAIT
;
114 if (bsa
->sa_flags
& SA_SIGINFO
)
115 lsa
->lsa_flags
|= LINUX_SA_SIGINFO
;
116 if (bsa
->sa_flags
& SA_ONSTACK
)
117 lsa
->lsa_flags
|= LINUX_SA_ONSTACK
;
118 if (bsa
->sa_flags
& SA_RESTART
)
119 lsa
->lsa_flags
|= LINUX_SA_RESTART
;
120 if (bsa
->sa_flags
& SA_RESETHAND
)
121 lsa
->lsa_flags
|= LINUX_SA_ONESHOT
;
122 if (bsa
->sa_flags
& SA_NODEFER
)
123 lsa
->lsa_flags
|= LINUX_SA_NOMASK
;
127 sys_linux_signal(struct linux_signal_args
*args
)
129 l_sigaction_t linux_nsa
, linux_osa
;
130 struct sigaction nsa
, osa
;
135 kprintf(ARGS(signal
, "%d, %p"),
136 args
->sig
, (void *)args
->handler
);
138 linux_nsa
.lsa_handler
= args
->handler
;
139 linux_nsa
.lsa_flags
= LINUX_SA_ONESHOT
| LINUX_SA_NOMASK
;
140 LINUX_SIGEMPTYSET(linux_nsa
.lsa_mask
);
141 linux_to_bsd_sigaction(&linux_nsa
, &nsa
);
142 if (args
->sig
<= LINUX_SIGTBLSZ
) {
143 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->sig
)];
148 error
= kern_sigaction(sig
, &nsa
, &osa
);
150 bsd_to_linux_sigaction(&osa
, &linux_osa
);
151 args
->sysmsg_result
= (int) linux_osa
.lsa_handler
;
156 sys_linux_rt_sigaction(struct linux_rt_sigaction_args
*args
)
158 l_sigaction_t linux_nsa
, linux_osa
;
159 struct sigaction nsa
, osa
;
163 if (ldebug(rt_sigaction
))
164 kprintf(ARGS(rt_sigaction
, "%ld, %p, %p, %ld"),
165 (long)args
->sig
, (void *)args
->act
,
166 (void *)args
->oact
, (long)args
->sigsetsize
);
168 if (args
->sigsetsize
!= sizeof(l_sigset_t
))
172 error
= copyin(args
->act
, &linux_nsa
, sizeof(linux_nsa
));
175 linux_to_bsd_sigaction(&linux_nsa
, &nsa
);
177 if (args
->sig
<= LINUX_SIGTBLSZ
) {
178 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->sig
)];
183 error
= kern_sigaction(sig
, args
->act
? &nsa
: NULL
,
184 args
->oact
? &osa
: NULL
);
186 if (error
== 0 && args
->oact
) {
187 bsd_to_linux_sigaction(&osa
, &linux_osa
);
188 error
= copyout(&linux_osa
, args
->oact
, sizeof(linux_osa
));
195 linux_to_bsd_sigprocmask(int how
)
198 case LINUX_SIG_BLOCK
:
200 case LINUX_SIG_UNBLOCK
:
202 case LINUX_SIG_SETMASK
:
210 sys_linux_sigprocmask(struct linux_sigprocmask_args
*args
)
213 l_sigset_t linux_set
, linux_oset
;
218 if (ldebug(sigprocmask
))
219 kprintf(ARGS(sigprocmask
, "%d, *, *"), args
->how
);
223 error
= copyin(args
->mask
, &mask
, sizeof(l_osigset_t
));
226 LINUX_SIGEMPTYSET(linux_set
);
227 linux_set
.__bits
[0] = mask
;
228 linux_to_bsd_sigset(&linux_set
, &set
);
230 how
= linux_to_bsd_sigprocmask(args
->how
);
232 error
= kern_sigprocmask(how
, args
->mask
? &set
: NULL
,
233 args
->omask
? &oset
: NULL
);
235 if (error
== 0 && args
->omask
) {
236 bsd_to_linux_sigset(&oset
, &linux_oset
);
237 mask
= linux_oset
.__bits
[0];
238 error
= copyout(&mask
, args
->omask
, sizeof(l_osigset_t
));
244 sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args
*args
)
246 l_sigset_t linux_set
, linux_oset
;
251 if (ldebug(rt_sigprocmask
))
252 kprintf(ARGS(rt_sigprocmask
, "%d, %p, %p, %ld"),
253 args
->how
, (void *)args
->mask
,
254 (void *)args
->omask
, (long)args
->sigsetsize
);
257 if (args
->sigsetsize
!= sizeof(l_sigset_t
))
261 error
= copyin(args
->mask
, &linux_set
, sizeof(l_sigset_t
));
264 linux_to_bsd_sigset(&linux_set
, &set
);
266 how
= linux_to_bsd_sigprocmask(args
->how
);
268 error
= kern_sigprocmask(how
, args
->mask
? &set
: NULL
,
269 args
->omask
? &oset
: NULL
);
271 if (error
== 0 && args
->omask
) {
272 bsd_to_linux_sigset(&oset
, &linux_oset
);
273 error
= copyout(&linux_oset
, args
->omask
, sizeof(l_sigset_t
));
280 sys_linux_sgetmask(struct linux_sgetmask_args
*args
)
282 struct lwp
*lp
= curthread
->td_lwp
;
286 if (ldebug(sgetmask
))
287 kprintf(ARGS(sgetmask
, ""));
290 bsd_to_linux_sigset(&lp
->lwp_sigmask
, &mask
);
291 args
->sysmsg_result
= mask
.__bits
[0];
296 sys_linux_ssetmask(struct linux_ssetmask_args
*args
)
298 struct lwp
*lp
= curthread
->td_lwp
;
303 if (ldebug(ssetmask
))
304 kprintf(ARGS(ssetmask
, "%08lx"), (unsigned long)args
->mask
);
307 bsd_to_linux_sigset(&lp
->lwp_sigmask
, &lset
);
308 args
->sysmsg_result
= lset
.__bits
[0];
309 LINUX_SIGEMPTYSET(lset
);
310 lset
.__bits
[0] = args
->mask
;
311 linux_to_bsd_sigset(&lset
, &bset
);
312 lp
->lwp_sigmask
= bset
;
313 SIG_CANTMASK(lp
->lwp_sigmask
);
318 sys_linux_sigpending(struct linux_sigpending_args
*args
)
320 struct thread
*td
= curthread
;
321 struct lwp
*lp
= td
->td_lwp
;
323 l_sigset_t linux_set
;
328 if (ldebug(sigpending
))
329 kprintf(ARGS(sigpending
, "*"));
332 error
= kern_sigpending(&set
);
335 SIGSETAND(set
, lp
->lwp_sigmask
);
336 bsd_to_linux_sigset(&set
, &linux_set
);
337 mask
= linux_set
.__bits
[0];
338 error
= copyout(&mask
, args
->mask
, sizeof(mask
));
344 sys_linux_kill(struct linux_kill_args
*args
)
350 kprintf(ARGS(kill
, "%d, %d"), args
->pid
, args
->signum
);
354 * Allow signal 0 as a means to check for privileges
356 if (args
->signum
< 0 || args
->signum
> LINUX_NSIG
)
359 if (args
->signum
> 0 && args
->signum
<= LINUX_SIGTBLSZ
)
360 sig
= linux_to_bsd_signal
[_SIG_IDX(args
->signum
)];
364 error
= kern_kill(sig
, args
->pid
, -1);