root/compat/ibcs2/ibcs2_signal.c

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

DEFINITIONS

This source file includes following definitions.
  1. ibcs2_to_bsd_sigset
  2. bsd_to_ibcs2_sigset
  3. ibcs2_to_bsd_sigaction
  4. bsd_to_ibcs2_sigaction
  5. ibcs2_sys_sigaction
  6. ibcs2_sys_sigsys
  7. ibcs2_sys_sigprocmask
  8. ibcs2_sys_sigpending
  9. ibcs2_sys_sigsuspend
  10. ibcs2_sys_pause
  11. ibcs2_sys_kill

    1 /*      $OpenBSD: ibcs2_signal.c,v 1.7 2002/03/14 01:26:50 millert Exp $        */
    2 /*      $NetBSD: ibcs2_signal.c,v 1.8 1996/05/03 17:05:27 christos Exp $        */
    3 
    4 /*
    5  * Copyright (c) 1995 Scott Bartram
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   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/ioctl.h>
   37 #include <sys/mount.h>
   38 #include <sys/kernel.h>
   39 #include <sys/signal.h>
   40 #include <sys/signalvar.h>
   41 #include <sys/malloc.h>
   42 
   43 #include <sys/syscallargs.h>
   44 
   45 #include <compat/ibcs2/ibcs2_types.h>
   46 #include <compat/ibcs2/ibcs2_signal.h>
   47 #include <compat/ibcs2/ibcs2_syscallargs.h>
   48 #include <compat/ibcs2/ibcs2_util.h>
   49 
   50 #define sigemptyset(s)          bzero((s), sizeof(*(s)))
   51 #define sigismember(s, n)       (*(s) & sigmask(n))
   52 #define sigaddset(s, n)         (*(s) |= sigmask(n))
   53 
   54 #define ibcs2_sigmask(n)        (1 << ((n) - 1))
   55 #define ibcs2_sigemptyset(s)    bzero((s), sizeof(*(s)))
   56 #define ibcs2_sigismember(s, n) (*(s) & ibcs2_sigmask(n))
   57 #define ibcs2_sigaddset(s, n)   (*(s) |= ibcs2_sigmask(n))
   58 
   59 int bsd_to_ibcs2_sig[] = {
   60         0,                      /* 0 */
   61         IBCS2_SIGHUP,           /* 1 */
   62         IBCS2_SIGINT,           /* 2 */
   63         IBCS2_SIGQUIT,          /* 3 */
   64         IBCS2_SIGILL,           /* 4 */
   65         IBCS2_SIGTRAP,          /* 5 */
   66         IBCS2_SIGABRT,          /* 6 */
   67         IBCS2_SIGEMT,           /* 7 */
   68         IBCS2_SIGFPE,           /* 8 */
   69         IBCS2_SIGKILL,          /* 9 */
   70         IBCS2_SIGBUS,           /* 10 */
   71         IBCS2_SIGSEGV,          /* 11 */
   72         IBCS2_SIGSYS,           /* 12 */
   73         IBCS2_SIGPIPE,          /* 13 */
   74         IBCS2_SIGALRM,          /* 14 */
   75         IBCS2_SIGTERM,          /* 15 */
   76         0,                      /* 16 - SIGURG */
   77         IBCS2_SIGSTOP,          /* 17 */
   78         IBCS2_SIGTSTP,          /* 18 */
   79         IBCS2_SIGCONT,          /* 19 */
   80         IBCS2_SIGCLD,           /* 20 */
   81         IBCS2_SIGTTIN,          /* 21 */
   82         IBCS2_SIGTTOU,          /* 22 */
   83         IBCS2_SIGPOLL,          /* 23 */
   84         0,                      /* 24 - SIGXCPU */
   85         0,                      /* 25 - SIGXFSZ */
   86         IBCS2_SIGVTALRM,        /* 26 */
   87         IBCS2_SIGPROF,          /* 27 */
   88         IBCS2_SIGWINCH,         /* 28 */
   89         0,                      /* 29 */
   90         IBCS2_SIGUSR1,          /* 30 */
   91         IBCS2_SIGUSR2,          /* 31 */
   92 };
   93 
   94 int ibcs2_to_bsd_sig[] = {
   95         0,                      /* 0 */
   96         SIGHUP,                 /* 1 */
   97         SIGINT,                 /* 2 */
   98         SIGQUIT,                /* 3 */
   99         SIGILL,                 /* 4 */
  100         SIGTRAP,                /* 5 */
  101         SIGABRT,                /* 6 */
  102         SIGEMT,                 /* 7 */
  103         SIGFPE,                 /* 8 */
  104         SIGKILL,                /* 9 */
  105         SIGBUS,                 /* 10 */
  106         SIGSEGV,                /* 11 */
  107         SIGSYS,                 /* 12 */
  108         SIGPIPE,                /* 13 */
  109         SIGALRM,                /* 14 */
  110         SIGTERM,                /* 15 */
  111         SIGUSR1,                /* 16 */
  112         SIGUSR2,                /* 17 */
  113         SIGCHLD,                /* 18 */
  114         0,                      /* 19 - SIGPWR */
  115         SIGWINCH,               /* 20 */
  116         0,                      /* 21 */
  117         SIGIO,                  /* 22 */
  118         SIGSTOP,                /* 23 */
  119         SIGTSTP,                /* 24 */
  120         SIGCONT,                /* 25 */
  121         SIGTTIN,                /* 26 */
  122         SIGTTOU,                /* 27 */
  123         SIGVTALRM,              /* 28 */
  124         SIGPROF,                /* 29 */
  125         0,                      /* 30 */
  126         0,                      /* 31 */
  127 };
  128 
  129 void ibcs2_to_bsd_sigset(const ibcs2_sigset_t *, sigset_t *);
  130 void bsd_to_ibcs2_sigset(const sigset_t *, ibcs2_sigset_t *);
  131 void ibcs2_to_bsd_sigaction(struct ibcs2_sigaction *,
  132     struct sigaction *);
  133 void bsd_to_ibcs2_sigaction(struct sigaction *, struct ibcs2_sigaction *);
  134 
  135 void
  136 ibcs2_to_bsd_sigset(iss, bss)
  137         const ibcs2_sigset_t *iss;
  138         sigset_t *bss;
  139 {
  140         int i, newsig;
  141 
  142         sigemptyset(bss);
  143         for (i = 1; i < IBCS2_NSIG; i++) {
  144                 if (ibcs2_sigismember(iss, i)) {
  145                         newsig = ibcs2_to_bsd_sig[i];
  146                         if (newsig)
  147                                 sigaddset(bss, newsig);
  148                 }
  149         }
  150 }
  151 
  152 void
  153 bsd_to_ibcs2_sigset(bss, iss)
  154         const sigset_t *bss;
  155         ibcs2_sigset_t *iss;
  156 {
  157         int i, newsig;
  158 
  159         ibcs2_sigemptyset(iss);
  160         for (i = 1; i < NSIG; i++) {
  161                 if (sigismember(bss, i)) {
  162                         newsig = bsd_to_ibcs2_sig[i];
  163                         if (newsig)
  164                                 ibcs2_sigaddset(iss, newsig);
  165                 }
  166         }
  167 }
  168 
  169 void
  170 ibcs2_to_bsd_sigaction(isa, bsa)
  171         struct ibcs2_sigaction *isa;
  172         struct sigaction *bsa;
  173 {
  174 
  175         bsa->sa_handler = isa->sa__handler;
  176         ibcs2_to_bsd_sigset(&isa->sa_mask, &bsa->sa_mask);
  177         bsa->sa_flags = 0;
  178         if ((isa->sa_flags & IBCS2_SA_NOCLDSTOP) != 0)
  179                 bsa->sa_flags |= SA_NOCLDSTOP;
  180 }
  181 
  182 void
  183 bsd_to_ibcs2_sigaction(bsa, isa)
  184         struct sigaction *bsa;
  185         struct ibcs2_sigaction *isa;
  186 {
  187 
  188         isa->sa__handler = bsa->sa_handler;
  189         bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->sa_mask);
  190         isa->sa_flags = 0;
  191         if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
  192                 isa->sa_flags |= IBCS2_SA_NOCLDSTOP;
  193 }
  194 
  195 int
  196 ibcs2_sys_sigaction(p, v, retval)
  197         register struct proc *p;
  198         void *v;
  199         register_t *retval;
  200 {
  201         struct ibcs2_sys_sigaction_args /* {
  202                 syscallarg(int) signum;
  203                 syscallarg(struct ibcs2_sigaction *) nsa;
  204                 syscallarg(struct ibcs2_sigaction *) osa;
  205         } */ *uap = v;
  206         struct ibcs2_sigaction *nisa, *oisa, tmpisa;
  207         struct sigaction *nbsa, *obsa, tmpbsa;
  208         struct sys_sigaction_args sa;
  209         caddr_t sg;
  210         int error;
  211 
  212         if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= IBCS2_NSIG)
  213                 return (EINVAL);
  214 
  215         sg = stackgap_init(p->p_emul);
  216         nisa = SCARG(uap, nsa);
  217         oisa = SCARG(uap, osa);
  218 
  219         if (oisa != NULL)
  220                 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  221         else
  222                 obsa = NULL;
  223 
  224         if (nisa != NULL) {
  225                 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  226                 if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
  227                         return error;
  228                 ibcs2_to_bsd_sigaction(&tmpisa, &tmpbsa);
  229                 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
  230                         return error;
  231         } else
  232                 nbsa = NULL;
  233 
  234         SCARG(&sa, signum) = ibcs2_to_bsd_sig[SCARG(uap, signum)];
  235         SCARG(&sa, nsa) = nbsa;
  236         SCARG(&sa, osa) = obsa;
  237 
  238         if ((error = sys_sigaction(p, &sa, retval)) != 0)
  239                 return error;
  240 
  241         if (oisa != NULL) {
  242                 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
  243                         return error;
  244                 bsd_to_ibcs2_sigaction(&tmpbsa, &tmpisa);
  245                 if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
  246                         return error;
  247         }
  248 
  249         return 0;
  250 }
  251 
  252 int
  253 ibcs2_sys_sigsys(p, v, retval)
  254         register struct proc *p;
  255         void *v;
  256         register_t *retval;
  257 {
  258         struct ibcs2_sys_sigsys_args /* {
  259                 syscallarg(int) sig;
  260                 syscallarg(ibcs2_sig_t) fp;
  261         } */ *uap = v;
  262         int signum, error;
  263         caddr_t sg = stackgap_init(p->p_emul);
  264 
  265         signum = IBCS2_SIGNO(SCARG(uap, sig));
  266         if (signum < 0 || signum >= IBCS2_NSIG) {
  267                 if (IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGNAL_MASK ||
  268                     IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGSET_MASK)
  269                         *retval = (int)IBCS2_SIG_ERR;
  270                 return EINVAL;
  271         }
  272         signum = ibcs2_to_bsd_sig[signum];
  273         
  274         switch (IBCS2_SIGCALL(SCARG(uap, sig))) {
  275         /*
  276          * sigset is identical to signal() except that SIG_HOLD is allowed as
  277          * an action.
  278          */
  279         case IBCS2_SIGSET_MASK:
  280                 /*
  281                  * sigset is identical to signal() except
  282                  * that SIG_HOLD is allowed as
  283                  * an action.
  284                  */
  285                 if (SCARG(uap, fp) == IBCS2_SIG_HOLD) {
  286                         struct sys_sigprocmask_args sa;
  287 
  288                         SCARG(&sa, how) = SIG_BLOCK;
  289                         SCARG(&sa, mask) = sigmask(signum);
  290                         return sys_sigprocmask(p, &sa, retval);
  291                 }
  292                 /* FALLTHROUGH */
  293 
  294         case IBCS2_SIGNAL_MASK:
  295                 {
  296                         struct sys_sigaction_args sa_args;
  297                         struct sigaction *nbsa, *obsa, sa;
  298 
  299                         nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  300                         obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  301                         SCARG(&sa_args, signum) = signum;
  302                         SCARG(&sa_args, nsa) = nbsa;
  303                         SCARG(&sa_args, osa) = obsa;
  304 
  305                         sa.sa_handler = SCARG(uap, fp);
  306                         sigemptyset(&sa.sa_mask);
  307                         sa.sa_flags = 0;
  308 #if 0
  309                         if (signum != SIGALRM)
  310                                 sa.sa_flags = SA_RESTART;
  311 #endif
  312                         if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
  313                                 return error;
  314                         if ((error = sys_sigaction(p, &sa_args, retval)) != 0) {
  315                                 DPRINTF(("signal: sigaction failed: %d\n",
  316                                          error));
  317                                 *retval = (int)IBCS2_SIG_ERR;
  318                                 return error;
  319                         }
  320                         if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
  321                                 return error;
  322                         *retval = (int)sa.sa_handler;
  323                         return 0;
  324                 }
  325                 
  326         case IBCS2_SIGHOLD_MASK:
  327                 {
  328                         struct sys_sigprocmask_args sa;
  329 
  330                         SCARG(&sa, how) = SIG_BLOCK;
  331                         SCARG(&sa, mask) = sigmask(signum);
  332                         return sys_sigprocmask(p, &sa, retval);
  333                 }
  334                 
  335         case IBCS2_SIGRELSE_MASK:
  336                 {
  337                         struct sys_sigprocmask_args sa;
  338 
  339                         SCARG(&sa, how) = SIG_UNBLOCK;
  340                         SCARG(&sa, mask) = sigmask(signum);
  341                         return sys_sigprocmask(p, &sa, retval);
  342                 }
  343                 
  344         case IBCS2_SIGIGNORE_MASK:
  345                 {
  346                         struct sys_sigaction_args sa_args;
  347                         struct sigaction *bsa, sa;
  348 
  349                         bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  350                         SCARG(&sa_args, signum) = signum;
  351                         SCARG(&sa_args, nsa) = bsa;
  352                         SCARG(&sa_args, osa) = NULL;
  353 
  354                         sa.sa_handler = SIG_IGN;
  355                         sigemptyset(&sa.sa_mask);
  356                         sa.sa_flags = 0;
  357                         if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
  358                                 return error;
  359                         if ((error = sys_sigaction(p, &sa_args, retval)) != 0) {
  360                                 DPRINTF(("sigignore: sigaction failed\n"));
  361                                 return error;
  362                         }
  363                         return 0;
  364                 }
  365                 
  366         case IBCS2_SIGPAUSE_MASK:
  367                 {
  368                         struct sys_sigsuspend_args sa;
  369 
  370                         SCARG(&sa, mask) = p->p_sigmask &~ sigmask(signum);
  371                         return sys_sigsuspend(p, &sa, retval);
  372                 }
  373                 
  374         default:
  375                 return ENOSYS;
  376         }
  377 }
  378 
  379 int
  380 ibcs2_sys_sigprocmask(p, v, retval)
  381         register struct proc *p;
  382         void *v;
  383         register_t *retval;
  384 {
  385         struct ibcs2_sys_sigprocmask_args /* {
  386                 syscallarg(int) how;
  387                 syscallarg(ibcs2_sigset_t *) set;
  388                 syscallarg(ibcs2_sigset_t *) oset;
  389         } */ *uap = v;
  390         ibcs2_sigset_t iss;
  391         sigset_t bss;
  392         int error = 0;
  393 
  394         if (SCARG(uap, oset) != NULL) {
  395                 /* Fix the return value first if needed */
  396                 bsd_to_ibcs2_sigset(&p->p_sigmask, &iss);
  397                 if ((error = copyout(&iss, SCARG(uap, oset), sizeof(iss))) != 0)
  398                         return error;
  399         }
  400                 
  401         if (SCARG(uap, set) == NULL)
  402                 /* Just examine */
  403                 return 0;
  404 
  405         if ((error = copyin(SCARG(uap, set), &iss, sizeof(iss))) != 0)
  406                 return error;
  407 
  408         ibcs2_to_bsd_sigset(&iss, &bss);
  409 
  410         (void) splhigh();
  411 
  412         switch (SCARG(uap, how)) {
  413         case IBCS2_SIG_BLOCK:
  414                 p->p_sigmask |= bss & ~sigcantmask;
  415                 break;
  416 
  417         case IBCS2_SIG_UNBLOCK:
  418                 p->p_sigmask &= ~bss;
  419                 break;
  420 
  421         case IBCS2_SIG_SETMASK:
  422                 p->p_sigmask = bss & ~sigcantmask;
  423                 break;
  424 
  425         default:
  426                 error = EINVAL;
  427                 break;
  428         }
  429 
  430         (void) spl0();
  431 
  432         return error;
  433 }
  434 
  435 int
  436 ibcs2_sys_sigpending(p, v, retval)
  437         register struct proc *p;
  438         void *v;
  439         register_t *retval;
  440 {
  441         struct ibcs2_sys_sigpending_args /* {
  442                 syscallarg(ibcs2_sigset_t *) mask;
  443         } */ *uap = v;
  444         sigset_t bss;
  445         ibcs2_sigset_t iss;
  446 
  447         bss = p->p_siglist & p->p_sigmask;
  448         bsd_to_ibcs2_sigset(&bss, &iss);
  449 
  450         return copyout(&iss, SCARG(uap, mask), sizeof(iss));
  451 }
  452 
  453 int
  454 ibcs2_sys_sigsuspend(p, v, retval)
  455         register struct proc *p;
  456         void *v;
  457         register_t *retval;
  458 {
  459         struct ibcs2_sys_sigsuspend_args /* {
  460                 syscallarg(ibcs2_sigset_t *) mask;
  461         } */ *uap = v;
  462         ibcs2_sigset_t sss;
  463         sigset_t bss;
  464         struct sys_sigsuspend_args sa;
  465         int error;
  466 
  467         if ((error = copyin(SCARG(uap, mask), &sss, sizeof(sss))) != 0)
  468                 return error;
  469 
  470         ibcs2_to_bsd_sigset(&sss, &bss);
  471 
  472         SCARG(&sa, mask) = bss;
  473         return sys_sigsuspend(p, &sa, retval);
  474 }
  475 
  476 int
  477 ibcs2_sys_pause(p, v, retval)
  478         register struct proc *p;
  479         void *v;
  480         register_t *retval;
  481 {
  482         struct sys_sigsuspend_args bsa;
  483 
  484         SCARG(&bsa, mask) = p->p_sigmask;
  485         return sys_sigsuspend(p, &bsa, retval);
  486 }
  487 
  488 int
  489 ibcs2_sys_kill(p, v, retval)
  490         register struct proc *p;
  491         void *v;
  492         register_t *retval;
  493 {
  494         struct ibcs2_sys_kill_args /* {
  495                 syscallarg(int) pid;
  496                 syscallarg(int) signo;
  497         } */ *uap = v;
  498         struct sys_kill_args ka;
  499 
  500         if (SCARG(uap, signo) < 0 || SCARG(uap, signo) >= IBCS2_NSIG)
  501                 return (EINVAL);
  502         SCARG(&ka, pid) = SCARG(uap, pid);
  503         SCARG(&ka, signum) = ibcs2_to_bsd_sig[SCARG(uap, signo)];
  504         return sys_kill(p, &ka, retval);
  505 }

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