root/compat/hpux/hpux_sig.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hpux_sys_sigvec
  2. hpux_sys_sigblock
  3. hpux_sys_sigsetmask
  4. hpux_sys_sigpause
  5. hpux_sys_kill
  6. hpux_sys_sigprocmask
  7. hpux_sys_sigpending
  8. hpux_sys_sigsuspend
  9. hpux_sys_sigaction
  10. hpuxtobsdsig
  11. bsdtohpuxsig
  12. hpuxtobsdmask
  13. bsdtohpuxmask

    1 /*      $OpenBSD: hpux_sig.c,v 1.9 2004/09/19 21:56:18 mickey Exp $     */
    2 /*      $NetBSD: hpux_sig.c,v 1.16 1997/04/01 19:59:02 scottr Exp $     */
    3 
    4 /*
    5  * Copyright (c) 1988 University of Utah.
    6  * Copyright (c) 1990, 1993
    7  *      The Regents of the University of California.  All rights reserved.
    8  *
    9  * This code is derived from software contributed to Berkeley by
   10  * the Systems Programming Group of the University of Utah Computer
   11  * Science Department.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  * from: Utah $Hdr: hpux_sig.c 1.4 92/01/20$
   38  *
   39  *      @(#)hpux_sig.c  8.2 (Berkeley) 9/23/93
   40  */
   41 
   42 /*
   43  * Signal related HPUX compatibility routines
   44  */
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/kernel.h>
   49 #include <sys/mount.h>
   50 #include <sys/proc.h>
   51 #include <sys/signalvar.h>
   52 #include <sys/syscallargs.h>
   53 
   54 #include <compat/hpux/hpux.h>
   55 #include <compat/hpux/hpux_sig.h>
   56 #include <compat/hpux/hpux_syscallargs.h>
   57 
   58 /* indexed by HPUX signal number - 1 */
   59 char hpuxtobsdsigmap[NSIG] = {
   60 /*01*/  SIGHUP,  SIGINT, SIGQUIT, SIGILL,   SIGTRAP, SIGIOT,  SIGEMT,   SIGFPE,
   61 /*09*/  SIGKILL, SIGBUS, SIGSEGV, SIGSYS,   SIGPIPE, SIGALRM, SIGTERM,  SIGUSR1,
   62 /*17*/  SIGUSR2, SIGCHLD, 0,      SIGVTALRM,SIGPROF, SIGIO,   SIGWINCH, SIGSTOP,
   63 /*25*/  SIGTSTP, SIGCONT,SIGTTIN, SIGTTOU,  SIGURG,  0,       0,        0
   64 };
   65 
   66 /* indexed by BSD signal number - 1 */
   67 char bsdtohpuxsigmap[NSIG] = {
   68 /*01*/   1,  2,  3,  4,  5,  6,  7,  8,
   69 /*09*/   9, 10, 11, 12, 13, 14, 15, 29,
   70 /*17*/  24, 25, 26, 18, 27, 28, 22,  0,
   71 /*25*/   0, 20, 21, 23,  0, 16, 17,  0
   72 };
   73 
   74 /*
   75  * XXX: In addition to mapping the signal number we also have
   76  * to see if the "old" style signal mechinism is needed.
   77  * If so, we set the OUSIG flag.  This is not really correct
   78  * as under HP-UX "old" style handling can be set on a per
   79  * signal basis and we are setting it for all signals in one
   80  * swell foop.  I suspect we can get away with this since I
   81  * doubt any program of interest mixes the two semantics.
   82  */
   83 int
   84 hpux_sys_sigvec(p, v, retval)
   85         struct proc *p;
   86         void *v;
   87         register_t *retval;
   88 {
   89         struct hpux_sys_sigvec_args *uap = v;
   90         struct sigvec vec;
   91         struct sigacts *ps = p->p_sigacts;
   92         struct sigvec *sv;
   93         int sig;
   94         int bit, error;
   95 
   96         sig = hpuxtobsdsig(SCARG(uap, signo));
   97         if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
   98                 return (EINVAL);
   99         sv = &vec;
  100         if (SCARG(uap, osv)) {
  101                 sv->sv_handler = ps->ps_sigact[sig];
  102                 sv->sv_mask = ps->ps_catchmask[sig];
  103                 bit = sigmask(sig);
  104                 sv->sv_flags = 0;
  105                 if ((ps->ps_sigonstack & bit) != 0)
  106                         sv->sv_flags |= SV_ONSTACK;
  107                 if ((ps->ps_sigintr & bit) != 0)
  108                         sv->sv_flags |= SV_INTERRUPT;
  109                 if ((ps->ps_sigreset & bit) != 0)
  110                         sv->sv_flags |= HPUXSV_RESET;
  111                 sv->sv_mask &= ~bit;
  112                 error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv),
  113                     sizeof (vec));
  114                 if (error)
  115                         return (error);
  116         }
  117         if (SCARG(uap, nsv)) {
  118                 error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv,
  119                     sizeof (vec));
  120                 if (error)
  121                         return (error);
  122                 if (sig == SIGCONT && sv->sv_handler == SIG_IGN)
  123                         return (EINVAL);
  124                 sv->sv_flags ^= SA_RESTART;
  125                 setsigvec(p, sig, (struct sigaction *)sv);
  126 #if 0
  127 /* XXX -- SOUSIG no longer exists, do something here */
  128                 if (sv->sv_flags & HPUXSV_RESET)
  129                         p->p_flag |= SOUSIG;            /* XXX */
  130 #endif
  131         }
  132         return (0);
  133 }
  134 
  135 int
  136 hpux_sys_sigblock(p, v, retval)
  137         struct proc *p;
  138         void *v;
  139         register_t *retval;
  140 {
  141         struct hpux_sys_sigblock_args *uap = v;
  142 
  143         (void) splhigh();
  144         *retval = bsdtohpuxmask(p->p_sigmask);
  145         p->p_sigmask |= hpuxtobsdmask(SCARG(uap, mask)) &~ sigcantmask;
  146         (void) spl0();
  147         return (0);
  148 }
  149 
  150 int
  151 hpux_sys_sigsetmask(p, v, retval)
  152         struct proc *p;
  153         void *v;
  154         register_t *retval;
  155 {
  156         struct hpux_sys_sigsetmask_args *uap = v;
  157 
  158         (void) splhigh();
  159         *retval = bsdtohpuxmask(p->p_sigmask);
  160         p->p_sigmask = hpuxtobsdmask(SCARG(uap, mask)) &~ sigcantmask;
  161         (void) spl0();
  162         return (0);
  163 }
  164 
  165 int
  166 hpux_sys_sigpause(p, v, retval)
  167         struct proc *p;
  168         void *v;
  169         register_t *retval;
  170 {
  171         struct hpux_sys_sigpause_args *uap = v;
  172 
  173         SCARG(uap, mask) = hpuxtobsdmask(SCARG(uap, mask));
  174         return (sys_sigsuspend(p, uap, retval));
  175 }
  176 
  177 /* not totally correct, but close enuf' */
  178 int
  179 hpux_sys_kill(p, v, retval)
  180         struct proc *p;
  181         void *v;
  182         register_t *retval;
  183 {
  184         struct hpux_sys_kill_args *uap = v;
  185 
  186         if (SCARG(uap, signo)) {
  187                 SCARG(uap, signo) = hpuxtobsdsig(SCARG(uap, signo));
  188                 if (SCARG(uap, signo) == 0)
  189                         SCARG(uap, signo) = NSIG;
  190         }
  191         return (sys_kill(p, uap, retval));
  192 }
  193 
  194 /*
  195  * The following (sigprocmask, sigpending, sigsuspend, sigaction are
  196  * POSIX calls.  Under BSD, the library routine dereferences the sigset_t
  197  * pointers before traping.  Not so under HP-UX.
  198  */
  199 
  200 /*
  201  * Manipulate signal mask.
  202  * Note that we receive new mask, not pointer,
  203  * and return old mask as return value;
  204  * the library stub does the rest.
  205  */
  206 int
  207 hpux_sys_sigprocmask(p, v, retval)
  208         struct proc *p;
  209         void *v;
  210         register_t *retval;
  211 {
  212         struct hpux_sys_sigprocmask_args *uap = v;
  213         int mask, error = 0;
  214         hpux_sigset_t sigset;
  215 
  216         /*
  217          * Copy out old mask first to ensure no errors.
  218          * (proc sigmask should not be changed if call fails for any reason)
  219          */
  220         if (SCARG(uap, oset)) {
  221                 bzero((caddr_t)&sigset, sizeof(sigset));
  222                 sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask);
  223                 if (copyout((caddr_t)&sigset, (caddr_t)SCARG(uap, oset),
  224                     sizeof(sigset)))
  225                         return (EFAULT);
  226         }
  227         if (SCARG(uap, set)) {
  228                 if (copyin((caddr_t)SCARG(uap, set), (caddr_t)&sigset,
  229                     sizeof(sigset)))
  230                         return (EFAULT);
  231                 mask = hpuxtobsdmask(sigset.sigset[0]);
  232                 (void) splhigh();
  233                 switch (SCARG(uap, how)) {
  234                 case HPUXSIG_BLOCK:
  235                         p->p_sigmask |= mask &~ sigcantmask;
  236                         break;
  237                 case HPUXSIG_UNBLOCK:
  238                         p->p_sigmask &= ~mask;
  239                         break;
  240                 case HPUXSIG_SETMASK:
  241                         p->p_sigmask = mask &~ sigcantmask;
  242                         break;
  243                 default:
  244                         error = EINVAL;
  245                         break;
  246                 }
  247                 (void) spl0();
  248         }
  249         return (error);
  250 }
  251 
  252 int
  253 hpux_sys_sigpending(p, v, retval)
  254         struct proc *p;
  255         void *v;
  256         register_t *retval;
  257 {
  258         struct hpux_sys_sigpending_args *uap = v;
  259         hpux_sigset_t sigset;
  260 
  261         sigset.sigset[0] = bsdtohpuxmask(p->p_siglist);
  262         return (copyout((caddr_t)&sigset, (caddr_t)SCARG(uap, set),
  263             sizeof(sigset)));
  264 }
  265 
  266 int
  267 hpux_sys_sigsuspend(p, v, retval)
  268         struct proc *p;
  269         void *v;
  270         register_t *retval;
  271 {
  272         struct hpux_sys_sigsuspend_args *uap = v;
  273         struct sigacts *ps = p->p_sigacts;
  274         hpux_sigset_t sigset;
  275         int mask;
  276 
  277         if (copyin((caddr_t)SCARG(uap, set), (caddr_t)&sigset, sizeof(sigset)))
  278                 return (EFAULT);
  279         mask = hpuxtobsdmask(sigset.sigset[0]);
  280         ps->ps_oldmask = p->p_sigmask;
  281         ps->ps_flags |= SAS_OLDMASK;
  282         p->p_sigmask = mask &~ sigcantmask;
  283         (void) tsleep((caddr_t)ps, PPAUSE | PCATCH, "pause", 0);
  284         /* always return EINTR rather than ERESTART... */
  285         return (EINTR);
  286 }
  287 
  288 int
  289 hpux_sys_sigaction(p, v, retval)
  290         struct proc *p;
  291         void *v;
  292         register_t *retval;
  293 {
  294         struct hpux_sys_sigaction_args *uap = v;
  295         struct hpux_sigaction action;
  296         struct sigacts *ps = p->p_sigacts;
  297         struct hpux_sigaction *sa;
  298         int sig;
  299         int bit;
  300 
  301         sig = hpuxtobsdsig(SCARG(uap, signo));
  302         if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
  303                 return (EINVAL);
  304 
  305         sa = &action;
  306         if (SCARG(uap, osa)) {
  307                 sa->sa__handler = ps->ps_sigact[sig];
  308                 bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask));
  309                 sa->sa_mask.sigset[0] = bsdtohpuxmask(ps->ps_catchmask[sig]);
  310                 bit = sigmask(sig);
  311                 sa->sa_flags = 0;
  312                 if ((ps->ps_sigonstack & bit) != 0)
  313                         sa->sa_flags |= HPUXSA_ONSTACK;
  314                 if ((ps->ps_sigreset & bit) != 0)
  315                         sa->sa_flags |= HPUXSA_RESETHAND;
  316                 if (p->p_flag & P_NOCLDSTOP)
  317                         sa->sa_flags |= HPUXSA_NOCLDSTOP;
  318                 if (p->p_flag & P_NOCLDWAIT)
  319                         sa->sa_flags |= HPUXSA_NOCLDWAIT;
  320                 if (copyout((caddr_t)sa, (caddr_t)SCARG(uap, osa),
  321                     sizeof (action)))
  322                         return (EFAULT);
  323         }
  324         if (SCARG(uap, nsa)) {
  325                 struct sigaction act;
  326 
  327                 if (copyin((caddr_t)SCARG(uap, nsa), (caddr_t)sa,
  328                     sizeof (action)))
  329                         return (EFAULT);
  330                 if (sig == SIGCONT && sa->sa__handler == SIG_IGN)
  331                         return (EINVAL);
  332                 /*
  333                  * Create a sigaction struct for setsigvec
  334                  */
  335                 act.sa_handler = sa->sa__handler;
  336                 act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]);
  337                 act.sa_flags = SA_RESTART;
  338                 if (sa->sa_flags & HPUXSA_ONSTACK)
  339                         act.sa_flags |= SA_ONSTACK;
  340                 if (sa->sa_flags & HPUXSA_NOCLDSTOP)
  341                         act.sa_flags |= SA_NOCLDSTOP;
  342                 if (sa->sa_flags & HPUXSA_NOCLDWAIT)
  343                         act.sa_flags |= SA_NOCLDWAIT;
  344                 setsigvec(p, sig, &act);
  345 #if 0
  346 /* XXX -- SOUSIG no longer exists, do something here */
  347                 if (sa->sa_flags & HPUXSA_RESETHAND)
  348                         p->p_flag |= SOUSIG;            /* XXX */
  349 #endif
  350         }
  351         return (0);
  352 }
  353 
  354 /* signal numbers: convert from HPUX to BSD */
  355 int
  356 hpuxtobsdsig(sig)
  357         int sig;
  358 {
  359         if (--sig < 0 || sig >= NSIG)
  360                 return(0);
  361         return((int)hpuxtobsdsigmap[sig]);
  362 }
  363 
  364 /* signal numbers: convert from BSD to HPUX */
  365 int
  366 bsdtohpuxsig(sig)
  367         int sig;
  368 {
  369         if (--sig < 0 || sig >= NSIG)
  370                 return(0);
  371         return((int)bsdtohpuxsigmap[sig]);
  372 }
  373 
  374 /* signal masks: convert from HPUX to BSD (not pretty or fast) */
  375 int
  376 hpuxtobsdmask(mask)
  377         int mask;
  378 {
  379         int nmask, sig, nsig;
  380 
  381         if (mask == 0 || mask == -1)
  382                 return(mask);
  383         nmask = 0;
  384         for (sig = 1; sig < NSIG; sig++)
  385                 if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig)))
  386                         nmask |= sigmask(nsig);
  387         return(nmask);
  388 }
  389 
  390 int
  391 bsdtohpuxmask(mask)
  392         int mask;
  393 {
  394         int nmask, sig, nsig;
  395 
  396         if (mask == 0 || mask == -1)
  397                 return(mask);
  398         nmask = 0;
  399         for (sig = 1; sig < NSIG; sig++)
  400                 if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig)))
  401                         nmask |= sigmask(nsig);
  402         return(nmask);
  403 }

/* [<][>][^][v][top][bottom][index][help] */