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

Cache object: 26499162f884f4b79c01a361afd4a221


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