home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / pdksh-4.9-src.tgz / tar.out / contrib / pdksh / sh / trap.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  218 lines

  1. /*
  2.  * signal handling
  3.  */
  4.  
  5. #ifndef lint
  6. static char *RCSid = "$Id: trap.c,v 1.4 93/05/05 21:17:12 sjg Exp $";
  7. #endif
  8.  
  9. #include "stdh.h"
  10. #include <errno.h>
  11. #include <signal.h>
  12. #include <setjmp.h>
  13. #include "sh.h"
  14.  
  15. Trap sigtraps [SIGNALS] = {
  16.     {0,    "EXIT", "Signal 0"}, /* todo: belongs in e.loc->exit */
  17.     {SIGHUP, "HUP", "Hangup"},
  18.     {SIGINT, "INT", "Interrupt"},
  19.     {SIGQUIT, "QUIT", "Quit"},
  20.     {SIGILL, "ILL", "Illegal instruction"},
  21.     {SIGTRAP, "TRAP", "Trace trap"},
  22. #ifdef    SIGABRT
  23.     {SIGIOT, "ABRT", "Abort"},
  24. #else
  25.     {SIGIOT, "IOT", "IOT instruction"},
  26. #endif
  27.     {SIGEMT, "EMT", "EMT trap"},
  28.     {SIGFPE, "FPE", "Floating exception"},
  29.     {SIGKILL, "KILL", "Killed"},
  30. #ifdef _MINIX
  31.     {SIGUSR1, "USR1", "User defined signal 1"},
  32.     {SIGSEGV, "SEGV", "Memory fault"},
  33.     {SIGUSR2, "USR2", "User defined signal 2"},
  34. #else
  35.     {SIGBUS, "BUS", "Bus error"},
  36.     {SIGSEGV, "SEGV", "Memory fault"},
  37.     {SIGSYS, "SYS", "Bad system call"},
  38. #endif
  39.     {SIGPIPE, "PIPE", "Broken pipe"},
  40.     {SIGALRM, "ALRM", "Alarm clock"},
  41.     {SIGTERM, "TERM", "Terminated"},
  42. #ifdef _MINIX
  43.     {SIGSTKFLT, "STKFLT", "Stack fault"},
  44. #endif
  45. #ifdef _SYSV
  46.     {SIGUSR1, "USR1", "User defined signal 1"},
  47.     {SIGUSR2, "USR2", "User defined signal 2"},
  48.     {SIGCLD, "CLD", "Death of a child"},
  49.     {SIGPWR, "PWR", "Power-fail restart"},
  50. #ifdef JOBS            /* todo: need to be more portable */
  51.     {SIGTSTP, "TSTP", "Stop"},
  52.     {SIGTTIN, "TTIN", "Stop (tty input)"},
  53. #ifdef SIGPOLL
  54.     {SIGPOLL, "POLL", "Pollable event occured"},
  55. #endif
  56.     {SIGSTOP, "STOP", "Stop (signal)"},
  57.     {SIGTTOU, "TTOU", "Stop (tty output)"},
  58.     {SIGCONT, "CONT", "Continue"},
  59. #endif
  60. #else
  61. #ifdef JOBS            /* todo: need to be more portable */
  62.     {SIGURG, "URG", "Urgent condition"}, /* BSDism */
  63.     {SIGSTOP, "STOP", "Stop (signal)"},
  64.     {SIGTSTP, "TSTP", "Stop"},
  65.     {SIGCONT, "CONT", "Continue"},
  66.     {SIGCHLD, "CHLD", "Waiting children"},
  67.     {SIGTTIN, "TTIN", "Stop (tty input)"},
  68.     {SIGTTOU, "TTOU", "Stop (tty output)"},
  69. #endif
  70. #endif
  71. };
  72.  
  73. Trap *
  74. gettrap(name)
  75.     char *name;
  76. {
  77.     int i;
  78.     register Trap *p;
  79.  
  80.     if (digit(*name)) {
  81.         i = getn(name);
  82.         return (0 <= i && i < SIGNALS) ? &sigtraps[getn(name)] : NULL;
  83.     }
  84. #if 0
  85.     if (strcmp("ERR", name) == 0)
  86.         return &e.loc->err;
  87.     if (strcmp("EXIT", name) == 0)
  88.         return &e.loc->exit;
  89. #endif
  90.     for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
  91.         if (p->name != NULL && strcmp(p->name, name) == 0)
  92.             return p;
  93.     return NULL;
  94. }
  95.  
  96. /*
  97.  * trap signal handler
  98.  */
  99. void
  100. trapsig(i)
  101.     int i;
  102. {
  103.     trap = sigtraps[i].set = 1;
  104.     if (i == SIGINT && (e.type == E_PARSE || e.type == E_LOOP))
  105.         /* dangerous but necessary to deal with BSD silly signals */
  106.         longjmp(e.jbuf, 1);
  107. #ifdef USE_SIGACT
  108.     sigaction(i, &Sigact_trap, NULL);
  109. #else
  110.     (void) signal(i, trapsig);
  111. #endif
  112. }
  113.  
  114. #ifdef amigaos
  115. /* need to copy any allocated trap command strings in child, or we free
  116.    memory of the parent when afree() is invoked */
  117. void
  118. child_dup_traps ()
  119. {
  120.   Trap *p;
  121.   
  122.   for (p = sigtraps; p < &sigtraps[sizeof (sigtraps) / sizeof (Trap)]; p++)
  123.     if (p->trap)
  124.       p->trap = strsave (p->trap, APERM);
  125. }
  126.  
  127. #endif /* amigaos */
  128.     
  129.  
  130. /*
  131.  * run any pending traps
  132.  */
  133. runtraps()
  134. {
  135.     int i;
  136.     register Trap *p;
  137.  
  138.     for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
  139.         if (p->set)
  140.             runtrap(p);
  141.     trap = 0;
  142. }
  143.  
  144. runtrap(p)
  145.     Trap *p;
  146. {
  147.     char *trapstr;
  148.  
  149.     p->set = 0;
  150.     if ((trapstr = p->trap) == NULL)
  151.         if (p->signal == SIGINT)
  152.             unwind();    /* return to shell() */
  153.         else
  154.             return;
  155.     if (p->signal == 0)    /* ??? */
  156.         p->trap = 0;
  157.     command(trapstr);
  158. }
  159.  
  160. /* restore signals for children */
  161. cleartraps()
  162. {
  163.     int i;
  164.     register Trap *p;
  165.  
  166.     if ((p = sigtraps)->trap != NULL) {    /* Maybe put in exchild() */
  167.         afree((void *)p->trap,APERM);    /* Necessary? */
  168.         p->trap = NULL;
  169.     }
  170.     for (i = SIGNALS, p = sigtraps; --i >= 0; p++) {
  171.         p->set = 0;
  172. #ifdef USE_SIGACT
  173.         if (p->ourtrap)
  174.         {
  175.           sigaction(p->signal, &Sigact_ign, &Sigact);
  176.           if (Sigact.sa_handler != SIG_IGN)
  177.             sigaction(p->signal, &Sigact_dfl, NULL);
  178.         }
  179. #else
  180.         if (p->ourtrap && signal(p->signal, SIG_IGN) != SIG_IGN)
  181.             (void) signal(p->signal, SIG_DFL);
  182. #endif
  183.     }
  184. }
  185.  
  186. ignoresig(i)
  187.     int i;
  188. {
  189. #ifdef USE_SIGACT
  190.   sigaction(i, &Sigact_ign, &Sigact);
  191.   sigemptyset(&Sigact.sa_mask);
  192.   Sigact.sa_flags = 0;
  193.  
  194.   if (Sigact.sa_handler != SIG_IGN)
  195.     sigtraps[i].sig_dfl = 1;
  196. #else
  197.   if (signal(i, SIG_IGN) != SIG_IGN)
  198.     sigtraps[i].sig_dfl = 1;
  199. #endif
  200. }
  201.  
  202. restoresigs()
  203. {
  204.     int i;
  205.     register Trap *p;
  206.  
  207.     for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
  208.         if (p->sig_dfl) {
  209.             p->sig_dfl = 0;
  210. #ifdef USE_SIGACT
  211.             sigaction(p->signal, &Sigact_dfl, NULL);
  212. #else
  213.             (void) signal(p->signal, SIG_DFL);
  214. #endif
  215.         }
  216. }
  217.  
  218.