home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / dev / gcc / ixemulsrc.lha / ixemul / library / kern_sig.c < prev    next >
C/C++ Source or Header  |  1996-12-11  |  24KB  |  1,011 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *  $Id: kern_sig.c,v 1.6 1994/07/11 00:32:56 rluebbert Exp $
  21.  *
  22.  *  $Log: kern_sig.c,v $
  23.  *  Revision 1.6  1994/07/11  00:32:56  rluebbert
  24.  *  Put issig back in.
  25.  *
  26.  *  Revision 1.5  1994/07/11  00:27:37  rluebbert
  27.  *  Commented out unused issig
  28.  *
  29.  *  Revision 1.4  1994/06/19  15:13:35  rluebbert
  30.  *  *** empty log message ***
  31.  *
  32.  *  Revision 1.2  1992/07/04  19:19:51  mwild
  33.  *  change to new ix_sleep() semantics
  34.  *
  35.  * Revision 1.1  1992/05/14  19:55:40  mwild
  36.  * Initial revision
  37.  *
  38.  *
  39.  *  Since the code originated from Berkeley, the following copyright
  40.  *  header applies as well. The code has been changed, it's not the
  41.  *  original Berkeley code!
  42.  */
  43.  
  44. /*
  45.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  46.  * All rights reserved.
  47.  *
  48.  * Redistribution is only permitted until one year after the first shipment
  49.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  50.  * binary forms are permitted provided that: (1) source distributions retain
  51.  * this entire copyright notice and comment, and (2) distributions including
  52.  * binaries display the following acknowledgement:  This product includes
  53.  * software developed by the University of California, Berkeley and its
  54.  * contributors'' in the documentation or other materials provided with the
  55.  * distribution and in all advertising materials mentioning features or use
  56.  * of this software.  Neither the name of the University nor the names of
  57.  * its contributors may be used to endorse or promote products derived from
  58.  * this software without specific prior written permission.
  59.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  60.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  61.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  62.  *
  63.  *    @(#)kern_sig.c    7.23 (Berkeley) 6/28/90
  64.  */
  65.  
  66. #define _KERNEL
  67. #include "ixemul.h"
  68. #include "kprintf.h"
  69.  
  70. #include <stdio.h>
  71. #include <string.h>
  72.  
  73. #include <wait.h>
  74.  
  75. #define    ttystopsigmask    (sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU))
  76. #define    stopsigmask    (sigmask(SIGSTOP)|ttystopsigmask)
  77. #define defaultignmask    (sigmask(SIGCONT)|sigmask(SIGIO)|sigmask(SIGURG)| \
  78.             sigmask(SIGCHLD)|sigmask(SIGWINCH)|sigmask(SIGINFO)|sigmask(SIGMSG))
  79.  
  80. void setsigvec (int sig, struct sigaction *sa);
  81. void sig_exit (unsigned int code);
  82. void stop (struct user *p);
  83.  
  84.  
  85. /*
  86.  * Can process p send the signal signo to process q?
  87.  */
  88. #define CANSIGNAL(p, q, signo) (1)
  89.  
  90. int
  91. sigaction (int sig, const struct sigaction *nsa, struct sigaction *osa)
  92. {
  93.   struct sigaction vec;
  94.   register struct sigaction *sa;
  95.   int bit;
  96.  
  97.   if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
  98.     {
  99.       errno = EINVAL;
  100.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  101.       return -1;
  102.     }
  103.  
  104.   sa = &vec;
  105.   if (osa)
  106.     {
  107.       sa->sa_handler = u.u_signal[sig];
  108.       sa->sa_mask = u.u_sigmask[sig];
  109.       bit = sigmask(sig);
  110.       sa->sa_flags = 0;
  111.       if ((u.u_sigonstack & bit) != 0)
  112.     sa->sa_flags |= SA_ONSTACK;
  113.  
  114.       if ((u.u_sigintr & bit) == 0)
  115.     sa->sa_flags |= SA_RESTART;
  116.  
  117.       if (u.p_flag & SNOCLDSTOP)
  118.     sa->sa_flags |= SA_NOCLDSTOP;
  119.  
  120.       *osa = *sa;
  121.     }
  122.  
  123.   if (nsa)
  124.     {
  125.       *sa = *nsa;
  126.       setsigvec(sig, sa);
  127.     }
  128.   
  129.   return (0);
  130. }
  131.  
  132. void
  133. setsigvec (int sig, struct sigaction *sa)
  134. {
  135.   register int bit;
  136.  
  137.   bit = sigmask(sig);
  138.   /*
  139.    * Change setting atomically.
  140.    */
  141.   Forbid();
  142.  
  143.   u.u_signal[sig] = sa->sa_handler;
  144.   u.u_sigmask[sig] = sa->sa_mask &~ sigcantmask;
  145.  
  146.   if ((sa->sa_flags & SA_RESTART) == 0)
  147.     u.u_sigintr |= bit;
  148.   else
  149.     u.u_sigintr &= ~bit;
  150.  
  151.   if (sa->sa_flags & SA_ONSTACK)
  152.     u.u_sigonstack |= bit;
  153.   else
  154.     u.u_sigonstack &= ~bit;
  155.  
  156.   if (sig == SIGCHLD) 
  157.     {
  158.       if (sa->sa_flags & SA_NOCLDSTOP)
  159.     u.p_flag |= SNOCLDSTOP;
  160.       else
  161.     u.p_flag &= ~SNOCLDSTOP;
  162.     }
  163.  
  164.   /*
  165.    * Set bit in p_sigignore for signals that are set to SIG_IGN,
  166.    * and for signals set to SIG_DFL where the default is to ignore.
  167.    * However, don't put SIGCONT in p_sigignore,
  168.    * as we have to restart the process.
  169.    */
  170.   if (sa->sa_handler == SIG_IGN ||
  171.       (bit & defaultignmask && sa->sa_handler == SIG_DFL)) 
  172.     {
  173.       u.p_sig &= ~bit;        /* never to be seen again */
  174.       if (sig != SIGCONT)
  175.     u.p_sigignore |= bit;    /* easier in _psignal */
  176.       u.p_sigcatch &= ~bit;
  177.     }
  178.   else 
  179.     {
  180.       u.p_sigignore &= ~bit;
  181.       if (sa->sa_handler == SIG_DFL)
  182.     u.p_sigcatch &= ~bit;
  183.       else
  184.     u.p_sigcatch |= bit;
  185.     }
  186.  
  187.   Permit();
  188. }
  189.  
  190.  
  191. /*
  192.  * Manipulate signal mask.
  193.  */
  194.  
  195. int
  196. sigprocmask (int how, const sigset_t *mask, sigset_t *omask)
  197. {
  198.   if (omask)
  199.     *omask = u.p_sigmask;
  200.  
  201.   if (mask)
  202.     {
  203.       Forbid();
  204.  
  205.       switch (how) 
  206.         {
  207.         case SIG_BLOCK:
  208.       u.p_sigmask |= *mask &~ sigcantmask;
  209.       break;
  210.  
  211.         case SIG_UNBLOCK:
  212.       u.p_sigmask &= ~*mask;
  213.       break;
  214.  
  215.         case SIG_SETMASK:
  216.       u.p_sigmask = *mask &~ sigcantmask;
  217.       break;
  218.     
  219.         default:
  220.       errno = EINVAL;
  221.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  222.       goto err_ret;
  223.         }
  224.  
  225.       Permit();
  226.     }
  227.  
  228.   if (CURSIG (&u))
  229.     setrun (FindTask (0));
  230.  
  231.   return 0;
  232.  
  233. err_ret:
  234.   Enable ();
  235.   return -1;
  236. }
  237.  
  238. int
  239. sigpending (sigset_t *sigs)
  240. {
  241.   *sigs = u.p_sig;
  242.   return 0;
  243. }
  244.  
  245. /*
  246.  * Generalized interface signal handler, 4.3-compatible.
  247.  * (included in amiga version, because I want to reduce the static part of the
  248.  *  library to a minimum)
  249.  */
  250. /* ARGSUSED */
  251. int
  252. sigvec(int sig, struct sigvec *nsv, struct sigvec *osv)
  253. {
  254.   struct sigvec vec;
  255.   register struct sigvec *sv;
  256.   struct user *p = &u;
  257.   int bit;
  258.  
  259.   if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
  260.     {
  261.       *p->u_errno = EINVAL;
  262.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  263.       return -1;
  264.     }
  265.  
  266.   sv = &vec;
  267.   if (osv) 
  268.     {
  269.       *(sig_t *)&sv->sv_handler = p->u_signal[sig];
  270.       sv->sv_mask = p->u_sigmask[sig];
  271.       bit = sigmask(sig);
  272.       sv->sv_flags = 0;
  273.       if ((p->u_sigonstack & bit) != 0)
  274.     sv->sv_flags |= SV_ONSTACK;
  275.       if ((p->u_sigintr & bit) != 0)
  276.     sv->sv_flags |= SV_INTERRUPT;
  277.       if (p->p_flag & SNOCLDSTOP)
  278.     sv->sv_flags |= SA_NOCLDSTOP;
  279.       *osv = *sv;
  280.     }
  281.  
  282.   if (nsv) 
  283.     {
  284.       *sv = *nsv;
  285.       sv->sv_flags ^= SA_RESTART;    /* opposite of SV_INTERRUPT */
  286.       setsigvec(sig, (struct sigaction *)sv);
  287.     }
  288.  
  289.   return (0);
  290. }
  291.  
  292. int
  293. sigblock (int mask)
  294. {
  295.   int result;
  296.  
  297.   Forbid();
  298.   result = u.p_sigmask;
  299.   u.p_sigmask |= mask &~ sigcantmask;
  300.   Permit();
  301.  
  302.   return result;
  303. }
  304.  
  305. int
  306. sigsetmask(int mask)
  307. {
  308.   int result;
  309.   struct user *p = &u;
  310.  
  311.   Forbid();
  312.   result = u.p_sigmask;
  313.   u.p_sigmask = mask &~ sigcantmask;
  314.   Permit();
  315.  
  316.   if (CURSIG (p))
  317.     setrun (FindTask (0));
  318.  
  319.   return result;
  320. }
  321.  
  322. /*
  323.  * Suspend process until signal, providing mask to be set
  324.  * in the meantime. 
  325.  */
  326. /* ARGSUSED */
  327. int
  328. sigsuspend (const sigset_t *mask)
  329. {
  330.   struct user *p = &u;
  331.  
  332.   /*
  333.    * When returning from sigpause, we want
  334.    * the old mask to be restored after the
  335.    * signal handler has finished.  Thus, we
  336.    * save it here and mark the proc structure
  337.    * to indicate this (should be in u.).
  338.    */
  339.  
  340.   Forbid();
  341.   p->u_oldmask = p->p_sigmask;
  342.   p->p_flag |= SOMASK;
  343.   p->p_sigmask = *mask &~ sigcantmask;
  344.  
  345.  
  346.   /* NOTE: we have to specify SIGBREAKF_CTRL_C here, as the OS doesn't seem
  347.    *       to reschedule our task, if it receives a signal it isn't waiting
  348.    *       for. If SIGINT is ignored, then this will jump back into the Wait,
  349.    *       if not, we're leaving correctly, since we waited for a signal
  350.    *       that now occured (lucky we, the OS tests the Recvd-field before
  351.    *       tc_Launch has a chance to reset it ;-))
  352.    */
  353.  
  354.   while (ix_sleep ((caddr_t)p, "sigsuspend") == 0);
  355.   Permit();
  356.  
  357.   setrun (FindTask (0));
  358.  
  359.   p->p_sigmask = p->u_oldmask;
  360.  
  361.   if (CURSIG (p))
  362.     setrun (FindTask (0));
  363.  
  364.   /* always return EINTR rather than ERESTART... */
  365.   errno = EINTR;
  366.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  367.   return -1;
  368. }
  369.  
  370.  
  371. int
  372. sigpause (int mask)
  373. {
  374.   return sigsuspend (&mask);
  375. }
  376.  
  377.  
  378. /* ARGSUSED */
  379. int
  380. sigstack(const struct sigstack *nss, struct sigstack *oss)
  381. {
  382.   if (oss) *oss = u.u_sigstack;
  383.   if (nss) u.u_sigstack = *nss;
  384.  
  385.   return 0;
  386. }
  387.  
  388.  
  389. /*
  390.  * Initialize signal state for process 0;
  391.  * set to ignore signals that are ignored by default.
  392.  */
  393. void
  394. siginit(struct user *p)
  395. {
  396.   p->p_sigignore = defaultignmask &~ sigmask(SIGCONT);
  397. }
  398.  
  399. /*
  400.  * This looks for the process p, validates it, and checks, whether the process
  401.  * is currently using our signal mechanism (checks magic cookie in struct user)
  402.  */
  403. struct Task *
  404. pfind (pid_t p)
  405. {
  406.   struct Task *t;
  407.   
  408.   if (p && !(p & 1))
  409.     {
  410.       /* have to check if the task really exists */
  411.  
  412.       struct List *exectasklist;
  413.       struct Node * execnode;
  414.  
  415.       Disable();
  416.       exectasklist = &(SysBase->TaskWait);
  417.       for (execnode = exectasklist->lh_Head; execnode->ln_Succ;
  418.            execnode = execnode->ln_Succ)
  419.         {
  420.           if ((pid_t)execnode == p)
  421.             break;
  422.         }
  423.       if (execnode == NULL)
  424.         {
  425.           exectasklist = &(SysBase->TaskReady);
  426.           for (execnode = exectasklist->lh_Head; execnode->ln_Succ;
  427.                execnode = execnode->ln_Succ)
  428.             {
  429.               if ((pid_t)execnode == p)
  430.                 break;
  431.             }
  432.         }
  433.       Enable();
  434.       if (execnode == NULL)
  435.         return 0;
  436.       t = (struct Task *) p;
  437.       if (t->tc_Node.ln_Type == NT_TASK ||
  438.           t->tc_Node.ln_Type == NT_PROCESS)
  439.         {
  440.           struct user *tu = getuser(t);
  441.  
  442.           if (tu && !((int)getuser(t) & 1) && tu->u_ixbase == u.u_ixbase)
  443.         return t;
  444.     }
  445.     }
  446.   else if (! p)
  447.     return FindTask (0);
  448.  
  449.   return 0;
  450. }
  451.  
  452. /* ARGSUSED */
  453. int
  454. kill(pid_t pid, int signo)
  455. {
  456.   register struct Task *t;
  457.  
  458.   if ((unsigned) signo >= NSIG)
  459.     {
  460.       errno = EINVAL;
  461.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  462.       return -1;
  463.     }
  464.  
  465.   if (pid >= 0)
  466.     {
  467.       /* kill single process */
  468.       t = pfind(pid);
  469.       if (t == 0)
  470.         {
  471.       /* there is a small chance, if pid == 0, that we may send the signal
  472.        * as well. If signo == SIGINT, and pid refers to a valid Task, we send
  473.        * it a SIGBREAKF_CTRL_C */
  474.       if ((signo == SIGINT) && pid && !(pid & 1))
  475.         {
  476.           t = (struct Task *) pid;
  477.           if (t->tc_Node.ln_Type == NT_TASK ||
  478.               t->tc_Node.ln_Type == NT_PROCESS)
  479.             {
  480.           Signal (t, SIGBREAKF_CTRL_C);
  481.           return 0;
  482.         }
  483.         }
  484.  
  485.           errno = ESRCH;
  486.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  487.           return -1;
  488.         }
  489.     
  490.       if (signo)
  491.     _psignal(t, signo);
  492.     
  493.       return (0);
  494.     }
  495.  
  496.   /* signalling process groups is not (yet) implemented */  
  497.   errno = ESRCH;
  498.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  499.   return -1;
  500. }
  501.  
  502. /* ARGSUSED */
  503. int
  504. killpg(int pgid, int signo)
  505. {
  506.   if ((unsigned) signo >= NSIG)
  507.     errno = EINVAL;
  508.   else
  509.     errno = ESRCH;
  510.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  511.  
  512.   /* signalling process groups is not (yet) implemented */  
  513.   return -1;
  514. }
  515.  
  516. /*
  517.  * Send a signal caused by a trap to the current process.
  518.  * If it will be caught immediately, deliver it with correct code.
  519.  * Otherwise, post it normally.
  520.  */
  521. void trapsignal(struct Task *t, int sig, unsigned code, void *addr)
  522. {
  523.   int mask;
  524.  
  525.   mask = sigmask(sig);
  526.   if ((u.p_flag & STRC) == 0 && (u.p_sigcatch & mask) != 0 &&
  527.       (u.p_sigmask & mask) == 0)
  528.     {
  529.       u.u_ru.ru_nsignals++;
  530.       sendsig(getuser(t), u.u_signal[sig], sig, u.p_sigmask, code, addr);
  531.       u.p_sigmask |= u.u_sigmask[sig] | mask;
  532.       setrun (t);
  533.     }
  534.   else
  535.     {
  536.       u.u_code = code;    /* XXX for core dump/debugger */
  537.       _psignal(t, sig);
  538.     }
  539. }
  540.  
  541. /*
  542.  * Create a core image on the file "core".
  543.  * It writes UPAGES block of the
  544.  * user.h area followed by the entire
  545.  * data+stack segments.
  546.  */
  547. int core(void)
  548. {
  549.   return -1;
  550. }
  551.  
  552. /*
  553.  * Send the specified signal to the specified process.
  554.  * Most signals do not do anything directly to a process;
  555.  * they set a flag that asks the process to do something to itself.
  556.  * Exceptions:
  557.  *   o When a stop signal is sent to a sleeping process that takes the default
  558.  *     action, the process is stopped without awakening it.
  559.  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
  560.  *     regardless of the signal action (eg, blocked or ignored).
  561.  * Other ignored signals are discarded immediately.
  562.  */
  563. void
  564. _psignal(struct Task *t, int sig)    /* MAY be called in Supervisor/Interrupt  !*/
  565. {
  566.   register sig_t action;
  567.   /* may be another process, so don't use u. here ! */
  568.   struct user *p = getuser(t);
  569.   int mask;
  570.  
  571.  
  572.   mask = sigmask(sig);
  573.  
  574.   /*
  575.    * If proc is traced, always give parent a chance.
  576.    */
  577.   if (p->p_flag & STRC)
  578.     action = SIG_DFL;
  579.   else 
  580.     {
  581.  
  582.       /* NOTE AMIGA !
  583.        * I can't allow for trap signals to be either ignored or masked out.
  584.        * This would cause the trap to reoccur immediately again, resulting
  585.        * in a deadly loop. So if such a signal gets here, it is converted
  586.        * in a SIGILL, masked in, not ignored, not caught, that's it.
  587.        */
  588.       if (((mask & p->p_sigignore) || (mask & p->p_sigmask))
  589.       && (sig == SIGILL  || sig == SIGBUS || sig == SIGFPE || 
  590.           sig == SIGTRAP || sig == SIGEMT))
  591.     {
  592.       sig = SIGILL;
  593.       mask = sigmask (sig);
  594.       p->p_sigignore &= ~mask;
  595.       p->p_sigmask   &= ~mask;
  596.       p->p_sigcatch  &= ~mask;
  597.       /* that's it, SIGILL is now reset to SIG_DFL, which will exit() */
  598.     }
  599.  
  600.       /*
  601.        * If the signal is being ignored,
  602.        * then we forget about it immediately.
  603.        * (Note: we don't set SIGCONT in p_sigignore,
  604.        * and if it is set to SIG_IGN,
  605.        * action will be SIG_DFL here.)
  606.        */
  607.      if (p->p_sigignore & mask)
  608.     return;
  609.  
  610.      if (p->p_sigmask & mask)
  611.     action = SIG_HOLD;
  612.      else if (p->p_sigcatch & mask)
  613.     action = SIG_CATCH;
  614.      else
  615.     action = SIG_DFL;
  616.     }
  617.  
  618.   switch (sig) 
  619.     {
  620.     case SIGTERM:
  621.       if ((p->p_flag&STRC) || action != SIG_DFL)
  622.     break;
  623.     /* FALLTHROUGH */
  624.  
  625.     case SIGKILL:
  626.       break;
  627.  
  628.     case SIGCONT:
  629.       p->p_sig &= ~stopsigmask;
  630.       break;
  631.  
  632.     case SIGTSTP:
  633.     case SIGTTIN:
  634.     case SIGTTOU:
  635.     case SIGSTOP:
  636.       p->p_sig &= ~sigmask(SIGCONT);
  637.       break;
  638.     }
  639.   p->p_sig |= mask;
  640.  
  641.   /*
  642.    * Defer further processing for signals which are held,
  643.    * except that stopped processes must be continued by SIGCONT.
  644.    */
  645.   if (action == SIG_HOLD && (sig != SIGCONT || p->p_stat != SSTOP))
  646.     return;
  647.  
  648.   /*
  649.    * If traced process is already stopped,
  650.    * then no further action is necessary.
  651.    */
  652.   if (p->p_stat == SSTOP && (p->p_flag & STRC))
  653.     return;
  654.  
  655.   setrun(t);
  656. }
  657.  
  658. void stopped_process_handler (void)
  659. {
  660.   /* We are running in user mode in the context of the exec Task that is
  661.      (in the view of other ixemul.library processes) a stopped process.
  662.      We got here from the stop_process_glue routine.  */
  663.  
  664.   struct Task *task = FindTask(0);
  665.   struct user *p = getuser(task);
  666.  
  667.   Forbid();
  668.   _psignal((struct Task *)p->p_pptr, SIGCHLD);
  669.   stop (p);
  670.  
  671.   while (p->p_stat != SRUN)
  672.     {
  673.       KPRINTF(("SSTOP: Wait (1<<p->p_zombie_sig);\n"));
  674.       Wait (1 << p->p_zombie_sig);
  675.       KPRINTF(("SSTOP: done, p->p_stat=%lx, p_xstat: %lx\n", p->p_stat, p->p_xstat));
  676.     }
  677.   Permit();
  678. }
  679.  
  680. /*
  681.  * If the current process has a signal to process (should be caught
  682.  * or cause termination, should interrupt current syscall),
  683.  * return the signal number.  Stop signals with default action
  684.  * are processed immediately, then cleared; they aren't returned.
  685.  * This is asked at least once each time a process enters the
  686.  * system (though this can usually be done without actually
  687.  * calling issig by checking the pending signal masks.)
  688.  */
  689. int
  690. issig(struct user *p)    /* called in SUPERVISOR */
  691. {
  692.   register int sig, mask;
  693.   u_int sr;
  694.  
  695.   KPRINTF(("issig(task=%lx)\n", SysBase->ThisTask));
  696.  
  697.   asm volatile (" 
  698.     movel a5,a0
  699.     lea      Lget_sr,a5
  700.     movel 4:w,a6
  701.     jsr      a6@(-0x1e)
  702.     movel a1,%0
  703.     bra      Lskip
  704. Lget_sr:
  705.     movew sp@,a1    | get sr register from the calling function
  706.     rte
  707. Lskip:
  708.     movel a0,a5
  709.     " : "=g" (sr) : : "a0", "a1", "a6");
  710.  
  711.   if (p->u_mask_state)
  712.     {
  713.       mask = p->u_mask_state;
  714.       p->u_mask_state = 0;
  715.       goto restart;
  716.     }
  717.   for (;;)
  718.     {
  719.       mask = p->p_sig & ~p->p_sigmask;
  720.       if (p->p_flag & SVFORK)
  721.     mask &= ~stopsigmask;
  722.  
  723.       if (mask == 0)         /* no signal to send */
  724.     return 0;
  725.  
  726.       sig = ffs((long)mask);
  727.       mask = sigmask(sig);
  728.       /*
  729.        * We should see pending but ignored signals
  730.        * only if STRC was on when they were posted.
  731.        */
  732.       if ((mask & p->p_sigignore) && (p->p_flag & STRC) == 0) 
  733.         {
  734.           p->p_sig &= ~mask;
  735.       continue;
  736.     }
  737.  
  738.       /* Don't do this while waiting in inet.library. */
  739.       if (p->p_stat != SWAIT && (p->p_flag & STRC)
  740.       && (p->p_flag & SVFORK) == 0) 
  741.         {
  742.       /*
  743.        * If traced, always stop, and stay
  744.        * stopped until released by the parent.
  745.        */
  746.       KPRINTF(("issig(task=%lx): ...stopping... Setting p->p_xstat = %ld\n", SysBase->ThisTask, sig));
  747.       p->p_xstat = sig;
  748.  
  749.       KPRINTF(("issig(task=%lx): ...stopping... Sending SIGCHLD to parent %lx\n", SysBase->ThisTask, p->p_pptr));
  750.  
  751.       if (sr & 0x2000)
  752.         {
  753.           KPRINTF(("issig(task=%lx): ...stopping... while in supervisor\n", SysBase->ThisTask));
  754.           p->u_mask_state = mask;
  755.           sendsig(p, (sig_t)stopped_process_handler, 0, 0, 0, 0);
  756.           return -1;  /* Drop into the context of the task. */
  757.         }
  758.       else
  759.         {
  760.           p->u_regs = NULL;
  761.           p->u_fpregs = NULL;
  762.           KPRINTF(("issig(task=%lx): ...stopping... while NOT in supervisor\n", SysBase->ThisTask));
  763.           stopped_process_handler ();
  764.         }
  765. restart:
  766.       /*
  767.        * If the traced bit got turned off,
  768.        * go back up to the top to rescan signals.
  769.        * This ensures that p_sig* and u_signal are consistent.
  770.        *
  771.        * (That may be, but it fails to work with ptrace(PT_DETACH):
  772.        * the old SIGTRAP is caught again, but without tracing that
  773.        * results in a call to exit(). So we comment it out.)
  774.        *
  775.        *if ((p->p_flag & STRC) == 0)
  776.        *  continue;
  777.        */
  778.  
  779.       /*
  780.        * If parent wants us to take the signal,
  781.        * then it will leave it in p->p_xstat;
  782.        * otherwise we just look for signals again.
  783.        */
  784.       p->p_sig &= ~mask;    /* clear the old signal */
  785.       sig = p->p_xstat;
  786.       if (sig == 0)
  787.         continue;
  788.       /*
  789.        * Put the new signal into p_sig.
  790.        * If signal is being masked,
  791.        * look for other signals.
  792.        */
  793.       mask = sigmask(sig);
  794.       p->p_sig |= mask;
  795.       if (p->p_sigmask & mask)
  796.         continue;
  797.     }
  798.  
  799.       /*
  800.        * Decide whether the signal should be returned.
  801.        * Return the signal's number, or fall through
  802.        * to clear it from the pending mask.
  803.        */
  804.       switch ((int)p->u_signal[sig]) 
  805.         {
  806.     case SIG_DFL:
  807. #if notyet
  808.       /*
  809.        * Don't take default actions on system processes.
  810.        */
  811.       if (p->p_ppid == 0)
  812.         break;        /* == ignore */
  813. #endif
  814.       /*
  815.        * If there is a pending stop signal to process
  816.        * with default action, stop here,
  817.        * then clear the signal.  However,
  818.        * if process is member of an orphaned
  819.        * process group, ignore tty stop signals.
  820.        */
  821.       if (mask & stopsigmask) 
  822.         {
  823. #if notyet
  824.           if (p->p_flag&STRC ||
  825.           (p->p_pgru.pg_jobc == 0 && mask & ttystopsigmask))
  826.         break;    /* == ignore */
  827.           u.p_xstat = sig;
  828.           stop(p);
  829.           if ((u.p_pptr->p_flag & SNOCLDSTOP) == 0)
  830.         _psignal(u.p_pptr, SIGCHLD);
  831.           swtch();
  832. #endif
  833.           break;
  834.         } 
  835.           else if (mask & defaultignmask)
  836.         {
  837.           /*
  838.            * Except for SIGCONT, shouldn't get here.
  839.            * Default action is to ignore; drop it.
  840.            */
  841.           break;        /* == ignore */
  842.         }
  843.       else
  844.         return (sig);
  845.       /*NOTREACHED*/
  846.  
  847.     case SIG_IGN:
  848.       /*
  849.        * Masking above should prevent us ever trying
  850.        * to take action on an ignored signal other
  851.        * than SIGCONT, unless process is traced.
  852.        */
  853. #if 0
  854.       if (sig != SIGCONT && (u.p_flag&STRC) == 0)
  855.         printf("issig\n");
  856. #endif
  857.       break;        /* == ignore */
  858.  
  859.     default:
  860.       /*
  861.        * This signal has an action, let
  862.        * psig process it.
  863.        */
  864.       return (sig);
  865.     }
  866.       u.p_sig &= ~mask;        /* take the signal! */
  867.     }
  868.   /* NOTREACHED */
  869. }
  870.  
  871. /*
  872.  * Put the argument process into the stopped
  873.  * state and notify the parent via wakeup.
  874.  * Signals are handled elsewhere.
  875.  * The process must not be on the run queue.
  876.  */
  877. void stop(struct user *p)
  878. {
  879.   p->p_stat = SSTOP;
  880.   p->p_flag &= ~SWTED;
  881.   ix_wakeup((u_int)getuser(p->p_pptr));
  882. }
  883.  
  884. /*
  885.  * Perform the action specified by the current signal.
  886.  * The usual sequence is:
  887.  *    if (sig = CURSIG(p))
  888.  *        psig(p, sig);
  889.  */
  890. void
  891. psig(struct user *p, int sig)    /* called in SUPERVISOR */
  892. {
  893.   int code, mask, returnmask;
  894.   register sig_t action; 
  895.  
  896.   do 
  897.     {
  898.       if (sig == -1)
  899.         return;
  900.       mask = sigmask(sig);
  901.       p->p_sig &= ~mask;
  902.       action = p->u_signal[sig];
  903.       if (action != SIG_DFL) 
  904.         {
  905.        /*
  906.         * Set the new mask value and also defer further
  907.         * occurences of this signal.
  908.         *
  909.         * Special case: user has done a sigpause.  Here the
  910.         * current mask is not of interest, but rather the
  911.          * mask from before the sigpause is what we want
  912.         * restored after the signal processing is completed.
  913.         */
  914.       if (p->p_flag & SOMASK)
  915.         {
  916.           returnmask = p->u_oldmask;
  917.           p->p_flag &= ~SOMASK;
  918.         }
  919.       else
  920.         returnmask = p->p_sigmask;
  921.       p->p_sigmask |= p->u_sigmask[sig] | mask;
  922.  
  923.       p->u_ru.ru_nsignals++;
  924.       if (p->u_sig != sig)
  925.         {
  926.           KPRINTF(("psig(): code = 0;"));
  927.           code = 0;
  928.         }
  929.       else
  930.         {
  931.           KPRINTF(("psig(): code = u.u_code;\n"));
  932.           code = p->u_code;
  933.           p->u_code = 0;
  934.         }
  935.       KPRINTF(("kern_sig.c:psig(): doing sendsig(p, action, sig, returnmask, code, 0);\n"));
  936.       sendsig(p, action, sig, returnmask, code, 0);
  937.       continue;
  938.     }
  939.  
  940. #if whatdoesthisdo
  941.       p->u_acflag |= AXSIG;
  942. #endif
  943.  
  944.       switch (sig) 
  945.         {
  946.     case SIGILL:
  947.     case SIGIOT:
  948.     case SIGBUS:
  949.     case SIGQUIT:
  950.     case SIGTRAP:
  951.     case SIGEMT:
  952.     case SIGFPE:
  953.     case SIGSEGV:
  954.     case SIGSYS:
  955.       p->u_sig = sig;
  956.       if (core() == 0)
  957.         sig |= WCOREFLAG;
  958.     }
  959.       /* we can't call exit() when in supervisor mode, have to do this just like
  960.        * it was a signal passed on its own frame */
  961.       sendsig(p, (sig_t)sig_exit, sig, 0, 0, 0);
  962.   } while ((sig = CURSIG(p)));
  963. }
  964.  
  965. static int sigprocessgrp(struct Process *proc, int pgrp, int signal, int test)
  966. {
  967.   struct Process *p;
  968.  
  969.   if (test)
  970.     {
  971.       if (getuser(proc) == NULL)
  972.         return 0;
  973.       for (p = getuser(proc)->p_cptr; p; p = getuser(p)->p_osptr)
  974.         {
  975.           if (getuser(p) == NULL)
  976.             return 0;
  977.           if (sigprocessgrp(p, pgrp, signal, test) == 0)
  978.             return 0;
  979.         }
  980.       return 1;
  981.     }
  982.   for (p = getuser(proc)->p_cptr; p; p = getuser(p)->p_osptr)
  983.     {
  984.       sigprocessgrp(p, pgrp, signal, test);
  985.     }
  986.   if (getuser(proc)->p_pgrp == pgrp)
  987.     _psignal((struct Task *)proc, signal);
  988.   return 1;
  989. }
  990.  
  991. void _psignalgrp(struct Process *proc, int signal)
  992. {
  993.   struct Process *p;
  994.   struct Process *ok = proc;
  995.  
  996.   if (proc == NULL || getuser(proc) == NULL)
  997.     return;
  998.   p = getuser(proc)->p_pptr;
  999.  
  1000.   /* traverse to the top of the process-tree */
  1001.   while (p && p != (struct Process *)1)
  1002.     {
  1003.       ok = p;
  1004.       if (getuser(p) == NULL)
  1005.         return;
  1006.       p = getuser(p)->p_pptr;
  1007.     }
  1008.   if (sigprocessgrp(ok, getuser(proc)->p_pgrp, signal, 1))
  1009.     sigprocessgrp(ok, getuser(proc)->p_pgrp, signal, 0);
  1010. }
  1011.