1 /* $NetBSD: ibcs2_signal.c,v 1.28 2007/12/08 18:36:01 dsl Exp $ */
4 * Copyright (c) 1995 Scott Bartram
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: ibcs2_signal.c,v 1.28 2007/12/08 18:36:01 dsl Exp $");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/namei.h>
37 #include <sys/filedesc.h>
38 #include <sys/ioctl.h>
39 #include <sys/mount.h>
40 #include <sys/kernel.h>
41 #include <sys/signal.h>
42 #include <sys/signalvar.h>
44 #include <sys/syscallargs.h>
46 #include <compat/ibcs2/ibcs2_types.h>
47 #include <compat/ibcs2/ibcs2_signal.h>
48 #include <compat/ibcs2/ibcs2_syscallargs.h>
49 #include <compat/ibcs2/ibcs2_util.h>
50 #include <compat/common/compat_sigaltstack.h>
52 #define ibcs2_sigmask(n) (1 << ((n) - 1))
53 #define ibcs2_sigemptyset(s) memset((s), 0, sizeof(*(s)))
54 #define ibcs2_sigismember(s, n) (*(s) & ibcs2_sigmask(n))
55 #define ibcs2_sigaddset(s, n) (*(s) |= ibcs2_sigmask(n))
57 extern const int native_to_ibcs2_signo
[];
58 extern const int ibcs2_to_native_signo
[];
60 void ibcs2_to_native_sigaction(const struct ibcs2_sigaction
*, struct sigaction
*);
61 void native_to_ibcs2_sigaction(const struct sigaction
*, struct ibcs2_sigaction
*);
64 ibcs2_to_native_sigset(const ibcs2_sigset_t
*iss
, sigset_t
*bss
)
69 for (i
= 1; i
< IBCS2_NSIG
; i
++) {
70 if (ibcs2_sigismember(iss
, i
)) {
71 newsig
= ibcs2_to_native_signo
[i
];
73 sigaddset(bss
, newsig
);
79 native_to_ibcs2_sigset(const sigset_t
*bss
, ibcs2_sigset_t
*iss
)
83 ibcs2_sigemptyset(iss
);
84 for (i
= 1; i
< NSIG
; i
++) {
85 if (sigismember(bss
, i
)) {
86 newsig
= native_to_ibcs2_signo
[i
];
88 ibcs2_sigaddset(iss
, newsig
);
94 ibcs2_to_native_sigaction(const struct ibcs2_sigaction
*isa
, struct sigaction
*bsa
)
97 bsa
->sa_handler
= isa
->ibcs2_sa_handler
;
98 ibcs2_to_native_sigset(&isa
->ibcs2_sa_mask
, &bsa
->sa_mask
);
100 if ((isa
->ibcs2_sa_flags
& IBCS2_SA_NOCLDSTOP
) != 0)
101 bsa
->sa_flags
|= SA_NOCLDSTOP
;
102 if ((isa
->ibcs2_sa_flags
& IBCS2_SA_RESETHAND
) != 0)
103 bsa
->sa_flags
|= SA_RESETHAND
;
104 if ((isa
->ibcs2_sa_flags
& IBCS2_SA_RESTART
) != 0)
105 bsa
->sa_flags
|= SA_RESTART
;
106 if ((isa
->ibcs2_sa_flags
& IBCS2_SA_SIGINFO
) != 0)
107 /*XXX*/ printf("ibcs2_to_native_sigaction: SA_SIGINFO ignored\n");
108 if ((isa
->ibcs2_sa_flags
& IBCS2_SA_NODEFER
) != 0)
109 bsa
->sa_flags
|= SA_NODEFER
;
110 if ((isa
->ibcs2_sa_flags
& IBCS2_SA_ONSTACK
) != 0)
111 bsa
->sa_flags
|= SA_ONSTACK
;
112 if ((isa
->ibcs2_sa_flags
& IBCS2_SA_NOCLDWAIT
) != 0)
113 /*XXX*/ printf("ibcs2_to_native_sigaction: SA_NOCLDWAIT ignored\n");
114 if ((isa
->ibcs2_sa_flags
& ~IBCS2_SA_ALLBITS
) != 0)
115 /*XXX*/ printf("ibcs2_to_native_sigaction: extra bits ignored\n");
119 native_to_ibcs2_sigaction(const struct sigaction
*bsa
, struct ibcs2_sigaction
*isa
)
122 isa
->ibcs2_sa_handler
= bsa
->sa_handler
;
123 native_to_ibcs2_sigset(&bsa
->sa_mask
, &isa
->ibcs2_sa_mask
);
124 isa
->ibcs2_sa_flags
= 0;
125 if ((bsa
->sa_flags
& SA_NOCLDSTOP
) != 0)
126 isa
->ibcs2_sa_flags
|= IBCS2_SA_NOCLDSTOP
;
127 if ((bsa
->sa_flags
& SA_RESETHAND
) != 0)
128 isa
->ibcs2_sa_flags
|= IBCS2_SA_RESETHAND
;
129 if ((bsa
->sa_flags
& SA_RESTART
) != 0)
130 isa
->ibcs2_sa_flags
|= IBCS2_SA_RESTART
;
131 if ((bsa
->sa_flags
& SA_NODEFER
) != 0)
132 isa
->ibcs2_sa_flags
|= IBCS2_SA_NODEFER
;
133 if ((bsa
->sa_flags
& SA_ONSTACK
) != 0)
134 isa
->ibcs2_sa_flags
|= IBCS2_SA_ONSTACK
;
139 ibcs2_sys_sigaction(struct lwp
*l
, const struct ibcs2_sys_sigaction_args
*uap
, register_t
*retval
)
142 syscallarg(int) signum;
143 syscallarg(const struct ibcs2_sigaction *) nsa;
144 syscallarg(struct ibcs2_sigaction *) osa;
146 struct ibcs2_sigaction nisa
, oisa
;
147 struct sigaction nbsa
, obsa
;
148 int error
, signum
= SCARG(uap
, signum
);
150 if (signum
< 0 || signum
>= IBCS2_NSIG
)
152 signum
= ibcs2_to_native_signo
[signum
];
154 if (SCARG(uap
, nsa
)) {
155 error
= copyin(SCARG(uap
, nsa
), &nisa
, sizeof(nisa
));
158 ibcs2_to_native_sigaction(&nisa
, &nbsa
);
160 error
= sigaction1(l
, signum
,
161 SCARG(uap
, nsa
) ? &nbsa
: 0, SCARG(uap
, osa
) ? &obsa
: 0,
165 if (SCARG(uap
, osa
)) {
166 native_to_ibcs2_sigaction(&obsa
, &oisa
);
167 error
= copyout(&oisa
, SCARG(uap
, osa
), sizeof(oisa
));
175 ibcs2_sys_sigaltstack(struct lwp
*l
, const struct ibcs2_sys_sigaltstack_args
*uap
, register_t
*retval
)
178 syscallarg(const struct ibcs2_sigaltstack *) nss;
179 syscallarg(struct ibcs2_sigaltstack *) oss;
181 compat_sigaltstack(uap
, ibcs2_sigaltstack
,
182 IBCS2_SS_ONSTACK
, IBCS2_SS_DISABLE
);
186 ibcs2_sys_sigsys(struct lwp
*l
, const struct ibcs2_sys_sigsys_args
*uap
, register_t
*retval
)
190 syscallarg(ibcs2_sig_t) fp;
192 struct sigaction nbsa
, obsa
;
194 int error
, signum
= IBCS2_SIGNO(SCARG(uap
, sig
));
196 if (signum
< 0 || signum
>= IBCS2_NSIG
)
198 signum
= ibcs2_to_native_signo
[signum
];
200 switch (IBCS2_SIGCALL(SCARG(uap
, sig
))) {
201 case IBCS2_SIGSET_MASK
:
202 if (SCARG(uap
, fp
) == IBCS2_SIG_HOLD
)
206 case IBCS2_SIGNAL_MASK
:
207 nbsa
.sa_handler
= (sig_t
)SCARG(uap
, fp
);
208 sigemptyset(&nbsa
.sa_mask
);
210 error
= sigaction1(l
, signum
, &nbsa
, &obsa
, NULL
, 0);
213 *retval
= (int)obsa
.sa_handler
;
216 case IBCS2_SIGHOLD_MASK
:
219 sigaddset(&ss
, signum
);
220 return (sigprocmask1(l
, SIG_BLOCK
, &ss
, 0));
222 case IBCS2_SIGRELSE_MASK
:
224 sigaddset(&ss
, signum
);
225 return (sigprocmask1(l
, SIG_UNBLOCK
, &ss
, 0));
227 case IBCS2_SIGIGNORE_MASK
:
228 nbsa
.sa_handler
= SIG_IGN
;
229 sigemptyset(&nbsa
.sa_mask
);
231 return (sigaction1(l
, signum
, &nbsa
, 0, NULL
, 0));
233 case IBCS2_SIGPAUSE_MASK
:
235 sigdelset(&ss
, signum
);
236 return (sigsuspend1(l
, &ss
));
244 ibcs2_sys_sigprocmask(struct lwp
*l
, const struct ibcs2_sys_sigprocmask_args
*uap
, register_t
*retval
)
248 syscallarg(const ibcs2_sigset_t *) set;
249 syscallarg(ibcs2_sigset_t *) oset;
251 ibcs2_sigset_t niss
, oiss
;
256 switch (SCARG(uap
, how
)) {
257 case IBCS2_SIG_BLOCK
:
260 case IBCS2_SIG_UNBLOCK
:
263 case IBCS2_SIG_SETMASK
:
270 if (SCARG(uap
, set
)) {
271 error
= copyin(SCARG(uap
, set
), &niss
, sizeof(niss
));
274 ibcs2_to_native_sigset(&niss
, &nbss
);
276 error
= sigprocmask1(l
, how
,
277 SCARG(uap
, set
) ? &nbss
: 0, SCARG(uap
, oset
) ? &obss
: 0);
280 if (SCARG(uap
, oset
)) {
281 native_to_ibcs2_sigset(&obss
, &oiss
);
282 error
= copyout(&oiss
, SCARG(uap
, oset
), sizeof(oiss
));
290 ibcs2_sys_sigpending(struct lwp
*l
, const struct ibcs2_sys_sigpending_args
*uap
, register_t
*retval
)
293 syscallarg(ibcs2_sigset_t *) set;
298 sigpending1(l
, &bss
);
299 native_to_ibcs2_sigset(&bss
, &iss
);
300 return (copyout(&iss
, SCARG(uap
, set
), sizeof(iss
)));
304 ibcs2_sys_sigsuspend(struct lwp
*l
, const struct ibcs2_sys_sigsuspend_args
*uap
, register_t
*retval
)
307 syscallarg(const ibcs2_sigset_t *) set;
313 if (SCARG(uap
, set
)) {
314 error
= copyin(SCARG(uap
, set
), &sss
, sizeof(sss
));
317 ibcs2_to_native_sigset(&sss
, &bss
);
320 return (sigsuspend1(l
, SCARG(uap
, set
) ? &bss
: 0));
324 ibcs2_sys_pause(struct lwp
*l
, const void *v
, register_t
*retval
)
327 return (sigsuspend1(l
, 0));
331 ibcs2_sys_kill(struct lwp
*l
, const struct ibcs2_sys_kill_args
*uap
, register_t
*retval
)
335 syscallarg(int) signo;
337 struct sys_kill_args ka
;
338 int signum
= SCARG(uap
, signo
);
340 if (signum
< 0 || signum
>= IBCS2_NSIG
)
342 signum
= ibcs2_to_native_signo
[signum
];
344 SCARG(&ka
, pid
) = SCARG(uap
, pid
);
345 SCARG(&ka
, signum
) = signum
;
346 return sys_kill(l
, &ka
, retval
);