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/compat/svr4/svr4_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 /*      $NetBSD: svr4_signal.c,v 1.64.10.1 2011/02/16 21:22:44 bouyer Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 1994, 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas and by Charles M. Hannum.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: svr4_signal.c,v 1.64.10.1 2011/02/16 21:22:44 bouyer Exp $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/namei.h>
   38 #include <sys/proc.h>
   39 #include <sys/filedesc.h>
   40 #include <sys/ioctl.h>
   41 #include <sys/mount.h>
   42 #include <sys/kernel.h>
   43 #include <sys/signal.h>
   44 #include <sys/signalvar.h>
   45 #include <sys/malloc.h>
   46 #include <sys/wait.h>
   47 
   48 #include <sys/syscallargs.h>
   49 
   50 #include <uvm/uvm_extern.h>
   51 
   52 #include <compat/svr4/svr4_types.h>
   53 #include <compat/svr4/svr4_signal.h>
   54 #include <compat/svr4/svr4_lwp.h>
   55 #include <compat/svr4/svr4_ucontext.h>
   56 #include <compat/svr4/svr4_syscallargs.h>
   57 #include <compat/svr4/svr4_util.h>
   58 
   59 #include <compat/common/compat_sigaltstack.h>
   60 
   61 #define svr4_sigmask(n)         (1 << (((n) - 1) & 31))
   62 #define svr4_sigword(n)         (((n) - 1) >> 5)
   63 #define svr4_sigemptyset(s)     memset((s), 0, sizeof(*(s)))
   64 #define svr4_sigismember(s, n)  ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
   65 #define svr4_sigaddset(s, n)    ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
   66 
   67 static inline void svr4_sigfillset(svr4_sigset_t *);
   68 void svr4_to_native_sigaction(const struct svr4_sigaction *,
   69                                 struct sigaction *);
   70 void native_to_svr4_sigaction(const struct sigaction *,
   71                                 struct svr4_sigaction *);
   72 
   73 extern const int native_to_svr4_signo[];
   74 extern const int svr4_to_native_signo[];
   75 
   76 static inline void
   77 svr4_sigfillset(svr4_sigset_t *s)
   78 {
   79         int i;
   80 
   81         svr4_sigemptyset(s);
   82         for (i = 1; i < SVR4_NSIG; i++)
   83                 if (svr4_to_native_signo[i] != 0)
   84                         svr4_sigaddset(s, i);
   85 }
   86 
   87 void
   88 svr4_to_native_sigset(const svr4_sigset_t *sss, sigset_t *bss)
   89 {
   90         int i, newsig;
   91 
   92         sigemptyset(bss);
   93         for (i = 1; i < SVR4_NSIG; i++) {
   94                 if (svr4_sigismember(sss, i)) {
   95                         newsig = svr4_to_native_signo[i];
   96                         if (newsig)
   97                                 sigaddset(bss, newsig);
   98                 }
   99         }
  100 }
  101 
  102 
  103 void
  104 native_to_svr4_sigset(const sigset_t *bss, svr4_sigset_t *sss)
  105 {
  106         int i, newsig;
  107 
  108         svr4_sigemptyset(sss);
  109         for (i = 1; i < NSIG; i++) {
  110                 if (sigismember(bss, i)) {
  111                         newsig = native_to_svr4_signo[i];
  112                         if (newsig)
  113                                 svr4_sigaddset(sss, newsig);
  114                 }
  115         }
  116 }
  117 
  118 /*
  119  * XXX: Only a subset of the flags is currently implemented.
  120  */
  121 void
  122 svr4_to_native_sigaction(const struct svr4_sigaction *ssa, struct sigaction *bsa)
  123 {
  124 
  125         bsa->sa_handler = (sig_t) ssa->svr4_sa_handler;
  126         svr4_to_native_sigset(&ssa->svr4_sa_mask, &bsa->sa_mask);
  127         bsa->sa_flags = 0;
  128         if ((ssa->svr4_sa_flags & SVR4_SA_ONSTACK) != 0)
  129                 bsa->sa_flags |= SA_ONSTACK;
  130         if ((ssa->svr4_sa_flags & SVR4_SA_RESETHAND) != 0)
  131                 bsa->sa_flags |= SA_RESETHAND;
  132         if ((ssa->svr4_sa_flags & SVR4_SA_RESTART) != 0)
  133                 bsa->sa_flags |= SA_RESTART;
  134         if ((ssa->svr4_sa_flags & SVR4_SA_SIGINFO) != 0)
  135                 bsa->sa_flags |= SA_SIGINFO;
  136         if ((ssa->svr4_sa_flags & SVR4_SA_NODEFER) != 0)
  137                 bsa->sa_flags |= SA_NODEFER;
  138         if ((ssa->svr4_sa_flags & SVR4_SA_NOCLDWAIT) != 0)
  139                 bsa->sa_flags |= SA_NOCLDWAIT;
  140         if ((ssa->svr4_sa_flags & SVR4_SA_NOCLDSTOP) != 0)
  141                 bsa->sa_flags |= SA_NOCLDSTOP;
  142         if ((ssa->svr4_sa_flags & ~SVR4_SA_ALLBITS) != 0) {
  143                 DPRINTF(("svr4_to_native_sigaction: extra bits %x ignored\n",
  144                     ssa->svr4_sa_flags & ~SVR4_SA_ALLBITS));
  145         }
  146 }
  147 
  148 void
  149 native_to_svr4_sigaction(const struct sigaction *bsa, struct svr4_sigaction *ssa)
  150 {
  151 
  152         ssa->svr4_sa_handler = (svr4_sig_t) bsa->sa_handler;
  153         native_to_svr4_sigset(&bsa->sa_mask, &ssa->svr4_sa_mask);
  154         ssa->svr4_sa_flags = 0;
  155         if ((bsa->sa_flags & SA_ONSTACK) != 0)
  156                 ssa->svr4_sa_flags |= SVR4_SA_ONSTACK;
  157         if ((bsa->sa_flags & SA_RESETHAND) != 0)
  158                 ssa->svr4_sa_flags |= SVR4_SA_RESETHAND;
  159         if ((bsa->sa_flags & SA_RESTART) != 0)
  160                 ssa->svr4_sa_flags |= SVR4_SA_RESTART;
  161         if ((bsa->sa_flags & SA_NODEFER) != 0)
  162                 ssa->svr4_sa_flags |= SVR4_SA_NODEFER;
  163         if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
  164                 ssa->svr4_sa_flags |= SVR4_SA_NOCLDSTOP;
  165 }
  166 
  167 int
  168 svr4_sys_sigaction(struct lwp *l, const struct svr4_sys_sigaction_args *uap, register_t *retval)
  169 {
  170         /* {
  171                 syscallarg(int) signum;
  172                 syscallarg(const struct svr4_sigaction *) nsa;
  173                 syscallarg(struct svr4_sigaction *) osa;
  174         } */
  175         struct svr4_sigaction nssa, ossa;
  176         struct sigaction nbsa, obsa;
  177         int error;
  178 
  179         if (SCARG(uap, nsa)) {
  180                 error = copyin(SCARG(uap, nsa), &nssa, sizeof(nssa));
  181                 if (error)
  182                         return (error);
  183                 svr4_to_native_sigaction(&nssa, &nbsa);
  184         }
  185         error = sigaction1(l, svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))],
  186             SCARG(uap, nsa) ? &nbsa : 0, SCARG(uap, osa) ? &obsa : 0,
  187             NULL, 0);
  188         if (error)
  189                 return (error);
  190         if (SCARG(uap, osa)) {
  191                 native_to_svr4_sigaction(&obsa, &ossa);
  192                 error = copyout(&ossa, SCARG(uap, osa), sizeof(ossa));
  193                 if (error)
  194                         return (error);
  195         }
  196         return (0);
  197 }
  198 
  199 int
  200 svr4_sys_sigaltstack(struct lwp *l, const struct svr4_sys_sigaltstack_args *uap, register_t *retval)
  201 {
  202         /* {
  203                 syscallarg(const struct svr4_sigaltstack *) nss;
  204                 syscallarg(struct svr4_sigaltstack *) oss;
  205         } */
  206         compat_sigaltstack(uap, svr4_sigaltstack,
  207             SVR4_SS_ONSTACK, SVR4_SS_DISABLE);
  208 }
  209 
  210 /*
  211  * Stolen from the ibcs2 one
  212  */
  213 int
  214 svr4_sys_signal(struct lwp *l, const struct svr4_sys_signal_args *uap, register_t *retval)
  215 {
  216         /* {
  217                 syscallarg(int) signum;
  218                 syscallarg(svr4_sig_t) handler;
  219         } */
  220         int signum = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
  221         struct proc *p = l->l_proc;
  222         struct sigaction nbsa, obsa;
  223         sigset_t ss;
  224         int error;
  225 
  226         if (signum <= 0 || signum >= SVR4_NSIG)
  227                 return (EINVAL);
  228 
  229         switch (SVR4_SIGCALL(SCARG(uap, signum))) {
  230         case SVR4_SIGDEFER_MASK:
  231                 if (SCARG(uap, handler) == SVR4_SIG_HOLD)
  232                         goto sighold;
  233                 /* FALLTHROUGH */
  234 
  235         case SVR4_SIGNAL_MASK:
  236                 nbsa.sa_handler = (sig_t)SCARG(uap, handler);
  237                 sigemptyset(&nbsa.sa_mask);
  238                 nbsa.sa_flags = 0;
  239                 error = sigaction1(l, signum, &nbsa, &obsa, NULL, 0);
  240                 if (error)
  241                         return (error);
  242                 *retval = (u_int)(u_long)obsa.sa_handler;
  243                 return (0);
  244 
  245         case SVR4_SIGHOLD_MASK:
  246         sighold:
  247                 sigemptyset(&ss);
  248                 sigaddset(&ss, signum);
  249                 mutex_enter(p->p_lock);
  250                 error = sigprocmask1(l, SIG_BLOCK, &ss, 0);
  251                 mutex_exit(p->p_lock);
  252                 return error;
  253 
  254         case SVR4_SIGRELSE_MASK:
  255                 sigemptyset(&ss);
  256                 sigaddset(&ss, signum);
  257                 mutex_enter(p->p_lock);
  258                 error = sigprocmask1(l, SIG_UNBLOCK, &ss, 0);
  259                 mutex_exit(p->p_lock);
  260                 return error;
  261 
  262         case SVR4_SIGIGNORE_MASK:
  263                 nbsa.sa_handler = SIG_IGN;
  264                 sigemptyset(&nbsa.sa_mask);
  265                 nbsa.sa_flags = 0;
  266                 return (sigaction1(l, signum, &nbsa, 0, NULL, 0));
  267 
  268         case SVR4_SIGPAUSE_MASK:
  269                 ss = l->l_sigmask;      /* XXXAD locking */
  270                 sigdelset(&ss, signum);
  271                 return (sigsuspend1(l, &ss));
  272 
  273         default:
  274                 return (ENOSYS);
  275         }
  276 }
  277 
  278 int
  279 svr4_sys_sigprocmask(struct lwp *l, const struct svr4_sys_sigprocmask_args *uap, register_t *retval)
  280 {
  281         /* {
  282                 syscallarg(int) how;
  283                 syscallarg(const svr4_sigset_t *) set;
  284                 syscallarg(svr4_sigset_t *) oset;
  285         } */
  286         struct proc *p = l->l_proc;
  287         svr4_sigset_t nsss, osss;
  288         sigset_t nbss, obss;
  289         int how;
  290         int error;
  291 
  292         /*
  293          * Initialize how to 0 to avoid a compiler warning.  Note that
  294          * this is safe because of the check in the default: case.
  295          */
  296         how = 0;
  297 
  298         switch (SCARG(uap, how)) {
  299         case SVR4_SIG_BLOCK:
  300                 how = SIG_BLOCK;
  301                 break;
  302         case SVR4_SIG_UNBLOCK:
  303                 how = SIG_UNBLOCK;
  304                 break;
  305         case SVR4_SIG_SETMASK:
  306                 how = SIG_SETMASK;
  307                 break;
  308         default:
  309                 if (SCARG(uap, set))
  310                         return EINVAL;
  311                 break;
  312         }
  313 
  314         if (SCARG(uap, set)) {
  315                 error = copyin(SCARG(uap, set), &nsss, sizeof(nsss));
  316                 if (error)
  317                         return error;
  318                 svr4_to_native_sigset(&nsss, &nbss);
  319         }
  320         mutex_enter(p->p_lock);
  321         error = sigprocmask1(l, how,
  322             SCARG(uap, set) ? &nbss : NULL, SCARG(uap, oset) ? &obss : NULL);
  323         mutex_exit(p->p_lock);
  324         if (error)
  325                 return error;
  326         if (SCARG(uap, oset)) {
  327                 native_to_svr4_sigset(&obss, &osss);
  328                 error = copyout(&osss, SCARG(uap, oset), sizeof(osss));
  329                 if (error)
  330                         return error;
  331         }
  332         return 0;
  333 }
  334 
  335 int
  336 svr4_sys_sigpending(struct lwp *l, const struct svr4_sys_sigpending_args *uap, register_t *retval)
  337 {
  338         /* {
  339                 syscallarg(int) what;
  340                 syscallarg(svr4_sigset_t *) set;
  341         } */
  342         sigset_t bss;
  343         svr4_sigset_t sss;
  344 
  345         switch (SCARG(uap, what)) {
  346         case 1: /* sigpending */
  347                 sigpending1(l, &bss);
  348                 native_to_svr4_sigset(&bss, &sss);
  349                 break;
  350 
  351         case 2: /* sigfillset */
  352                 svr4_sigfillset(&sss);
  353                 break;
  354 
  355         default:
  356                 return (EINVAL);
  357         }
  358         return (copyout(&sss, SCARG(uap, set), sizeof(sss)));
  359 }
  360 
  361 int
  362 svr4_sys_sigsuspend(struct lwp *l, const struct svr4_sys_sigsuspend_args *uap, register_t *retval)
  363 {
  364         /* {
  365                 syscallarg(const svr4_sigset_t *) set;
  366         } */
  367         svr4_sigset_t sss;
  368         sigset_t bss;
  369         int error;
  370 
  371         if (SCARG(uap, set)) {
  372                 error = copyin(SCARG(uap, set), &sss, sizeof(sss));
  373                 if (error)
  374                         return (error);
  375                 svr4_to_native_sigset(&sss, &bss);
  376         }
  377 
  378         return (sigsuspend1(l, SCARG(uap, set) ? &bss : 0));
  379 }
  380 
  381 int
  382 svr4_sys_pause(struct lwp *l, const void *v, register_t *retval)
  383 {
  384 
  385         return (sigsuspend1(l, 0));
  386 }
  387 
  388 int
  389 svr4_sys_kill(struct lwp *l, const struct svr4_sys_kill_args *uap, register_t *retval)
  390 {
  391         /* {
  392                 syscallarg(int) pid;
  393                 syscallarg(int) signum;
  394         } */
  395         struct sys_kill_args ka;
  396 
  397         SCARG(&ka, pid) = SCARG(uap, pid);
  398         SCARG(&ka, signum) = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
  399         return sys_kill(l, &ka, retval);
  400 }
  401 
  402 void
  403 svr4_getcontext(struct lwp *l, struct svr4_ucontext *uc)
  404 {
  405         sigset_t mask;
  406         struct proc *p = l->l_proc;
  407 
  408         svr4_getmcontext(l, &uc->uc_mcontext, &uc->uc_flags);
  409         uc->uc_link = l->l_ctxlink;
  410 
  411         /*
  412          * The (unsupplied) definition of the `current execution stack'
  413          * in the System V Interface Definition appears to allow returning
  414          * the main context stack.
  415          */
  416         if ((l->l_sigstk.ss_flags & SS_ONSTACK) == 0) {
  417                 uc->uc_stack.ss_sp = (void *)USRSTACK;
  418                 uc->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize);
  419                 uc->uc_stack.ss_flags = 0;      /* XXX, def. is Very Fishy */
  420         } else {
  421                 /* Simply copy alternate signal execution stack. */
  422                 uc->uc_stack.ss_sp = l->l_sigstk.ss_sp;
  423                 uc->uc_stack.ss_size = l->l_sigstk.ss_size;
  424                 uc->uc_stack.ss_flags = l->l_sigstk.ss_flags;
  425         }
  426         (void)sigprocmask1(l, 0, NULL, &mask);
  427 
  428         native_to_svr4_sigset(&mask, &uc->uc_sigmask);
  429         uc->uc_flags |= _UC_SIGMASK | _UC_STACK;
  430 }
  431 
  432 
  433 int
  434 svr4_setcontext(struct lwp *l, struct svr4_ucontext *uc)
  435 {
  436         struct proc *p = l->l_proc;
  437         sigset_t mask;
  438 
  439         if (uc->uc_flags & _UC_SIGMASK) {
  440                 svr4_to_native_sigset(&uc->uc_sigmask, &mask);
  441                 mutex_enter(p->p_lock);
  442                 sigprocmask1(l, SIG_SETMASK, &mask, NULL);
  443                 mutex_exit(p->p_lock);
  444         }
  445 
  446         /* Ignore the stack; see comment in svr4_getcontext. */
  447 
  448         l->l_ctxlink = uc->uc_link;
  449         svr4_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
  450 
  451         return EJUSTRETURN;
  452 }
  453 
  454 int
  455 svr4_sys_context(struct lwp *l, const struct svr4_sys_context_args *uap, register_t *retval)
  456 {
  457         /* {
  458                 syscallarg(int) func;
  459                 syscallarg(struct svr4_ucontext *) uc;
  460         } */
  461         int error;
  462         svr4_ucontext_t uc;
  463         *retval = 0;
  464 
  465         memset(&uc, 0, sizeof(uc));
  466 
  467         switch (SCARG(uap, func)) {
  468         case SVR4_GETCONTEXT:
  469                 DPRINTF(("getcontext(%p)\n", SCARG(uap, uc)));
  470                 svr4_getcontext(l, &uc);
  471         return (copyout(&uc, SCARG(uap, uc), sizeof (*SCARG(uap, uc))));
  472 
  473 
  474         case SVR4_SETCONTEXT:
  475                 DPRINTF(("setcontext(%p)\n", SCARG(uap, uc)));
  476                 error = copyin(SCARG(uap, uc), &uc, sizeof (uc));
  477                 if (error)
  478                         return (error);
  479                 svr4_setcontext(l, &uc);
  480                 return EJUSTRETURN;
  481 
  482         default:
  483                 DPRINTF(("context(%d, %p)\n", SCARG(uap, func),
  484                     SCARG(uap, uc)));
  485                 return ENOSYS;
  486         }
  487 }

Cache object: 70d12d4bea6519d50a563cea4750d6ba


[ 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.