home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / k / ksh48.zip / sh / trap.c < prev    next >
C/C++ Source or Header  |  1992-08-25  |  4KB  |  204 lines

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