home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-19.28-src.tgz / tar.out / fsf / emacs / unixlib / src / signals.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  212 lines

  1. #include "amiga.h"
  2. #include "timers.h"
  3. #include "signals.h"
  4. #include "processes.h"
  5.  
  6. static ULONG signalsigs;    /* When one of these occur, call handle_signals */
  7. struct sigvec _sig_handlers[NSIG];
  8. long _sig_mask, _sig_pending;
  9.  
  10. /* Alarm signal */
  11. /* ------------ */
  12.  
  13. static struct timeinfo *alarm_timer;
  14.  
  15. static int check_alarm(ULONG sigs)
  16. {
  17.   return alarm_timer && _timer_expired(alarm_timer);
  18. }
  19.  
  20. void alarm(int secs)
  21. /* Effect: Schedule a SIGALRM after secs seconds
  22. */
  23. {
  24.   _timer_start(alarm_timer, secs, 0);
  25. }
  26.  
  27. static void init_alarm(void)
  28. {
  29.   if (!(alarm_timer = _alloc_timer())) _fail("Failed to create timer");
  30.   signalsigs |= _timer_sig(alarm_timer);
  31. }
  32.  
  33. static void cleanup_alarm(void)
  34. {
  35.   _free_timer(alarm_timer);
  36. }
  37.  
  38. /* SIGINT definition */
  39. /* ----------------- */
  40.  
  41. static void init_sigint(void)
  42. {
  43.   signalsigs |= SIGBREAKF_CTRL_C;
  44. }
  45.  
  46. /*static void cleanup_sigint(void) { }*/
  47.  
  48. static int check_sigint(ULONG sigs)
  49. {
  50.   return (sigs & SIGBREAKF_CTRL_C) != 0;
  51. }
  52.  
  53. /* SIGQUIT definition */
  54. /* ------------------ */
  55.  
  56. static void init_sigquit(void)
  57. {
  58.   signalsigs |= SIGBREAKF_CTRL_D;
  59. }
  60.  
  61. /*static void cleanup_sigquit(void) { }*/
  62.  
  63. static int check_sigquit(ULONG sigs)
  64. {
  65.   return (sigs & SIGBREAKF_CTRL_D) != 0;
  66. }
  67.  
  68. /* SIGCHLD definition */
  69. /* ------------------ */
  70.  
  71. static void init_children(void)
  72. {
  73.   _init_processes();
  74.   signalsigs |= 1L << _children_exit->mp_SigBit;
  75. }
  76.  
  77. static void cleanup_children(void)
  78. {
  79.   _cleanup_processes();
  80. }
  81.  
  82. static int check_children(ULONG sigs)
  83. {
  84.   struct exit_message *msg;
  85.   int change = FALSE;
  86.   
  87.   while (msg = (struct exit_message *)GetMsg(_children_exit))
  88.     {
  89.       struct process *p;
  90.  
  91.       if ((p = _find_pid(msg->pid)) && p->status == alive)
  92.     {
  93.       change = TRUE;
  94.       p->status = exited;
  95.       p->rc = msg->rc;
  96.     }
  97.       FreeMem(msg, sizeof(struct exit_message));
  98.     }
  99.   return change;
  100. }
  101.  
  102. /* Signal dispatching */
  103. /* ------------------ */
  104.  
  105. void _sig_dispatch(int sig)
  106. /* Effect: Do the action associated with signal sig it it isn't masked
  107.      Mask it for the duration of the signal exec
  108. */
  109. {
  110.   void (*fn)(int);
  111.   long smask = 1 << sig;
  112.  
  113.   if (sig == SIGKILL) _exit(0);
  114.  
  115.   if (_sig_mask & smask) _sig_pending |= smask;
  116.   else
  117.     do
  118.       {
  119.     _sig_pending &= ~smask;
  120.     if (sig >= 0 && sig < NSIG)
  121.       {
  122.         fn = _sig_handlers[sig].sv_handler;
  123.  
  124.         if (fn == SIG_DFL)
  125.           switch (sig)
  126.         {
  127.         case SIGCHLD: case SIGURG: case SIGWINCH: break;
  128.         case SIGINT: case SIGQUIT: _message("user interrupt");
  129.         default: _exit(0);
  130.         }
  131.         else if (fn != SIG_IGN)
  132.           {
  133.         int mask = smask | _sig_handlers[sig].sv_mask;
  134.  
  135.         _sig_mask |= mask;
  136.         fn(sig);
  137.         _sig_mask &= ~mask;
  138.           }
  139.       }
  140.       }
  141.     while (_sig_pending & smask); /* Signal may have been generated during the
  142.                      signal handling function. */
  143. }
  144.  
  145. ULONG _check_signals(ULONG extra_sigs)
  146. {
  147.   return SetSignal(0, signalsigs | extra_sigs);
  148. }
  149.  
  150. ULONG _wait_signals(ULONG extra_sigs)
  151. {
  152.   return Wait(signalsigs | extra_sigs);
  153. }
  154.  
  155. int _handle_signals(ULONG sigs)
  156. {
  157.   int signaled = 0;
  158.  
  159.   if (check_alarm(sigs)) { signaled = 1; _sig_dispatch(SIGALRM); }
  160.   if (check_sigint(sigs)) { signaled = 1; _sig_dispatch(SIGINT); }
  161.   if (check_sigquit(sigs)) { signaled = 1; _sig_dispatch(SIGQUIT); }
  162.   if (check_children(sigs)) { signaled = 1; _sig_dispatch(SIGCHLD); }
  163.  
  164.   return signaled;
  165. }
  166.  
  167. /* Patch into SAS signal stuff so as to replace it */
  168.  
  169. void CXFERR(int code)
  170. {
  171.     extern int _FPERR;
  172.  
  173.     _FPERR = code;
  174.     _sig_dispatch(SIGFPE);
  175. }
  176.  
  177. void chkabort(void)
  178. /* Checks all signals */
  179. {
  180.   _handle_signals(_check_signals(0));
  181. }
  182.  
  183. void Chk_Abort(void) { chkabort(); }
  184.  
  185. /* Initialisation */
  186. /* -------------- */
  187.  
  188. void _init_signals(void)
  189. {
  190.   int i;
  191.  
  192.   for (i = 0; i < NSIG; i++)
  193.     {
  194.       _sig_handlers[i].sv_handler = SIG_DFL;
  195.       _sig_handlers[i].sv_mask = 0;
  196.       /*_sig_handlers[i].sv_flags = 0;*/
  197.     }
  198.       
  199.   _sig_mask = _sig_pending = 0;
  200.   signalsigs = 0;
  201.  
  202.   init_sigint(); init_sigquit(); init_alarm(); init_children();
  203. }
  204.  
  205. void _cleanup_signals(void)
  206. {
  207.   cleanup_alarm();
  208.   /*cleanup_sigquit();*/
  209.   /*cleanup_sigint();*/
  210.   cleanup_children();
  211. }
  212.