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/linux/linux_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) 1994-1995 Søren Schmidt
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer 
   10  *    in this position and unchanged.
   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 withough 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/lock.h>
   34 #include <sys/proc.h>
   35 #include <sys/signalvar.h>
   36 #include <sys/sysproto.h>
   37 
   38 #include <machine/../linux/linux.h>
   39 #include <machine/../linux/linux_proto.h>
   40 #include <compat/linux/linux_signal.h>
   41 #include <compat/linux/linux_util.h>
   42 
   43 void
   44 linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
   45 {
   46         int b, l;
   47 
   48         SIGEMPTYSET(*bss);
   49         bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
   50         bss->__bits[1] = lss->__bits[1];
   51         for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
   52                 if (LINUX_SIGISMEMBER(*lss, l)) {
   53 #ifdef __alpha__
   54                         b = _SIG_IDX(l);
   55 #else
   56                         b = linux_to_bsd_signal[_SIG_IDX(l)];
   57 #endif
   58                         if (b)
   59                                 SIGADDSET(*bss, b);
   60                 }
   61         }
   62 }
   63 
   64 void
   65 bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
   66 {
   67         int b, l;
   68 
   69         LINUX_SIGEMPTYSET(*lss);
   70         lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
   71         lss->__bits[1] = bss->__bits[1];
   72         for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
   73                 if (SIGISMEMBER(*bss, b)) {
   74 #if __alpha__
   75                         l = _SIG_IDX(b);
   76 #else
   77                         l = bsd_to_linux_signal[_SIG_IDX(b)];
   78 #endif
   79                         if (l)
   80                                 LINUX_SIGADDSET(*lss, l);
   81                 }
   82         }
   83 }
   84 
   85 static void
   86 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
   87 {
   88 
   89         linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
   90         bsa->sa_handler = lsa->lsa_handler;
   91         bsa->sa_flags = 0;
   92         if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)
   93                 bsa->sa_flags |= SA_NOCLDSTOP;
   94         if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT)
   95                 bsa->sa_flags |= SA_NOCLDWAIT;
   96         if (lsa->lsa_flags & LINUX_SA_SIGINFO)
   97                 bsa->sa_flags |= SA_SIGINFO;
   98         if (lsa->lsa_flags & LINUX_SA_ONSTACK)
   99                 bsa->sa_flags |= SA_ONSTACK;
  100         if (lsa->lsa_flags & LINUX_SA_RESTART)
  101                 bsa->sa_flags |= SA_RESTART;
  102         if (lsa->lsa_flags & LINUX_SA_ONESHOT)
  103                 bsa->sa_flags |= SA_RESETHAND;
  104         if (lsa->lsa_flags & LINUX_SA_NOMASK)
  105                 bsa->sa_flags |= SA_NODEFER;
  106 }
  107 
  108 static void
  109 bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
  110 {
  111 
  112         bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
  113         lsa->lsa_handler = bsa->sa_handler;
  114         lsa->lsa_restorer = NULL;       /* unsupported */
  115         lsa->lsa_flags = 0;
  116         if (bsa->sa_flags & SA_NOCLDSTOP)
  117                 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
  118         if (bsa->sa_flags & SA_NOCLDWAIT)
  119                 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
  120         if (bsa->sa_flags & SA_SIGINFO)
  121                 lsa->lsa_flags |= LINUX_SA_SIGINFO;
  122         if (bsa->sa_flags & SA_ONSTACK)
  123                 lsa->lsa_flags |= LINUX_SA_ONSTACK;
  124         if (bsa->sa_flags & SA_RESTART)
  125                 lsa->lsa_flags |= LINUX_SA_RESTART;
  126         if (bsa->sa_flags & SA_RESETHAND)
  127                 lsa->lsa_flags |= LINUX_SA_ONESHOT;
  128         if (bsa->sa_flags & SA_NODEFER)
  129                 lsa->lsa_flags |= LINUX_SA_NOMASK;
  130 }
  131 
  132 int
  133 linux_do_sigaction(struct proc *p, int linux_sig, l_sigaction_t *linux_nsa,
  134                    l_sigaction_t *linux_osa)
  135 {
  136         struct sigaction *nsa, *osa;
  137         struct sigaction_args sa_args;
  138         int error;
  139         caddr_t sg = stackgap_init();
  140 
  141         if (linux_sig <= 0 || linux_sig > LINUX_NSIG)
  142                 return (EINVAL);
  143 
  144         if (linux_osa != NULL)
  145                 osa = stackgap_alloc(&sg, sizeof(struct sigaction));
  146         else
  147                 osa = NULL;
  148 
  149         if (linux_nsa != NULL) {
  150                 nsa = stackgap_alloc(&sg, sizeof(struct sigaction));
  151                 linux_to_bsd_sigaction(linux_nsa, nsa);
  152         }
  153         else
  154                 nsa = NULL;
  155 
  156 #ifndef __alpha__
  157         if (linux_sig <= LINUX_SIGTBLSZ)
  158                 sa_args.sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
  159         else
  160 #endif
  161                 sa_args.sig = linux_sig;
  162 
  163         sa_args.act = nsa;
  164         sa_args.oact = osa;
  165         error = sigaction(p, &sa_args);
  166         if (error)
  167                 return (error);
  168 
  169         if (linux_osa != NULL)
  170                 bsd_to_linux_sigaction(osa, linux_osa);
  171 
  172         return (0);
  173 }
  174 
  175 
  176 #ifndef __alpha__
  177 int
  178 linux_signal(struct proc *p, struct linux_signal_args *args)
  179 {
  180         l_sigaction_t nsa, osa;
  181         int error;
  182 
  183 #ifdef DEBUG
  184         if (ldebug(signal))
  185                 printf(ARGS(signal, "%d, %p"),
  186                     args->sig, (void *)args->handler);
  187 #endif
  188 
  189         nsa.lsa_handler = args->handler;
  190         nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
  191         LINUX_SIGEMPTYSET(nsa.lsa_mask);
  192 
  193         error = linux_do_sigaction(p, args->sig, &nsa, &osa);
  194         p->p_retval[0] = (int)osa.lsa_handler;
  195 
  196         return (error);
  197 }
  198 #endif  /*!__alpha__*/
  199 
  200 int
  201 linux_rt_sigaction(struct proc *p, struct linux_rt_sigaction_args *args)
  202 {
  203         l_sigaction_t nsa, osa;
  204         int error;
  205 
  206 #ifdef DEBUG
  207         if (ldebug(rt_sigaction))
  208                 printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"),
  209                     (long)args->sig, (void *)args->act,
  210                     (void *)args->oact, (long)args->sigsetsize);
  211 #endif
  212 
  213         if (args->sigsetsize != sizeof(l_sigset_t))
  214                 return (EINVAL);
  215 
  216         if (args->act != NULL) {
  217                 error = copyin(args->act, &nsa, sizeof(l_sigaction_t));
  218                 if (error)
  219                         return (error);
  220         }
  221 
  222         error = linux_do_sigaction(p, args->sig,
  223                                    args->act ? &nsa : NULL,
  224                                    args->oact ? &osa : NULL);
  225 
  226         if (args->oact != NULL && !error) {
  227                 error = copyout(&osa, args->oact, sizeof(l_sigaction_t));
  228         }
  229 
  230         return (error);
  231 }
  232 
  233 static int
  234 linux_do_sigprocmask(struct proc *p, int how, l_sigset_t *new,
  235                      l_sigset_t *old)
  236 {
  237         int error;
  238         sigset_t mask;
  239 
  240         error = 0;
  241         p->p_retval[0] = 0;
  242 
  243         if (old != NULL)
  244                 bsd_to_linux_sigset(&p->p_sigmask, old);
  245 
  246         if (new != NULL) {
  247                 linux_to_bsd_sigset(new, &mask);
  248 
  249                 switch (how) {
  250                 case LINUX_SIG_BLOCK:
  251                         SIGSETOR(p->p_sigmask, mask);
  252                         SIG_CANTMASK(p->p_sigmask);
  253                         break;
  254                 case LINUX_SIG_UNBLOCK:
  255                         SIGSETNAND(p->p_sigmask, mask);
  256                         break;
  257                 case LINUX_SIG_SETMASK:
  258                         p->p_sigmask = mask;
  259                         SIG_CANTMASK(p->p_sigmask);
  260                         break;
  261                 default:
  262                         error = EINVAL;
  263                         break;
  264                 }
  265         }
  266 
  267         return (error);
  268 }
  269 
  270 #ifndef __alpha__
  271 int
  272 linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args)
  273 {
  274         l_osigset_t mask;
  275         l_sigset_t set, oset;
  276         int error;
  277 
  278 #ifdef DEBUG
  279         if (ldebug(sigprocmask))
  280                 printf(ARGS(sigprocmask, "%d, *, *"), args->how);
  281 #endif
  282 
  283         if (args->mask != NULL) {
  284                 error = copyin(args->mask, &mask, sizeof(l_osigset_t));
  285                 if (error)
  286                         return (error);
  287                 LINUX_SIGEMPTYSET(set);
  288                 set.__bits[0] = mask;
  289         }
  290 
  291         error = linux_do_sigprocmask(p, args->how,
  292                                      args->mask ? &set : NULL,
  293                                      args->omask ? &oset : NULL);
  294 
  295         if (args->omask != NULL && !error) {
  296                 mask = oset.__bits[0];
  297                 error = copyout(&mask, args->omask, sizeof(l_osigset_t));
  298         }
  299 
  300         return (error);
  301 }
  302 #endif  /*!__alpha__*/
  303 
  304 int
  305 linux_rt_sigprocmask(struct proc *p, struct linux_rt_sigprocmask_args *args)
  306 {
  307         l_sigset_t set, oset;
  308         int error;
  309 
  310 #ifdef DEBUG
  311         if (ldebug(rt_sigprocmask))
  312                 printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"),
  313                     args->how, (void *)args->mask,
  314                     (void *)args->omask, (long)args->sigsetsize);
  315 #endif
  316 
  317         if (args->sigsetsize != sizeof(l_sigset_t))
  318                 return EINVAL;
  319 
  320         if (args->mask != NULL) {
  321                 error = copyin(args->mask, &set, sizeof(l_sigset_t));
  322                 if (error)
  323                         return (error);
  324         }
  325 
  326         error = linux_do_sigprocmask(p, args->how,
  327                                      args->mask ? &set : NULL,
  328                                      args->omask ? &oset : NULL);
  329 
  330         if (args->omask != NULL && !error) {
  331                 error = copyout(&oset, args->omask, sizeof(l_sigset_t));
  332         }
  333 
  334         return (error);
  335 }
  336 
  337 #ifndef __alpha__
  338 int
  339 linux_sgetmask(struct proc *p, struct linux_sgetmask_args *args)
  340 {
  341         l_sigset_t mask;
  342 
  343 #ifdef DEBUG
  344         if (ldebug(sgetmask))
  345                 printf(ARGS(sgetmask, ""));
  346 #endif
  347 
  348         bsd_to_linux_sigset(&p->p_sigmask, &mask);
  349         p->p_retval[0] = mask.__bits[0];
  350         return (0);
  351 }
  352 
  353 int
  354 linux_ssetmask(struct proc *p, struct linux_ssetmask_args *args)
  355 {
  356         l_sigset_t lset;
  357         sigset_t bset;
  358 
  359 #ifdef DEBUG
  360         if (ldebug(ssetmask))
  361                 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
  362 #endif
  363 
  364         bsd_to_linux_sigset(&p->p_sigmask, &lset);
  365         p->p_retval[0] = lset.__bits[0];
  366         LINUX_SIGEMPTYSET(lset);
  367         lset.__bits[0] = args->mask;
  368         linux_to_bsd_sigset(&lset, &bset);
  369         p->p_sigmask = bset;
  370         SIG_CANTMASK(p->p_sigmask);
  371         return (0);
  372 }
  373 
  374 int
  375 linux_sigpending(struct proc *p, struct linux_sigpending_args *args)
  376 {
  377         sigset_t bset;
  378         l_sigset_t lset;
  379         l_osigset_t mask;
  380 
  381 #ifdef DEBUG
  382         if (ldebug(sigpending))
  383                 printf(ARGS(sigpending, "*"));
  384 #endif
  385 
  386         bset = p->p_siglist;
  387         SIGSETAND(bset, p->p_sigmask);
  388         bsd_to_linux_sigset(&bset, &lset);
  389         mask = lset.__bits[0];
  390         return (copyout(&mask, args->mask, sizeof(mask)));
  391 }
  392 #endif  /*!__alpha__*/
  393 
  394 int
  395 linux_kill(struct proc *p, struct linux_kill_args *args)
  396 {
  397         struct kill_args /* {
  398             int pid;
  399             int signum;
  400         } */ tmp;
  401 
  402 #ifdef DEBUG
  403         if (ldebug(kill))
  404                 printf(ARGS(kill, "%d, %d"), args->pid, args->signum);
  405 #endif
  406 
  407         /*
  408          * Allow signal 0 as a means to check for privileges
  409          */
  410         if (args->signum < 0 || args->signum > LINUX_NSIG)
  411                 return EINVAL;
  412 
  413 #ifndef __alpha__
  414         if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
  415                 tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
  416         else
  417 #endif
  418                 tmp.signum = args->signum;
  419 
  420         tmp.pid = args->pid;
  421         return (kill(p, &tmp));
  422 }

Cache object: e762c6a2dab4c5d21374058c2da7bb18


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