home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / library / rcs / kern_sig.c,v < prev    next >
Encoding:
Text File  |  1992-08-09  |  20.7 KB  |  971 lines

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