root/compat/freebsd/freebsd_signal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. openbsd_to_freebsd_sigaction
  2. freebsd_to_openbsd_sigaction
  3. freebsd_sys_sigaction40
  4. freebsd_sys_sigpending40
  5. freebsd_sys_sigprocmask40
  6. freebsd_sys_sigsuspend40

    1 /*      $OpenBSD: freebsd_signal.c,v 1.3 2003/06/02 23:28:00 millert Exp $      */
    2 /*      $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $   */
    3 
    4 /*
    5  * Copyright (c) 1997 Theo de Raadt. All rights reserved. 
    6  * Copyright (c) 1982, 1986, 1989, 1991, 1993
    7  *      The Regents of the University of California.  All rights reserved.
    8  * (c) UNIX System Laboratories, Inc.
    9  * All or some portions of this file are derived from material licensed
   10  * to the University of California by American Telephone and Telegraph
   11  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   12  * the permission of UNIX System Laboratories, Inc.
   13  *
   14  * Redistribution and use in source and binary forms, with or without
   15  * modification, are permitted provided that the following conditions
   16  * are met:
   17  * 1. Redistributions of source code must retain the above copyright
   18  *    notice, this list of conditions and the following disclaimer.
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  * 3. Neither the name of the University nor the names of its contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  *      @(#)kern_sig.c  8.7 (Berkeley) 4/18/94
   39  */
   40 
   41 #include <sys/param.h>
   42 #include <sys/proc.h>
   43 #include <sys/signalvar.h>
   44 #include <sys/signal.h>
   45 #include <sys/systm.h>
   46 #include <sys/mount.h>
   47 
   48 #include <compat/freebsd/freebsd_signal.h>
   49 #include <compat/freebsd/freebsd_syscallargs.h>
   50 
   51 static void freebsd_to_openbsd_sigaction(struct freebsd_sigaction *,
   52         struct sigaction *);
   53 
   54 static void openbsd_to_freebsd_sigaction(struct sigaction *,
   55         struct freebsd_sigaction *);
   56 
   57 static void
   58 openbsd_to_freebsd_sigaction(obsa, fbsa)
   59         struct sigaction         *obsa;
   60         struct freebsd_sigaction *fbsa;
   61 {
   62         bzero(fbsa, sizeof(struct freebsd_sigaction));
   63         fbsa->freebsd_sa_handler = obsa->sa_handler;
   64         bcopy(&obsa->sa_mask, &fbsa->freebsd_sa_mask.__bits[0],
   65                 sizeof(sigset_t));
   66         fbsa->freebsd_sa_flags = obsa->sa_flags;
   67 }
   68 
   69 static void
   70 freebsd_to_openbsd_sigaction(fbsa, obsa)
   71         struct freebsd_sigaction *fbsa;
   72         struct sigaction         *obsa;
   73 {
   74         obsa->sa_handler = fbsa->freebsd_sa_handler;
   75         bcopy(&fbsa->freebsd_sa_mask.__bits[0], &obsa->sa_mask,
   76                 sizeof(sigset_t));
   77         obsa->sa_flags = fbsa->freebsd_sa_flags;
   78 }
   79 
   80 /* ARGSUSED */
   81 int
   82 freebsd_sys_sigaction40(p, v, retval)
   83         struct proc *p;
   84         void *v;
   85         register_t *retval;
   86 {
   87         register struct freebsd_sys_sigaction40_args /* {
   88                 syscallarg(int) sig;
   89                 syscallarg(struct freebsd_sigaction *) act;
   90                 syscallarg(struct freebsd_sigaction *) oact;
   91         } */ *uap = v;
   92         struct sigaction vec;
   93         register struct sigaction *sa;
   94         struct freebsd_sigaction fbsa;
   95         register struct sigacts *ps = p->p_sigacts;
   96         register int signum;
   97         int bit, error;
   98 
   99         signum = SCARG(uap, sig);
  100         if (signum <= 0 || signum >= NSIG ||
  101             (SCARG(uap, act) && (signum == SIGKILL || signum == SIGSTOP)))
  102                 return (EINVAL);
  103         sa = &vec;
  104         if (SCARG(uap, oact)) {
  105                 sa->sa_handler = ps->ps_sigact[signum];
  106                 sa->sa_mask = ps->ps_catchmask[signum];
  107                 bit = sigmask(signum);
  108                 sa->sa_flags = 0;
  109                 if ((ps->ps_sigonstack & bit) != 0)
  110                         sa->sa_flags |= SA_ONSTACK;
  111                 if ((ps->ps_sigintr & bit) == 0)
  112                         sa->sa_flags |= SA_RESTART;
  113                 if ((ps->ps_sigreset & bit) != 0)
  114                         sa->sa_flags |= SA_RESETHAND;
  115                 if ((ps->ps_siginfo & bit) != 0)
  116                         sa->sa_flags |= SA_SIGINFO;
  117                 if (signum == SIGCHLD) {
  118                         if ((p->p_flag & P_NOCLDSTOP) != 0)
  119                                 sa->sa_flags |= SA_NOCLDSTOP;
  120                         if ((p->p_flag & P_NOCLDWAIT) != 0)
  121                                 sa->sa_flags |= SA_NOCLDWAIT;
  122                 }
  123                 if ((sa->sa_mask & bit) == 0)
  124                         sa->sa_flags |= SA_NODEFER;
  125                 sa->sa_mask &= ~bit;
  126                 openbsd_to_freebsd_sigaction(sa, &fbsa);
  127                 error = copyout((caddr_t)&fbsa, (caddr_t)SCARG(uap, oact),
  128                                 sizeof (struct freebsd_sigaction));
  129                 if (error)
  130                         return (error);
  131         }
  132         if (SCARG(uap, act)) {
  133                 error = copyin((caddr_t)SCARG(uap, act), (caddr_t)&fbsa,
  134                                sizeof (struct freebsd_sigaction));
  135                 if (error)
  136                         return (error);
  137                 freebsd_to_openbsd_sigaction(&fbsa, sa);
  138                 setsigvec(p, signum, sa);
  139         }
  140         return (0);
  141 }
  142 
  143 /* ARGSUSED */
  144 int
  145 freebsd_sys_sigpending40(p, v, retval)
  146         struct proc *p;
  147         void *v;
  148         register_t *retval;
  149 {
  150         register struct freebsd_sys_sigpending40_args /* {
  151                 freebsd_sigset_t *set;
  152         } */ *uap = v;
  153         freebsd_sigset_t fss;
  154 
  155         bcopy(&p->p_siglist, &fss.__bits[0], sizeof(sigset_t));
  156         return (copyout((caddr_t)&fss, (caddr_t)SCARG(uap, set), sizeof(fss)));
  157 }
  158 
  159 int
  160 freebsd_sys_sigprocmask40(p, v, retval)
  161         register struct proc *p;
  162         void *v;
  163         register_t *retval;
  164 {
  165         struct freebsd_sys_sigprocmask40_args /* {
  166                 syscallarg(int) how;
  167                 syscallarg(freebsd_sigset_t *) set;
  168                 syscallarg(freebsd_sigset_t *) oset;
  169         } */ *uap = v;
  170         freebsd_sigset_t nss, oss;
  171         sigset_t obnss;
  172         int error = 0;
  173 
  174         if (SCARG(uap, set)) {
  175                 error = copyin(SCARG(uap, set), &nss, sizeof(nss));
  176                 if (error)
  177                         return (error);
  178         }
  179         if (SCARG(uap, oset)) {
  180                 bzero(&oss, sizeof(freebsd_sigset_t));
  181                 bcopy(&p->p_sigmask, &oss.__bits[0], sizeof(sigset_t));
  182                 error = copyout((caddr_t)&oss, (caddr_t)SCARG(uap, oset),
  183                         sizeof(freebsd_sigset_t));
  184                 if (error)
  185                         return (error);
  186         }
  187         if (SCARG(uap, set)) {
  188                 bcopy(&nss.__bits[0], &obnss, sizeof(sigset_t));
  189                 (void)splhigh();
  190                 switch (SCARG(uap, how)) {
  191                 case SIG_BLOCK:
  192                         p->p_sigmask |= obnss &~ sigcantmask;
  193                         break;
  194                 case SIG_UNBLOCK:
  195                         p->p_sigmask &= ~obnss;
  196                         break;
  197                 case SIG_SETMASK:
  198                         p->p_sigmask = obnss &~ sigcantmask;
  199                         break;
  200                 default:
  201                         error = EINVAL;
  202                         break;
  203                 }
  204                 (void) spl0();
  205         }
  206         return (error);
  207 }
  208 
  209 int
  210 freebsd_sys_sigsuspend40(p, v, retval)
  211         register struct proc *p;
  212         void *v;
  213         register_t *retval;
  214 {
  215         struct freebsd_sys_sigsuspend40_args /* {
  216                 syscallarg(freebsd_sigset_t *) sigmask;
  217         } */ *uap = v;
  218         register struct sigacts *ps = p->p_sigacts;
  219         freebsd_sigset_t fbset;
  220         sigset_t obset;
  221 
  222         copyin(SCARG(uap, sigmask), &fbset, sizeof(freebsd_sigset_t));
  223         bcopy(&fbset.__bits[0], &obset, sizeof(sigset_t));
  224         /*
  225          * When returning from sigpause, we want
  226          * the old mask to be restored after the
  227          * signal handler has finished.  Thus, we
  228          * save it here and mark the sigacts structure
  229          * to indicate this.
  230          */
  231         ps->ps_oldmask = p->p_sigmask;
  232         ps->ps_flags |= SAS_OLDMASK;
  233         p->p_sigmask = obset &~ sigcantmask;
  234         while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
  235                 /* void */;
  236         /* always return EINTR rather than ERESTART... */
  237         return (EINTR);
  238 }

/* [<][>][^][v][top][bottom][index][help] */