Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / ibcs2 / ibcs2_signal.c
blob9bed72322ce4d8f235335ffd59a7b05c3efd78bb
1 /* $NetBSD: ibcs2_signal.c,v 1.28 2007/12/08 18:36:01 dsl Exp $ */
3 /*
4 * Copyright (c) 1995 Scott Bartram
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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>
36 #include <sys/proc.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 *);
63 void
64 ibcs2_to_native_sigset(const ibcs2_sigset_t *iss, sigset_t *bss)
66 int i, newsig;
68 sigemptyset(bss);
69 for (i = 1; i < IBCS2_NSIG; i++) {
70 if (ibcs2_sigismember(iss, i)) {
71 newsig = ibcs2_to_native_signo[i];
72 if (newsig)
73 sigaddset(bss, newsig);
78 void
79 native_to_ibcs2_sigset(const sigset_t *bss, ibcs2_sigset_t *iss)
81 int i, newsig;
83 ibcs2_sigemptyset(iss);
84 for (i = 1; i < NSIG; i++) {
85 if (sigismember(bss, i)) {
86 newsig = native_to_ibcs2_signo[i];
87 if (newsig)
88 ibcs2_sigaddset(iss, newsig);
93 void
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);
99 bsa->sa_flags = 0;
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");
118 void
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)
141 /* {
142 syscallarg(int) signum;
143 syscallarg(const struct ibcs2_sigaction *) nsa;
144 syscallarg(struct ibcs2_sigaction *) osa;
145 } */
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)
151 return EINVAL;
152 signum = ibcs2_to_native_signo[signum];
154 if (SCARG(uap, nsa)) {
155 error = copyin(SCARG(uap, nsa), &nisa, sizeof(nisa));
156 if (error)
157 return (error);
158 ibcs2_to_native_sigaction(&nisa, &nbsa);
160 error = sigaction1(l, signum,
161 SCARG(uap, nsa) ? &nbsa : 0, SCARG(uap, osa) ? &obsa : 0,
162 NULL, 0);
163 if (error)
164 return (error);
165 if (SCARG(uap, osa)) {
166 native_to_ibcs2_sigaction(&obsa, &oisa);
167 error = copyout(&oisa, SCARG(uap, osa), sizeof(oisa));
168 if (error)
169 return (error);
171 return (0);
175 ibcs2_sys_sigaltstack(struct lwp *l, const struct ibcs2_sys_sigaltstack_args *uap, register_t *retval)
177 /* {
178 syscallarg(const struct ibcs2_sigaltstack *) nss;
179 syscallarg(struct ibcs2_sigaltstack *) oss;
180 } */
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)
188 /* {
189 syscallarg(int) sig;
190 syscallarg(ibcs2_sig_t) fp;
191 } */
192 struct sigaction nbsa, obsa;
193 sigset_t ss;
194 int error, signum = IBCS2_SIGNO(SCARG(uap, sig));
196 if (signum < 0 || signum >= IBCS2_NSIG)
197 return EINVAL;
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)
203 goto sighold;
204 /* FALLTHROUGH */
206 case IBCS2_SIGNAL_MASK:
207 nbsa.sa_handler = (sig_t)SCARG(uap, fp);
208 sigemptyset(&nbsa.sa_mask);
209 nbsa.sa_flags = 0;
210 error = sigaction1(l, signum, &nbsa, &obsa, NULL, 0);
211 if (error)
212 return (error);
213 *retval = (int)obsa.sa_handler;
214 return (0);
216 case IBCS2_SIGHOLD_MASK:
217 sighold:
218 sigemptyset(&ss);
219 sigaddset(&ss, signum);
220 return (sigprocmask1(l, SIG_BLOCK, &ss, 0));
222 case IBCS2_SIGRELSE_MASK:
223 sigemptyset(&ss);
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);
230 nbsa.sa_flags = 0;
231 return (sigaction1(l, signum, &nbsa, 0, NULL, 0));
233 case IBCS2_SIGPAUSE_MASK:
234 ss = l->l_sigmask;
235 sigdelset(&ss, signum);
236 return (sigsuspend1(l, &ss));
238 default:
239 return (ENOSYS);
244 ibcs2_sys_sigprocmask(struct lwp *l, const struct ibcs2_sys_sigprocmask_args *uap, register_t *retval)
246 /* {
247 syscallarg(int) how;
248 syscallarg(const ibcs2_sigset_t *) set;
249 syscallarg(ibcs2_sigset_t *) oset;
250 } */
251 ibcs2_sigset_t niss, oiss;
252 sigset_t nbss, obss;
253 int how;
254 int error;
256 switch (SCARG(uap, how)) {
257 case IBCS2_SIG_BLOCK:
258 how = SIG_BLOCK;
259 break;
260 case IBCS2_SIG_UNBLOCK:
261 how = SIG_UNBLOCK;
262 break;
263 case IBCS2_SIG_SETMASK:
264 how = SIG_SETMASK;
265 break;
266 default:
267 return (EINVAL);
270 if (SCARG(uap, set)) {
271 error = copyin(SCARG(uap, set), &niss, sizeof(niss));
272 if (error)
273 return (error);
274 ibcs2_to_native_sigset(&niss, &nbss);
276 error = sigprocmask1(l, how,
277 SCARG(uap, set) ? &nbss : 0, SCARG(uap, oset) ? &obss : 0);
278 if (error)
279 return (error);
280 if (SCARG(uap, oset)) {
281 native_to_ibcs2_sigset(&obss, &oiss);
282 error = copyout(&oiss, SCARG(uap, oset), sizeof(oiss));
283 if (error)
284 return (error);
286 return (0);
290 ibcs2_sys_sigpending(struct lwp *l, const struct ibcs2_sys_sigpending_args *uap, register_t *retval)
292 /* {
293 syscallarg(ibcs2_sigset_t *) set;
294 } */
295 sigset_t bss;
296 ibcs2_sigset_t iss;
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)
306 /* {
307 syscallarg(const ibcs2_sigset_t *) set;
308 } */
309 ibcs2_sigset_t sss;
310 sigset_t bss;
311 int error;
313 if (SCARG(uap, set)) {
314 error = copyin(SCARG(uap, set), &sss, sizeof(sss));
315 if (error)
316 return (error);
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)
333 /* {
334 syscallarg(int) pid;
335 syscallarg(int) signo;
336 } */
337 struct sys_kill_args ka;
338 int signum = SCARG(uap, signo);
340 if (signum < 0 || signum >= IBCS2_NSIG)
341 return EINVAL;
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);