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