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

Cache object: f8acea54a87f60abd22b9493ad9ac83b


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