]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/svr4/svr4_signal.c
This commit was generated by cvs2svn to compensate for changes in r52279,
[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 svr4_sigmask(n)         (1 << (((n) - 1) & 31))
51 #define svr4_sigword(n)         (((n) - 1) >> 5)
52 #define svr4_sigemptyset(s)     memset((s), 0, sizeof(*(s)))
53 #define svr4_sigfillset(s)      memset((s), 0xffffffff, sizeof(*(s)))
54 #define svr4_sigismember(s, n)  ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
55 #define svr4_sigaddset(s, n)    ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
56
57 void svr4_to_bsd_sigaction __P((const struct svr4_sigaction *,
58                                 struct sigaction *));
59 void bsd_to_svr4_sigaction __P((const struct sigaction *,
60                                 struct svr4_sigaction *));
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_to_bsd_sigset(sss, bss)
132         const svr4_sigset_t *sss;
133         sigset_t *bss;
134 {
135         int i, newsig;
136
137         SIGEMPTYSET(*bss);
138         bss->__bits[0] = sss->bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1);
139         bss->__bits[1] = sss->bits[1];
140         bss->__bits[2] = sss->bits[2];
141         bss->__bits[3] = sss->bits[3];
142         for (i = 1; i <= SVR4_SIGTBLSZ; i++) {
143                 if (svr4_sigismember(sss, i)) {
144                         newsig = svr4_to_bsd_sig[_SIG_IDX(i)];
145                         if (newsig)
146                                 SIGADDSET(*bss, newsig);
147                 }
148         }
149 }
150
151 void
152 bsd_to_svr4_sigset(bss, sss)
153         const sigset_t *bss;
154         svr4_sigset_t *sss;
155 {
156         int i, newsig;
157
158         svr4_sigemptyset(sss);
159         sss->bits[0] = bss->__bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1);
160         sss->bits[1] = bss->__bits[1];
161         sss->bits[2] = bss->__bits[2];
162         sss->bits[3] = bss->__bits[3];
163         for (i = 1; i <= SVR4_SIGTBLSZ; i++) {
164                 if (SIGISMEMBER(*bss, i)) {
165                         newsig = bsd_to_svr4_sig[_SIG_IDX(i)];
166                         if (newsig)
167                                 svr4_sigaddset(sss, newsig);
168                 }
169         }
170 }
171
172 /*
173  * XXX: Only a subset of the flags is currently implemented.
174  */
175 void
176 svr4_to_bsd_sigaction(ssa, bsa)
177         const struct svr4_sigaction *ssa;
178         struct sigaction *bsa;
179 {
180
181         bsa->sa_handler = (sig_t) ssa->ssa_handler;
182         svr4_to_bsd_sigset(&ssa->ssa_mask, &bsa->sa_mask);
183         bsa->sa_flags = 0;
184         if ((ssa->ssa_flags & SVR4_SA_ONSTACK) != 0)
185                 bsa->sa_flags |= SA_ONSTACK;
186         if ((ssa->ssa_flags & SVR4_SA_RESETHAND) != 0)
187                 bsa->sa_flags |= SA_RESETHAND;
188         if ((ssa->ssa_flags & SVR4_SA_RESTART) != 0)
189                 bsa->sa_flags |= SA_RESTART;
190         if ((ssa->ssa_flags & SVR4_SA_SIGINFO) != 0)
191                 DPRINTF(("svr4_to_bsd_sigaction: SA_SIGINFO ignored\n"));
192         if ((ssa->ssa_flags & SVR4_SA_NOCLDSTOP) != 0)
193                 bsa->sa_flags |= SA_NOCLDSTOP;
194         if ((ssa->ssa_flags & SVR4_SA_NODEFER) != 0)
195                 bsa->sa_flags |= SA_NODEFER;
196         if ((ssa->ssa_flags & SVR4_SA_NOCLDWAIT) != 0)
197                 bsa->sa_flags |= SA_NOCLDWAIT;
198         if ((ssa->ssa_flags & ~SVR4_SA_ALLBITS) != 0)
199                 DPRINTF(("svr4_to_bsd_sigaction: extra bits ignored\n"));
200 }
201
202 void
203 bsd_to_svr4_sigaction(bsa, ssa)
204         const struct sigaction *bsa;
205         struct svr4_sigaction *ssa;
206 {
207
208         ssa->ssa_handler = (svr4_sig_t) bsa->sa_handler;
209         bsd_to_svr4_sigset(&bsa->sa_mask, &ssa->ssa_mask);
210         ssa->ssa_flags = 0;
211         if ((bsa->sa_flags & SA_ONSTACK) != 0)
212                 ssa->ssa_flags |= SVR4_SA_ONSTACK;
213         if ((bsa->sa_flags & SA_RESETHAND) != 0)
214                 ssa->ssa_flags |= SVR4_SA_RESETHAND;
215         if ((bsa->sa_flags & SA_RESTART) != 0)
216                 ssa->ssa_flags |= SVR4_SA_RESTART;
217         if ((bsa->sa_flags & SA_NODEFER) != 0)
218                 ssa->ssa_flags |= SVR4_SA_NODEFER;
219         if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
220                 ssa->ssa_flags |= SVR4_SA_NOCLDSTOP;
221 }
222
223 void
224 svr4_to_bsd_sigaltstack(sss, bss)
225         const struct svr4_sigaltstack *sss;
226         struct sigaltstack *bss;
227 {
228
229         bss->ss_sp = sss->ss_sp;
230         bss->ss_size = sss->ss_size;
231         bss->ss_flags = 0;
232         if ((sss->ss_flags & SVR4_SS_DISABLE) != 0)
233                 bss->ss_flags |= SS_DISABLE;
234         if ((sss->ss_flags & SVR4_SS_ONSTACK) != 0)
235                 bss->ss_flags |= SS_ONSTACK;
236         if ((sss->ss_flags & ~SVR4_SS_ALLBITS) != 0)
237           /*XXX*/ uprintf("svr4_to_bsd_sigaltstack: extra bits ignored\n");
238 }
239
240 void
241 bsd_to_svr4_sigaltstack(bss, sss)
242         const struct sigaltstack *bss;
243         struct svr4_sigaltstack *sss;
244 {
245
246         sss->ss_sp = bss->ss_sp;
247         sss->ss_size = bss->ss_size;
248         sss->ss_flags = 0;
249         if ((bss->ss_flags & SS_DISABLE) != 0)
250                 sss->ss_flags |= SVR4_SS_DISABLE;
251         if ((bss->ss_flags & SS_ONSTACK) != 0)
252                 sss->ss_flags |= SVR4_SS_ONSTACK;
253 }
254
255 int
256 svr4_sys_sigaction(p, uap)
257         register struct proc *p;
258         struct svr4_sys_sigaction_args *uap;
259 {
260         struct svr4_sigaction *nisa, *oisa, tmpisa;
261         struct sigaction *nbsa, *obsa, tmpbsa;
262         struct sigaction_args sa;
263         caddr_t sg;
264         int error;
265
266         sg = stackgap_init();
267         nisa = SCARG(uap, nsa);
268         oisa = SCARG(uap, osa);
269
270         if (oisa != NULL)
271                 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
272         else
273                 obsa = NULL;
274
275         if (nisa != NULL) {
276                 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
277                 if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
278                         return error;
279                 svr4_to_bsd_sigaction(&tmpisa, &tmpbsa);
280                 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
281                         return error;
282         } else
283                 nbsa = NULL;
284
285         SCARG(&sa, sig) = SVR4_SVR42BSD_SIG(SCARG(uap, signum));
286         SCARG(&sa, act) = nbsa;
287         SCARG(&sa, oact) = obsa;
288
289         if ((error = sigaction(p, &sa)) != 0)
290                 return error;
291
292         if (oisa != NULL) {
293                 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
294                         return error;
295                 bsd_to_svr4_sigaction(&tmpbsa, &tmpisa);
296                 if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
297                         return error;
298         }
299
300         return 0;
301 }
302
303 int 
304 svr4_sys_sigaltstack(p, uap)
305         register struct proc *p;
306         struct svr4_sys_sigaltstack_args *uap;
307 {
308         struct svr4_sigaltstack *nsss, *osss, tmpsss;
309         struct sigaltstack *nbss, *obss, tmpbss;
310         struct sigaltstack_args sa;
311         caddr_t sg;
312         int error, *retval;
313
314         retval = p->p_retval;
315         sg = stackgap_init();
316         nsss = SCARG(uap, nss);
317         osss = SCARG(uap, oss);
318
319         if (osss != NULL)
320                 obss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
321         else
322                 obss = NULL;
323
324         if (nsss != NULL) {
325                 nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
326                 if ((error = copyin(nsss, &tmpsss, sizeof(tmpsss))) != 0)
327                         return error;
328                 svr4_to_bsd_sigaltstack(&tmpsss, &tmpbss);
329                 if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0)
330                         return error;
331         } else
332                 nbss = NULL;
333
334         SCARG(&sa, ss) = nbss;
335         SCARG(&sa, oss) = obss;
336
337         if ((error = sigaltstack(p, &sa)) != 0)
338                 return error;
339
340         if (obss != NULL) {
341                 if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0)
342                         return error;
343                 bsd_to_svr4_sigaltstack(&tmpbss, &tmpsss);
344                 if ((error = copyout(&tmpsss, osss, sizeof(tmpsss))) != 0)
345                         return error;
346         }
347
348         return 0;
349 }
350
351 /*
352  * Stolen from the ibcs2 one
353  */
354 int
355 svr4_sys_signal(p, uap)
356         register struct proc *p;
357         struct svr4_sys_signal_args *uap;
358 {
359         int signum;
360         int error, *retval;
361         caddr_t sg = stackgap_init();
362
363         signum = SVR4_SVR42BSD_SIG(SVR4_SIGNO(SCARG(uap, signum)));
364         retval = p->p_retval;
365         if (signum <= 0 || signum > SVR4_NSIG)
366                 return (EINVAL);
367
368         switch (SVR4_SIGCALL(SCARG(uap, signum))) {
369         case SVR4_SIGDEFER_MASK:
370                 if (SCARG(uap, handler) == SVR4_SIG_HOLD)
371                         goto sighold;
372                 /* FALLTHROUGH */
373
374         case SVR4_SIGNAL_MASK:
375                 {
376                         struct sigaction_args sa_args;
377                         struct sigaction *nbsa, *obsa, sa;
378
379                         nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
380                         obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
381                         SCARG(&sa_args, sig) = signum;
382                         SCARG(&sa_args, act) = nbsa;
383                         SCARG(&sa_args, oact) = obsa;
384
385                         sa.sa_handler = (sig_t) SCARG(uap, handler);
386                         SIGEMPTYSET(sa.sa_mask);
387                         sa.sa_flags = 0;
388
389                         if (signum != SIGALRM)
390                                 sa.sa_flags = SA_RESTART;
391
392                         if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
393                                 return error;
394                         if ((error = sigaction(p, &sa_args)) != 0) {
395                                 DPRINTF(("signal: sigaction failed: %d\n",
396                                          error));
397                                 *retval = (int)SVR4_SIG_ERR;
398                                 return error;
399                         }
400                         if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
401                                 return error;
402                         *retval = (int)sa.sa_handler;
403                         return 0;
404                 }
405
406         case SVR4_SIGHOLD_MASK:
407 sighold:
408                 {
409                         struct sigprocmask_args sa;
410                         sigset_t *set;
411
412                         set = stackgap_alloc(&sg, sizeof(sigset_t));
413                         SIGEMPTYSET(*set);
414                         SIGADDSET(*set, signum);
415                         SCARG(&sa, how) = SIG_BLOCK;
416                         SCARG(&sa, set) = set;
417                         SCARG(&sa, oset) = NULL;
418                         return sigprocmask(p, &sa);
419                 }
420
421         case SVR4_SIGRELSE_MASK:
422                 {
423                         struct sigprocmask_args sa;
424                         sigset_t *set;
425
426                         set = stackgap_alloc(&sg, sizeof(sigset_t));
427                         SIGEMPTYSET(*set);
428                         SIGADDSET(*set, signum);
429                         SCARG(&sa, how) = SIG_UNBLOCK;
430                         SCARG(&sa, set) = set;
431                         SCARG(&sa, oset) = NULL;
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, sig) = signum;
442                         SCARG(&sa_args, act) = bsa;
443                         SCARG(&sa_args, oact) = 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                         sigset_t *set;
461
462                         set = stackgap_alloc(&sg, sizeof(sigset_t));
463                         *set = p->p_sigmask;
464                         SIGDELSET(*set, signum);
465                         SCARG(&sa, sigmask) = set;
466                         return sigsuspend(p, &sa);
467                 }
468
469         default:
470                 return (ENOSYS);
471         }
472 }
473
474
475 int
476 svr4_sys_sigprocmask(p, uap)
477         struct proc *p;
478         struct svr4_sys_sigprocmask_args *uap;
479 {
480         svr4_sigset_t sss;
481         sigset_t bss;
482         int error = 0, *retval;
483
484         retval = p->p_retval;
485         if (SCARG(uap, oset) != NULL) {
486                 /* Fix the return value first if needed */
487                 bsd_to_svr4_sigset(&p->p_sigmask, &sss);
488                 if ((error = copyout(&sss, SCARG(uap, oset), sizeof(sss))) != 0)
489                         return error;
490         }
491
492         if (SCARG(uap, set) == NULL)
493                 /* Just examine */
494                 return 0;
495
496         if ((error = copyin(SCARG(uap, set), &sss, sizeof(sss))) != 0)
497                 return error;
498
499         svr4_to_bsd_sigset(&sss, &bss);
500
501         (void) splhigh();
502
503         switch (SCARG(uap, how)) {
504         case SVR4_SIG_BLOCK:
505                 SIGSETOR(p->p_sigmask, bss);
506                 SIG_CANTMASK(p->p_sigmask);
507                 break;
508
509         case SVR4_SIG_UNBLOCK:
510                 SIGSETNAND(p->p_sigmask, bss);
511                 break;
512
513         case SVR4_SIG_SETMASK:
514                 p->p_sigmask = bss;
515                 SIG_CANTMASK(p->p_sigmask);
516                 break;
517
518         default:
519                 error = EINVAL;
520                 break;
521         }
522
523         (void) spl0();
524
525         return error;
526 }
527
528 int
529 svr4_sys_sigpending(p, uap)
530         struct proc *p;
531         struct svr4_sys_sigpending_args *uap;
532 {
533         sigset_t bss;
534         int *retval;
535         svr4_sigset_t sss;
536
537         retval = p->p_retval;
538         switch (SCARG(uap, what)) {
539         case 1: /* sigpending */
540                 if (SCARG(uap, mask) == NULL)
541                         return 0;
542                 bss = p->p_siglist;
543                 SIGSETAND(bss, p->p_sigmask);
544                 bsd_to_svr4_sigset(&bss, &sss);
545                 break;
546
547         case 2: /* sigfillset */
548                 svr4_sigfillset(&sss);
549                 break;
550
551         default:
552                 return EINVAL;
553         }
554                 
555         return copyout(&sss, SCARG(uap, mask), sizeof(sss));
556 }
557
558 int
559 svr4_sys_sigsuspend(p, uap)
560         register struct proc *p;
561         struct svr4_sys_sigsuspend_args *uap;
562 {
563         svr4_sigset_t sss;
564         sigset_t *bss;
565         struct sigsuspend_args sa;
566         int error;
567         caddr_t sg = stackgap_init();
568
569         if ((error = copyin(SCARG(uap, ss), &sss, sizeof(sss))) != 0)
570                 return error;
571
572         bss = stackgap_alloc(&sg, sizeof(sigset_t));
573         svr4_to_bsd_sigset(&sss, bss);
574
575         SCARG(&sa, sigmask) = bss;
576         return sigsuspend(p, &sa);
577 }
578
579
580 int
581 svr4_sys_kill(p, uap)
582         register struct proc *p;
583         struct svr4_sys_kill_args *uap;
584 {
585         struct kill_args ka;
586
587         SCARG(&ka, pid) = SCARG(uap, pid);
588         SCARG(&ka, signum) = SVR4_SVR42BSD_SIG(SCARG(uap, signum));
589         return kill(p, &ka);
590 }
591
592
593 int 
594 svr4_sys_context(p, uap)
595         register struct proc *p;
596         struct svr4_sys_context_args *uap;
597 {
598         struct svr4_ucontext uc;
599         int error;
600
601         switch (uap->func) {
602         case 0:
603                 DPRINTF(("getcontext(%p)\n", uap->uc));
604                 svr4_getcontext(p, &uc, &p->p_sigmask,
605                     p->p_sigstk.ss_flags & SS_ONSTACK);
606                 return copyout(&uc, uap->uc, sizeof(uc));
607
608         case 1: 
609                 DPRINTF(("setcontext(%p)\n", uap->uc));
610                 if ((error = copyin(uap->uc, &uc, sizeof(uc))) != 0)
611                         return error;
612                 DPRINTF(("uc_flags = %x\n", uc.uc_flags));
613                 DPRINTF(("uc_sigmask = %x\n", uc.uc_sigmask));
614
615                 return svr4_setcontext(p, &uc);
616
617         default:
618                 DPRINTF(("context(%d, %p)\n", uap->func,
619                     uap->uc));
620                 return ENOSYS;
621         }
622         return 0;
623 }
624
625 int
626 svr4_sys_pause(p, uap)
627         register struct proc *p;
628         struct svr4_sys_pause_args *uap;
629 {
630         struct sigsuspend_args bsa;
631
632         SCARG(&bsa, sigmask) = &p->p_sigmask;
633         return sigsuspend(p, &bsa);
634 }