1 /*-
2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994 Christos Zoulas
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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 without specific prior written permission
16 *
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.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/filedesc.h>
35 #include <sys/lock.h>
36 #include <sys/mutex.h>
37 #include <sys/proc.h>
38 #include <sys/signal.h>
39 #include <sys/signalvar.h>
40 #include <sys/syscallsubr.h>
41 #include <sys/sysproto.h>
42
43 #include <machine/cpu.h>
44
45 #include <compat/svr4/svr4.h>
46 #include <compat/svr4/svr4_types.h>
47 #include <compat/svr4/svr4_signal.h>
48 #include <compat/svr4/svr4_proto.h>
49 #include <compat/svr4/svr4_util.h>
50 #include <compat/svr4/svr4_ucontext.h>
51
52 #define svr4_sigmask(n) (1 << (((n) - 1) & 31))
53 #define svr4_sigword(n) (((n) - 1) >> 5)
54 #define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s)))
55 #define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
56 #define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
57
58 void svr4_to_bsd_sigaction(const struct svr4_sigaction *, struct sigaction *);
59 void bsd_to_svr4_sigaction(const struct sigaction *, struct svr4_sigaction *);
60 void svr4_sigfillset(svr4_sigset_t *);
61
62 int bsd_to_svr4_sig[SVR4_SIGTBLSZ] = {
63 SVR4_SIGHUP,
64 SVR4_SIGINT,
65 SVR4_SIGQUIT,
66 SVR4_SIGILL,
67 SVR4_SIGTRAP,
68 SVR4_SIGABRT,
69 SVR4_SIGEMT,
70 SVR4_SIGFPE,
71 SVR4_SIGKILL,
72 SVR4_SIGBUS,
73 SVR4_SIGSEGV,
74 SVR4_SIGSYS,
75 SVR4_SIGPIPE,
76 SVR4_SIGALRM,
77 SVR4_SIGTERM,
78 SVR4_SIGURG,
79 SVR4_SIGSTOP,
80 SVR4_SIGTSTP,
81 SVR4_SIGCONT,
82 SVR4_SIGCHLD,
83 SVR4_SIGTTIN,
84 SVR4_SIGTTOU,
85 SVR4_SIGIO,
86 SVR4_SIGXCPU,
87 SVR4_SIGXFSZ,
88 SVR4_SIGVTALRM,
89 SVR4_SIGPROF,
90 SVR4_SIGWINCH,
91 0, /* SIGINFO */
92 SVR4_SIGUSR1,
93 SVR4_SIGUSR2,
94 };
95
96 int svr4_to_bsd_sig[SVR4_SIGTBLSZ] = {
97 SIGHUP,
98 SIGINT,
99 SIGQUIT,
100 SIGILL,
101 SIGTRAP,
102 SIGABRT,
103 SIGEMT,
104 SIGFPE,
105 SIGKILL,
106 SIGBUS,
107 SIGSEGV,
108 SIGSYS,
109 SIGPIPE,
110 SIGALRM,
111 SIGTERM,
112 SIGUSR1,
113 SIGUSR2,
114 SIGCHLD,
115 0, /* XXX NetBSD uses SIGPWR here, but we don't seem to have one */
116 SIGWINCH,
117 SIGURG,
118 SIGIO,
119 SIGSTOP,
120 SIGTSTP,
121 SIGCONT,
122 SIGTTIN,
123 SIGTTOU,
124 SIGVTALRM,
125 SIGPROF,
126 SIGXCPU,
127 SIGXFSZ,
128 };
129
130 void
131 svr4_sigfillset(s)
132 svr4_sigset_t *s;
133 {
134 int i;
135
136 svr4_sigemptyset(s);
137 for (i = 0; i < SVR4_NSIG; i++)
138 if (svr4_to_bsd_sig[i] != 0)
139 svr4_sigaddset(s, i);
140 }
141
142 void
143 svr4_to_bsd_sigset(sss, bss)
144 const svr4_sigset_t *sss;
145 sigset_t *bss;
146 {
147 int i, newsig;
148
149 SIGEMPTYSET(*bss);
150 for (i = 0; i < SVR4_NSIG; i++)
151 if (svr4_sigismember(sss, i + 1)) {
152 newsig = svr4_to_bsd_sig[i];
153 if (newsig)
154 SIGADDSET(*bss, newsig);
155 }
156 }
157
158 void
159 bsd_to_svr4_sigset(bss, sss)
160 const sigset_t *bss;
161 svr4_sigset_t *sss;
162 {
163 int i, newsig;
164
165 svr4_sigemptyset(sss);
166 sss->bits[0] = bss->__bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1);
167 sss->bits[1] = bss->__bits[1];
168 sss->bits[2] = bss->__bits[2];
169 sss->bits[3] = bss->__bits[3];
170 for (i = 1; i <= SVR4_SIGTBLSZ; i++) {
171 if (SIGISMEMBER(*bss, i)) {
172 newsig = bsd_to_svr4_sig[_SIG_IDX(i)];
173 if (newsig)
174 svr4_sigaddset(sss, newsig);
175 }
176 }
177 }
178
179 /*
180 * XXX: Only a subset of the flags is currently implemented.
181 */
182 void
183 svr4_to_bsd_sigaction(ssa, bsa)
184 const struct svr4_sigaction *ssa;
185 struct sigaction *bsa;
186 {
187
188 bsa->sa_handler = (sig_t) ssa->ssa_handler;
189 svr4_to_bsd_sigset(&ssa->ssa_mask, &bsa->sa_mask);
190 bsa->sa_flags = 0;
191 if ((ssa->ssa_flags & SVR4_SA_ONSTACK) != 0)
192 bsa->sa_flags |= SA_ONSTACK;
193 if ((ssa->ssa_flags & SVR4_SA_RESETHAND) != 0)
194 bsa->sa_flags |= SA_RESETHAND;
195 if ((ssa->ssa_flags & SVR4_SA_RESTART) != 0)
196 bsa->sa_flags |= SA_RESTART;
197 if ((ssa->ssa_flags & SVR4_SA_SIGINFO) != 0)
198 DPRINTF(("svr4_to_bsd_sigaction: SA_SIGINFO ignored\n"));
199 if ((ssa->ssa_flags & SVR4_SA_NOCLDSTOP) != 0)
200 bsa->sa_flags |= SA_NOCLDSTOP;
201 if ((ssa->ssa_flags & SVR4_SA_NODEFER) != 0)
202 bsa->sa_flags |= SA_NODEFER;
203 if ((ssa->ssa_flags & SVR4_SA_NOCLDWAIT) != 0)
204 bsa->sa_flags |= SA_NOCLDWAIT;
205 if ((ssa->ssa_flags & ~SVR4_SA_ALLBITS) != 0)
206 DPRINTF(("svr4_to_bsd_sigaction: extra bits ignored\n"));
207 }
208
209 void
210 bsd_to_svr4_sigaction(bsa, ssa)
211 const struct sigaction *bsa;
212 struct svr4_sigaction *ssa;
213 {
214
215 ssa->ssa_handler = (svr4_sig_t) bsa->sa_handler;
216 bsd_to_svr4_sigset(&bsa->sa_mask, &ssa->ssa_mask);
217 ssa->ssa_flags = 0;
218 if ((bsa->sa_flags & SA_ONSTACK) != 0)
219 ssa->ssa_flags |= SVR4_SA_ONSTACK;
220 if ((bsa->sa_flags & SA_RESETHAND) != 0)
221 ssa->ssa_flags |= SVR4_SA_RESETHAND;
222 if ((bsa->sa_flags & SA_RESTART) != 0)
223 ssa->ssa_flags |= SVR4_SA_RESTART;
224 if ((bsa->sa_flags & SA_NODEFER) != 0)
225 ssa->ssa_flags |= SVR4_SA_NODEFER;
226 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
227 ssa->ssa_flags |= SVR4_SA_NOCLDSTOP;
228 }
229
230 void
231 svr4_to_bsd_sigaltstack(sss, bss)
232 const struct svr4_sigaltstack *sss;
233 struct sigaltstack *bss;
234 {
235
236 bss->ss_sp = sss->ss_sp;
237 bss->ss_size = sss->ss_size;
238 bss->ss_flags = 0;
239 if ((sss->ss_flags & SVR4_SS_DISABLE) != 0)
240 bss->ss_flags |= SS_DISABLE;
241 if ((sss->ss_flags & SVR4_SS_ONSTACK) != 0)
242 bss->ss_flags |= SS_ONSTACK;
243 if ((sss->ss_flags & ~SVR4_SS_ALLBITS) != 0)
244 /*XXX*/ uprintf("svr4_to_bsd_sigaltstack: extra bits ignored\n");
245 }
246
247 void
248 bsd_to_svr4_sigaltstack(bss, sss)
249 const struct sigaltstack *bss;
250 struct svr4_sigaltstack *sss;
251 {
252
253 sss->ss_sp = bss->ss_sp;
254 sss->ss_size = bss->ss_size;
255 sss->ss_flags = 0;
256 if ((bss->ss_flags & SS_DISABLE) != 0)
257 sss->ss_flags |= SVR4_SS_DISABLE;
258 if ((bss->ss_flags & SS_ONSTACK) != 0)
259 sss->ss_flags |= SVR4_SS_ONSTACK;
260 }
261
262 int
263 svr4_sys_sigaction(td, uap)
264 register struct thread *td;
265 struct svr4_sys_sigaction_args *uap;
266 {
267 struct svr4_sigaction isa;
268 struct sigaction nbsa, obsa;
269 struct sigaction *nbsap;
270 int error;
271
272 if (uap->signum < 0 || uap->signum >= SVR4_NSIG)
273 return (EINVAL);
274
275 DPRINTF(("@@@ svr4_sys_sigaction(%d, %d, %d)\n", td->td_proc->p_pid,
276 uap->signum,
277 SVR4_SVR42BSD_SIG(uap->signum)));
278
279 if (uap->nsa != NULL) {
280 if ((error = copyin(uap->nsa, &isa, sizeof(isa))) != 0)
281 return (error);
282 svr4_to_bsd_sigaction(&isa, &nbsa);
283 nbsap = &nbsa;
284 } else
285 nbsap = NULL;
286 #if defined(DEBUG_SVR4)
287 {
288 int i;
289 for (i = 0; i < 4; i++)
290 DPRINTF(("\tssa_mask[%d] = %lx\n", i,
291 isa.ssa_mask.bits[i]));
292 DPRINTF(("\tssa_handler = %p\n", isa.ssa_handler));
293 }
294 #endif
295 error = kern_sigaction(td, SVR4_SVR42BSD_SIG(uap->signum), nbsap, &obsa,
296 0);
297 if (error == 0 && uap->osa != NULL) {
298 bsd_to_svr4_sigaction(&obsa, &isa);
299 error = copyout(&isa, uap->osa, sizeof(isa));
300 }
301 return (error);
302 }
303
304 int
305 svr4_sys_sigaltstack(td, uap)
306 register struct thread *td;
307 struct svr4_sys_sigaltstack_args *uap;
308 {
309 struct svr4_sigaltstack sss;
310 struct sigaltstack nbss, obss, *nbssp;
311 int error;
312
313 if (uap->nss != NULL) {
314 if ((error = copyin(uap->nss, &sss, sizeof(sss))) != 0)
315 return (error);
316 svr4_to_bsd_sigaltstack(&sss, &nbss);
317 nbssp = &nbss;
318 } else
319 nbssp = NULL;
320 error = kern_sigaltstack(td, nbssp, &obss);
321 if (error == 0 && uap->oss != NULL) {
322 bsd_to_svr4_sigaltstack(&obss, &sss);
323 error = copyout(&sss, uap->oss, sizeof(sss));
324 }
325 return (error);
326 }
327
328 /*
329 * Stolen from the ibcs2 one
330 */
331 int
332 svr4_sys_signal(td, uap)
333 register struct thread *td;
334 struct svr4_sys_signal_args *uap;
335 {
336 struct proc *p;
337 int signum;
338 int error;
339
340 p = td->td_proc;
341 DPRINTF(("@@@ svr4_sys_signal(%d)\n", p->p_pid));
342
343 signum = SVR4_SIGNO(uap->signum);
344 if (signum < 0 || signum >= SVR4_NSIG) {
345 if (SVR4_SIGCALL(uap->signum) == SVR4_SIGNAL_MASK ||
346 SVR4_SIGCALL(uap->signum) == SVR4_SIGDEFER_MASK)
347 td->td_retval[0] = (int)SVR4_SIG_ERR;
348 return (EINVAL);
349 }
350 signum = SVR4_SVR42BSD_SIG(signum);
351
352 switch (SVR4_SIGCALL(uap->signum)) {
353 case SVR4_SIGDEFER_MASK:
354 if (uap->handler == SVR4_SIG_HOLD)
355 goto sighold;
356 /* FALLTHROUGH */
357
358 case SVR4_SIGNAL_MASK:
359 {
360 struct sigaction nbsa, obsa;
361
362 nbsa.sa_handler = (sig_t) uap->handler;
363 SIGEMPTYSET(nbsa.sa_mask);
364 nbsa.sa_flags = 0;
365 if (signum != SIGALRM)
366 nbsa.sa_flags = SA_RESTART;
367 error = kern_sigaction(td, signum, &nbsa, &obsa, 0);
368 if (error != 0) {
369 DPRINTF(("signal: sigaction failed: %d\n",
370 error));
371 td->td_retval[0] = (int)SVR4_SIG_ERR;
372 return (error);
373 }
374 td->td_retval[0] = (int)obsa.sa_handler;
375 return (0);
376 }
377
378 case SVR4_SIGHOLD_MASK:
379 sighold:
380 {
381 sigset_t set;
382
383 SIGEMPTYSET(set);
384 SIGADDSET(set, signum);
385 return (kern_sigprocmask(td, SIG_BLOCK, &set, NULL, 0));
386 }
387
388 case SVR4_SIGRELSE_MASK:
389 {
390 sigset_t set;
391
392 SIGEMPTYSET(set);
393 SIGADDSET(set, signum);
394 return (kern_sigprocmask(td, SIG_UNBLOCK, &set, NULL,
395 0));
396 }
397
398 case SVR4_SIGIGNORE_MASK:
399 {
400 struct sigaction sa;
401
402 sa.sa_handler = SIG_IGN;
403 SIGEMPTYSET(sa.sa_mask);
404 sa.sa_flags = 0;
405 error = kern_sigaction(td, signum, &sa, NULL, 0);
406 if (error != 0)
407 DPRINTF(("sigignore: sigaction failed\n"));
408 return (error);
409 }
410
411 case SVR4_SIGPAUSE_MASK:
412 {
413 sigset_t mask;
414
415 PROC_LOCK(p);
416 mask = td->td_sigmask;
417 PROC_UNLOCK(p);
418 SIGDELSET(mask, signum);
419 return kern_sigsuspend(td, mask);
420 }
421
422 default:
423 return (ENOSYS);
424 }
425 }
426
427
428 int
429 svr4_sys_sigprocmask(td, uap)
430 struct thread *td;
431 struct svr4_sys_sigprocmask_args *uap;
432 {
433 svr4_sigset_t sss;
434 sigset_t oss, nss;
435 sigset_t *nssp;
436 int error;
437
438 if (uap->set != NULL) {
439 if ((error = copyin(uap->set, &sss, sizeof(sss))) != 0)
440 return error;
441 svr4_to_bsd_sigset(&sss, &nss);
442 nssp = &nss;
443 } else
444 nssp = NULL;
445
446 /* SVR/4 sigprocmask flag values are the same as the FreeBSD values. */
447 error = kern_sigprocmask(td, uap->how, nssp, &oss, 0);
448 if (error == 0 && uap->oset != NULL) {
449 bsd_to_svr4_sigset(&oss, &sss);
450 error = copyout(&sss, uap->oset, sizeof(sss));
451 }
452 return (error);
453 }
454
455 int
456 svr4_sys_sigpending(td, uap)
457 struct thread *td;
458 struct svr4_sys_sigpending_args *uap;
459 {
460 struct proc *p;
461 sigset_t bss;
462 svr4_sigset_t sss;
463
464 p = td->td_proc;
465 DPRINTF(("@@@ svr4_sys_sigpending(%d)\n", p->p_pid));
466 switch (uap->what) {
467 case 1: /* sigpending */
468 if (uap->mask == NULL)
469 return 0;
470 PROC_LOCK(p);
471 bss = p->p_siglist;
472 SIGSETOR(bss, td->td_siglist);
473 SIGSETAND(bss, td->td_sigmask);
474 PROC_UNLOCK(p);
475 bsd_to_svr4_sigset(&bss, &sss);
476 break;
477
478 case 2: /* sigfillset */
479 svr4_sigfillset(&sss);
480 #if defined(DEBUG_SVR4)
481 {
482 int i;
483 for (i = 0; i < 4; i++)
484 DPRINTF(("new sigset[%d] = %lx\n", i, (long)sss.bits[i]));
485 }
486 #endif
487 break;
488
489 default:
490 return EINVAL;
491 }
492
493 return copyout(&sss, uap->mask, sizeof(sss));
494 }
495
496 int
497 svr4_sys_sigsuspend(td, uap)
498 register struct thread *td;
499 struct svr4_sys_sigsuspend_args *uap;
500 {
501 svr4_sigset_t sss;
502 sigset_t bss;
503 int error;
504
505 if ((error = copyin(uap->ss, &sss, sizeof(sss))) != 0)
506 return error;
507
508 svr4_to_bsd_sigset(&sss, &bss);
509 return kern_sigsuspend(td, bss);
510 }
511
512
513 int
514 svr4_sys_kill(td, uap)
515 register struct thread *td;
516 struct svr4_sys_kill_args *uap;
517 {
518 struct kill_args ka;
519
520 if (uap->signum < 0 || uap->signum >= SVR4_NSIG)
521 return (EINVAL);
522 ka.pid = uap->pid;
523 ka.signum = SVR4_SVR42BSD_SIG(uap->signum);
524 return kill(td, &ka);
525 }
526
527
528 int
529 svr4_sys_context(td, uap)
530 register struct thread *td;
531 struct svr4_sys_context_args *uap;
532 {
533 struct svr4_ucontext uc;
534 int error, onstack;
535
536 switch (uap->func) {
537 case 0:
538 DPRINTF(("getcontext(%p)\n", uap->uc));
539 PROC_LOCK(td->td_proc);
540 onstack = sigonstack(cpu_getstack(td));
541 PROC_UNLOCK(td->td_proc);
542 svr4_getcontext(td, &uc, &td->td_sigmask, onstack);
543 return copyout(&uc, uap->uc, sizeof(uc));
544
545 case 1:
546 DPRINTF(("setcontext(%p)\n", uap->uc));
547 if ((error = copyin(uap->uc, &uc, sizeof(uc))) != 0)
548 return error;
549 DPRINTF(("uc_flags = %lx\n", uc.uc_flags));
550 #if defined(DEBUG_SVR4)
551 {
552 int i;
553 for (i = 0; i < 4; i++)
554 DPRINTF(("uc_sigmask[%d] = %lx\n", i,
555 uc.uc_sigmask.bits[i]));
556 }
557 #endif
558 return svr4_setcontext(td, &uc);
559
560 default:
561 DPRINTF(("context(%d, %p)\n", uap->func,
562 uap->uc));
563 return ENOSYS;
564 }
565 return 0;
566 }
567
568 int
569 svr4_sys_pause(td, uap)
570 register struct thread *td;
571 struct svr4_sys_pause_args *uap;
572 {
573 sigset_t mask;
574
575 PROC_LOCK(td->td_proc);
576 mask = td->td_sigmask;
577 PROC_UNLOCK(td->td_proc);
578 return kern_sigsuspend(td, mask);
579 }
Cache object: c8cb70ae36815ba605ea2a5e9e7cc2d5
|