The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/ibcs2/ibcs2_signal.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1995 Scott Bartram
    3  * Copyright (c) 1995 Steven Wallace
    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: releng/5.0/sys/i386/ibcs2/ibcs2_signal.c 108086 2002-12-19 09:40:13Z alfred $
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/lock.h>
   34 #include <sys/mutex.h>
   35 #include <sys/signalvar.h>
   36 #include <sys/sysproto.h>
   37 
   38 #include <i386/ibcs2/ibcs2_types.h>
   39 #include <i386/ibcs2/ibcs2_signal.h>
   40 #include <i386/ibcs2/ibcs2_proto.h>
   41 #include <i386/ibcs2/ibcs2_xenix.h>
   42 #include <i386/ibcs2/ibcs2_util.h>
   43 
   44 #define sigemptyset(s)          SIGEMPTYSET(*(s))
   45 #define sigismember(s, n)       SIGISMEMBER(*(s), n)
   46 #define sigaddset(s, n)         SIGADDSET(*(s), n)
   47 
   48 #define ibcs2_sigmask(n)        (1 << ((n) - 1))
   49 #define ibcs2_sigemptyset(s)    bzero((s), sizeof(*(s)))
   50 #define ibcs2_sigismember(s, n) (*(s) & ibcs2_sigmask(n))
   51 #define ibcs2_sigaddset(s, n)   (*(s) |= ibcs2_sigmask(n))
   52 
   53 static void ibcs2_to_bsd_sigset(const ibcs2_sigset_t *, sigset_t *);
   54 static void bsd_to_ibcs2_sigset(const sigset_t *, ibcs2_sigset_t *);
   55 static void ibcs2_to_bsd_sigaction(struct ibcs2_sigaction *,
   56                                         struct sigaction *);
   57 static void bsd_to_ibcs2_sigaction(struct sigaction *,
   58                                         struct ibcs2_sigaction *);
   59 
   60 int bsd_to_ibcs2_sig[IBCS2_SIGTBLSZ] = {
   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         0                       /* 32 */
   93 };
   94 
   95 static int ibcs2_to_bsd_sig[IBCS2_SIGTBLSZ] = {
   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         0                       /* 32 */
  128 };
  129 
  130 void
  131 ibcs2_to_bsd_sigset(iss, bss)
  132         const ibcs2_sigset_t *iss;
  133         sigset_t *bss;
  134 {
  135         int i, newsig;
  136 
  137         sigemptyset(bss);
  138         for (i = 1; i <= IBCS2_SIGTBLSZ; i++) {
  139                 if (ibcs2_sigismember(iss, i)) {
  140                         newsig = ibcs2_to_bsd_sig[_SIG_IDX(i)];
  141                         if (newsig)
  142                                 sigaddset(bss, newsig);
  143                 }
  144         }
  145 }
  146 
  147 static void
  148 bsd_to_ibcs2_sigset(bss, iss)
  149         const sigset_t *bss;
  150         ibcs2_sigset_t *iss;
  151 {
  152         int i, newsig;
  153 
  154         ibcs2_sigemptyset(iss);
  155         for (i = 1; i <= IBCS2_SIGTBLSZ; i++) {
  156                 if (sigismember(bss, i)) {
  157                         newsig = bsd_to_ibcs2_sig[_SIG_IDX(i)];
  158                         if (newsig)
  159                                 ibcs2_sigaddset(iss, newsig);
  160                 }
  161         }
  162 }
  163 
  164 static void
  165 ibcs2_to_bsd_sigaction(isa, bsa)
  166         struct ibcs2_sigaction *isa;
  167         struct sigaction *bsa;
  168 {
  169 
  170         bsa->sa_handler = isa->isa_handler;
  171         ibcs2_to_bsd_sigset(&isa->isa_mask, &bsa->sa_mask);
  172         bsa->sa_flags = 0;      /* ??? SA_NODEFER */
  173         if ((isa->isa_flags & IBCS2_SA_NOCLDSTOP) != 0)
  174                 bsa->sa_flags |= SA_NOCLDSTOP;
  175 }
  176 
  177 static void
  178 bsd_to_ibcs2_sigaction(bsa, isa)
  179         struct sigaction *bsa;
  180         struct ibcs2_sigaction *isa;
  181 {
  182 
  183         isa->isa_handler = bsa->sa_handler;
  184         bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->isa_mask);
  185         isa->isa_flags = 0;
  186         if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
  187                 isa->isa_flags |= IBCS2_SA_NOCLDSTOP;
  188 }
  189 
  190 int
  191 ibcs2_sigaction(td, uap)
  192         register struct thread *td;
  193         struct ibcs2_sigaction_args *uap;
  194 {
  195         struct ibcs2_sigaction *nisa, *oisa, tmpisa;
  196         struct sigaction *nbsa, *obsa, tmpbsa;
  197         struct sigaction_args sa;
  198         caddr_t sg;
  199         int error;
  200 
  201         sg = stackgap_init();
  202         nisa = uap->act;
  203         oisa = uap->oact;
  204 
  205         if (oisa != NULL)
  206                 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  207         else
  208                 obsa = NULL;
  209 
  210         if (nisa != NULL) {
  211                 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  212                 if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
  213                         return error;
  214                 ibcs2_to_bsd_sigaction(&tmpisa, &tmpbsa);
  215                 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
  216                         return error;
  217         } else
  218                 nbsa = NULL;
  219 
  220         sa.sig = ibcs2_to_bsd_sig[_SIG_IDX(uap->sig)];
  221         sa.act = nbsa;
  222         sa.oact = obsa;
  223 
  224         if ((error = sigaction(td, &sa)) != 0)
  225                 return error;
  226 
  227         if (oisa != NULL) {
  228                 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
  229                         return error;
  230                 bsd_to_ibcs2_sigaction(&tmpbsa, &tmpisa);
  231                 if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
  232                         return error;
  233         }
  234 
  235         return 0;
  236 }
  237 
  238 int
  239 ibcs2_sigsys(td, uap)
  240         register struct thread *td;
  241         struct ibcs2_sigsys_args *uap;
  242 {
  243         struct proc *p = td->td_proc;
  244         struct sigaction sa;
  245         int signum = ibcs2_to_bsd_sig[_SIG_IDX(IBCS2_SIGNO(uap->sig))];
  246         int error;
  247         caddr_t sg = stackgap_init();
  248 
  249         if (signum <= 0 || signum >= IBCS2_NSIG) {
  250                 if (IBCS2_SIGCALL(uap->sig) == IBCS2_SIGNAL_MASK ||
  251                     IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK)
  252                         td->td_retval[0] = (int)IBCS2_SIG_ERR;
  253                 return EINVAL;
  254         }
  255         
  256         switch (IBCS2_SIGCALL(uap->sig)) {
  257         case IBCS2_SIGSET_MASK:
  258                 /*
  259                  * Check for SIG_HOLD action.
  260                  * Otherwise, perform signal() except with different sa_flags.
  261                  */
  262                 if (uap->fp != IBCS2_SIG_HOLD) {
  263                         /* add sig to mask before exececuting signal handler */
  264                         sa.sa_flags = 0;
  265                         goto ibcs2_sigset;
  266                 }
  267                 /* else FALLTHROUGH to sighold */
  268 
  269         case IBCS2_SIGHOLD_MASK:
  270                 {
  271                         sigset_t mask;
  272                         struct sigprocmask_args sa;
  273 
  274                         SIGEMPTYSET(mask);
  275                         SIGADDSET(mask, signum);
  276                         sa.how = SIG_BLOCK;
  277                         sa.set = &mask;
  278                         sa.oset = NULL;
  279                         return sigprocmask(td, &sa);
  280                 }
  281                 
  282         case IBCS2_SIGNAL_MASK:
  283                 {
  284                         struct sigaction_args sa_args;
  285                         struct sigaction *nbsa, *obsa;
  286 
  287                         /* do not automatically block signal */
  288                         sa.sa_flags = SA_NODEFER;
  289 #ifdef SA_RESETHAND
  290                         if((signum != IBCS2_SIGILL) &&
  291                            (signum != IBCS2_SIGTRAP) &&
  292                            (signum != IBCS2_SIGPWR))
  293                                 /* set to SIG_DFL before executing handler */
  294                                 sa.sa_flags |= SA_RESETHAND;
  295 #endif
  296                 ibcs2_sigset:
  297                         nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  298                         obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  299                         sa_args.sig = signum;
  300                         sa_args.act = nbsa;
  301                         sa_args.oact = obsa;
  302 
  303                         sa.sa_handler = uap->fp;
  304                         sigemptyset(&sa.sa_mask);
  305 #if 0
  306                         if (signum != SIGALRM)
  307                                 sa.sa_flags |= SA_RESTART;
  308 #endif
  309                         td->td_retval[0] = (int)IBCS2_SIG_ERR; /* init error return */
  310 
  311                         /* perform native sigaction() */
  312                         if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
  313                                 return error;
  314                         if ((error = sigaction(td, &sa_args)) != 0) {
  315                                 DPRINTF(("signal: sigaction failed: %d\n",
  316                                          error));
  317                                 return error;
  318                         }
  319                         if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
  320                                 return error;
  321                         td->td_retval[0] = (int)sa.sa_handler;
  322 
  323                         /* special sigset() check */
  324                         if(IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK) {
  325                                 PROC_LOCK(p);
  326                                 /* check to make sure signal is not blocked */
  327                                 if(sigismember(&p->p_sigmask, signum)) {
  328                                         /* return SIG_HOLD and unblock signal*/
  329                                         td->td_retval[0] = (int)IBCS2_SIG_HOLD;
  330                                         SIGDELSET(p->p_sigmask, signum);
  331                                         signotify(p);
  332                                 }
  333                                 PROC_UNLOCK(p);
  334                         }
  335                                 
  336                         return 0;
  337                 }
  338                 
  339         case IBCS2_SIGRELSE_MASK:
  340                 {
  341                         sigset_t mask;
  342                         struct sigprocmask_args sa;
  343 
  344                         SIGEMPTYSET(mask);
  345                         SIGADDSET(mask, signum);
  346                         sa.how = SIG_UNBLOCK;
  347                         sa.set = &mask;
  348                         sa.oset = NULL;
  349                         return sigprocmask(td, &sa);
  350                 }
  351                 
  352         case IBCS2_SIGIGNORE_MASK:
  353                 {
  354                         struct sigaction_args sa_args;
  355                         struct sigaction *bsa;
  356 
  357                         bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  358                         sa_args.sig = signum;
  359                         sa_args.act = bsa;
  360                         sa_args.oact = NULL;
  361 
  362                         sa.sa_handler = SIG_IGN;
  363                         sigemptyset(&sa.sa_mask);
  364                         sa.sa_flags = 0;
  365                         if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
  366                                 return error;
  367                         if ((error = sigaction(td, &sa_args)) != 0) {
  368                                 DPRINTF(("sigignore: sigaction failed\n"));
  369                                 return error;
  370                         }
  371                         return 0;
  372                 }
  373                 
  374         case IBCS2_SIGPAUSE_MASK:
  375                 {
  376                         sigset_t mask;
  377                         struct sigsuspend_args sa;
  378 
  379                         PROC_LOCK(p);
  380                         mask = p->p_sigmask;
  381                         PROC_UNLOCK(p);
  382                         SIGDELSET(mask, signum);
  383                         sa.sigmask = &mask;
  384                         return sigsuspend(td, &sa);
  385                 }
  386                 
  387         default:
  388                 return ENOSYS;
  389         }
  390 }
  391 
  392 int
  393 ibcs2_sigprocmask(td, uap)
  394         register struct thread *td;
  395         struct ibcs2_sigprocmask_args *uap;
  396 {
  397         struct proc *p = td->td_proc;
  398         ibcs2_sigset_t iss;
  399         sigset_t bss;
  400         int error = 0;
  401 
  402         if (uap->oset != NULL) {
  403                 /* Fix the return value first if needed */
  404                 PROC_LOCK(p);
  405                 bsd_to_ibcs2_sigset(&p->p_sigmask, &iss);
  406                 PROC_UNLOCK(p);
  407                 if ((error = copyout(&iss, uap->oset, sizeof(iss))) != 0)
  408                         return error;
  409         }
  410                 
  411         if (uap->set == NULL)
  412                 /* Just examine */
  413                 return 0;
  414 
  415         if ((error = copyin(uap->set, &iss, sizeof(iss))) != 0)
  416                 return error;
  417 
  418         ibcs2_to_bsd_sigset(&iss, &bss);
  419 
  420         PROC_LOCK(p);
  421 
  422         switch (uap->how) {
  423         case IBCS2_SIG_BLOCK:
  424                 SIGSETOR(p->p_sigmask, bss);
  425                 SIG_CANTMASK(p->p_sigmask);
  426                 break;
  427 
  428         case IBCS2_SIG_UNBLOCK:
  429                 SIGSETNAND(p->p_sigmask, bss);
  430                 signotify(p);
  431                 break;
  432 
  433         case IBCS2_SIG_SETMASK:
  434                 p->p_sigmask = bss;
  435                 SIG_CANTMASK(p->p_sigmask);
  436                 signotify(p);
  437                 break;
  438 
  439         default:
  440                 error = EINVAL;
  441                 break;
  442         }
  443 
  444         PROC_UNLOCK(p);
  445 
  446         return error;
  447 }
  448 
  449 int
  450 ibcs2_sigpending(td, uap)
  451         register struct thread *td;
  452         struct ibcs2_sigpending_args *uap;
  453 {
  454         struct proc *p = td->td_proc;
  455         sigset_t bss;
  456         ibcs2_sigset_t iss;
  457 
  458         PROC_LOCK(p);
  459         bss = p->p_siglist;
  460         SIGSETAND(bss, p->p_sigmask);
  461         PROC_UNLOCK(p);
  462         bsd_to_ibcs2_sigset(&bss, &iss);
  463 
  464         return copyout(&iss, uap->mask, sizeof(iss));
  465 }
  466 
  467 int
  468 ibcs2_sigsuspend(td, uap)
  469         register struct thread *td;
  470         struct ibcs2_sigsuspend_args *uap;
  471 {
  472         ibcs2_sigset_t sss;
  473         sigset_t bss;
  474         struct sigsuspend_args sa;
  475         int error;
  476 
  477         if ((error = copyin(uap->mask, &sss, sizeof(sss))) != 0)
  478                 return error;
  479 
  480         ibcs2_to_bsd_sigset(&sss, &bss);
  481         sa.sigmask = &bss;
  482         return sigsuspend(td, &sa);
  483 }
  484 
  485 int
  486 ibcs2_pause(td, uap)
  487         register struct thread *td;
  488         struct ibcs2_pause_args *uap;
  489 {
  490         struct proc *p = td->td_proc;
  491         sigset_t mask;
  492         struct sigsuspend_args sa;
  493 
  494         PROC_LOCK(p);
  495         mask = td->td_proc->p_sigmask;
  496         PROC_UNLOCK(p);
  497         sa.sigmask = &mask;
  498         return sigsuspend(td, &sa);
  499 }
  500 
  501 int
  502 ibcs2_kill(td, uap)
  503         register struct thread *td;
  504         struct ibcs2_kill_args *uap;
  505 {
  506         struct kill_args ka;
  507 
  508         ka.pid = uap->pid;
  509         ka.signum = ibcs2_to_bsd_sig[_SIG_IDX(uap->signo)];
  510         return kill(td, &ka);
  511 }

Cache object: 48b8abd4d8ff49f8c8c99934fcbc9faa


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.