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/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: src/sys/i386/linux/linux_signal.c,v 1.6.4.2 1999/09/05 08:14:17 peter Exp $
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/sysproto.h>
   34 #include <sys/proc.h>
   35 #include <sys/exec.h>
   36 #include <sys/signal.h>
   37 #include <sys/signalvar.h>
   38 
   39 #include <i386/linux/linux.h>
   40 #include <i386/linux/linux_proto.h>
   41 #include <i386/linux/linux_util.h>
   42 
   43 static sigset_t
   44 linux_to_bsd_sigset(linux_sigset_t mask) {
   45     int b, l;
   46     sigset_t new = 0;
   47 
   48     for (l = 1; l < LINUX_NSIG; l++) {
   49         if (mask & (1 << (l - 1))) {
   50             if ((b = linux_to_bsd_signal[l]))
   51                 new |= (1 << (b - 1));
   52         }
   53     }
   54     return new;
   55 }
   56 
   57 static linux_sigset_t
   58 bsd_to_linux_sigset(sigset_t mask) {
   59     int b, l;
   60     sigset_t new = 0;
   61 
   62     for (b = 1; b < NSIG; b++) {
   63         if (mask & (1 << (b - 1))) {
   64             if ((l = bsd_to_linux_signal[b]))
   65                 new |= (1 << (l - 1));
   66         }
   67     }
   68     return new;
   69 }
   70 
   71 static void
   72 linux_to_bsd_sigaction(linux_sigaction_t *lsa, struct sigaction *bsa)
   73 {
   74     bsa->sa_mask = linux_to_bsd_sigset(lsa->sa_mask);
   75     bsa->sa_handler = lsa->sa_handler;
   76     bsa->sa_flags = 0;
   77     if (lsa->sa_flags & LINUX_SA_NOCLDSTOP)
   78         bsa->sa_flags |= SA_NOCLDSTOP;
   79     if (lsa->sa_flags & LINUX_SA_ONSTACK)
   80         bsa->sa_flags |= SA_ONSTACK;
   81     if (lsa->sa_flags & LINUX_SA_RESTART)
   82         bsa->sa_flags |= SA_RESTART;
   83     if (lsa->sa_flags & LINUX_SA_ONESHOT)
   84         bsa->sa_flags |= SA_RESETHAND;
   85     if (lsa->sa_flags & LINUX_SA_NOMASK)
   86         bsa->sa_flags |= SA_NODEFER;
   87 }
   88 
   89 static void
   90 bsd_to_linux_sigaction(struct sigaction *bsa, linux_sigaction_t *lsa)
   91 {
   92     lsa->sa_handler = bsa->sa_handler;
   93     lsa->sa_restorer = NULL;    /* unsupported */
   94     lsa->sa_mask = bsd_to_linux_sigset(bsa->sa_mask);
   95     lsa->sa_flags = 0;
   96     if (bsa->sa_flags & SA_NOCLDSTOP)
   97         lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
   98     if (bsa->sa_flags & SA_ONSTACK)
   99         lsa->sa_flags |= LINUX_SA_ONSTACK;
  100     if (bsa->sa_flags & SA_RESTART)
  101         lsa->sa_flags |= LINUX_SA_RESTART;
  102     if (bsa->sa_flags & SA_RESETHAND)
  103         lsa->sa_flags |= LINUX_SA_ONESHOT;
  104     if (bsa->sa_flags & SA_NODEFER)
  105         lsa->sa_flags |= LINUX_SA_NOMASK;
  106 }
  107 
  108 int
  109 linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval)
  110 {
  111     linux_sigaction_t linux_sa;
  112     struct sigaction *nsa = NULL, *osa = NULL, bsd_sa;
  113     struct sigaction_args sa;
  114     int error;
  115     caddr_t sg = stackgap_init();
  116     
  117 #ifdef DEBUG
  118     printf("Linux-emul(%d): sigaction(%d, %08x, %08x)\n", p->p_pid, args->sig,
  119         args->nsa, args->osa);
  120 #endif
  121     if (args->sig <= 0 || args->sig >= LINUX_NSIG)
  122         return EINVAL;
  123     if (args->osa)
  124         osa = (struct sigaction *)stackgap_alloc(&sg, sizeof(struct sigaction));
  125 
  126     if (args->nsa) {
  127         nsa = (struct sigaction *)stackgap_alloc(&sg, sizeof(struct sigaction));
  128         if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t)))
  129             return error;
  130         linux_to_bsd_sigaction(&linux_sa, &bsd_sa);
  131         if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction)))
  132             return error;
  133     }
  134     sa.signum = linux_to_bsd_signal[args->sig];
  135     sa.nsa = nsa;
  136     sa.osa = osa;
  137     if ((error = sigaction(p, &sa, retval)))
  138         return error;
  139 
  140     if (args->osa) {
  141         if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction)))
  142             return error;
  143         bsd_to_linux_sigaction(&bsd_sa, &linux_sa);
  144         if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t)))
  145             return error;
  146     }
  147     return 0;
  148 }
  149 
  150 int
  151 linux_signal(struct proc *p, struct linux_signal_args *args, int *retval)
  152 {
  153     caddr_t sg;
  154     struct sigaction_args sa_args;
  155     struct sigaction *osa, *nsa, tmpsa;
  156     int error;
  157 
  158 #ifdef DEBUG
  159     printf("Linux-emul(%d): signal(%d, %08x)\n", p->p_pid,
  160             args->sig, args->handler);
  161 #endif
  162     if (args->sig <= 0 || args->sig >= LINUX_NSIG)
  163         return EINVAL;
  164     sg = stackgap_init();
  165     nsa = stackgap_alloc(&sg, sizeof *nsa);
  166     osa = stackgap_alloc(&sg, sizeof *osa);
  167 
  168     tmpsa.sa_handler = args->handler;
  169     tmpsa.sa_mask = (sigset_t) 0;
  170     tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
  171     if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
  172         return error;
  173 
  174     sa_args.signum = linux_to_bsd_signal[args->sig];
  175     sa_args.osa = osa;
  176     sa_args.nsa = nsa;
  177     if ((error = sigaction(p, &sa_args, retval)))
  178         return error;
  179 
  180     if ((error = copyin(osa, &tmpsa, sizeof *osa)))
  181         return error;
  182 
  183     *retval = (int)tmpsa.sa_handler;
  184 
  185     return 0;
  186 }
  187 
  188 
  189 int
  190 linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
  191                   int *retval)
  192 {
  193     int error, s;
  194     sigset_t mask;
  195     sigset_t omask;
  196 
  197 #ifdef DEBUG
  198     printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how);
  199 #endif
  200 
  201     *retval = 0;
  202 
  203     if (args->omask != NULL) {
  204         omask = bsd_to_linux_sigset(p->p_sigmask);
  205         if (error = copyout(&omask, args->omask, sizeof(sigset_t)))
  206             return error;
  207     }
  208     if (!(args->mask))
  209         return 0;
  210     if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t)))
  211         return error;
  212 
  213     mask = linux_to_bsd_sigset(mask);
  214     s = splhigh();
  215     switch (args->how) {
  216     case LINUX_SIG_BLOCK:
  217         p->p_sigmask |= (mask & ~sigcantmask);
  218         break;
  219     case LINUX_SIG_UNBLOCK:
  220         p->p_sigmask &= ~mask;
  221         break;
  222     case LINUX_SIG_SETMASK:
  223         p->p_sigmask = (mask & ~sigcantmask);
  224         break;
  225     default:
  226         error = EINVAL;
  227         break;
  228     }
  229     splx(s);
  230     return error;
  231 }
  232 
  233 int
  234 linux_siggetmask(struct proc *p, struct linux_siggetmask_args *args, int *retval)
  235 {
  236 #ifdef DEBUG
  237     printf("Linux-emul(%d): siggetmask()\n", p->p_pid);
  238 #endif
  239     *retval = bsd_to_linux_sigset(p->p_sigmask);
  240     return 0;
  241 }
  242 
  243 int
  244 linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval)
  245 {
  246     int s;
  247     sigset_t mask;
  248 
  249 #ifdef DEBUG
  250     printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask);
  251 #endif
  252     *retval = bsd_to_linux_sigset(p->p_sigmask);
  253 
  254     mask = linux_to_bsd_sigset(args->mask);
  255     s = splhigh();
  256     p->p_sigmask = mask & ~sigcantmask;
  257     splx(s);
  258     return 0;
  259 }
  260 
  261 int
  262 linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval)
  263 {
  264     linux_sigset_t linux_sig;
  265 
  266 #ifdef DEBUG
  267     printf("Linux-emul(%d): sigpending(*)\n", p->p_pid);
  268 #endif
  269     linux_sig = bsd_to_linux_sigset(p->p_siglist & p->p_sigmask);
  270     return copyout(&linux_sig, args->mask, sizeof(linux_sig));
  271 }
  272 
  273 /*
  274  * Linux has two extra args, restart and oldmask.  We dont use these,
  275  * but it seems that "restart" is actually a context pointer that
  276  * enables the signal to happen with a different register set.
  277  */
  278 int
  279 linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval)
  280 {
  281     struct sigsuspend_args tmp;
  282 
  283 #ifdef DEBUG
  284     printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask);
  285 #endif
  286     tmp.mask = linux_to_bsd_sigset(args->mask);
  287     return sigsuspend(p, &tmp , retval);
  288 }
  289 
  290 int
  291 linux_pause(struct proc *p, struct linux_pause_args *args,int *retval)
  292 {
  293     struct sigsuspend_args tmp;
  294 
  295 #ifdef DEBUG
  296     printf("Linux-emul(%d): pause()\n", p->p_pid);
  297 #endif
  298     tmp.mask = p->p_sigmask;
  299     return sigsuspend(p, &tmp , retval);
  300 }
  301 
  302 int
  303 linux_kill(struct proc *p, struct linux_kill_args *args, int *retval)
  304 {
  305     struct kill_args /* {
  306         int pid;
  307         int signum;
  308     } */ tmp;
  309 
  310 #ifdef DEBUG
  311     printf("Linux-emul(%d): kill(%d, %d)\n", 
  312            p->p_pid, args->pid, args->signum);
  313 #endif
  314     if (args->signum <= 0 || args->signum >= LINUX_NSIG)
  315         return EINVAL;
  316     tmp.pid = args->pid;
  317     tmp.signum = linux_to_bsd_signal[args->signum];
  318     return kill(p, &tmp, retval);
  319 }

Cache object: db227e3e77b9f6aad60f9034c816324b


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