|
|
1.1 ! root 1: /* ! 2: * signal handling ! 3: */ ! 4: ! 5: #include <stddef.h> ! 6: #include <stdlib.h> ! 7: #include <stdio.h> ! 8: #include <string.h> ! 9: #include <errno.h> ! 10: #include <signal.h> ! 11: #include <setjmp.h> ! 12: #include "sh.h" ! 13: #include "lex.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: #if !COHERENT ! 21: {SIGILL, "ILL", "Illegal instruction"}, ! 22: #endif ! 23: {SIGTRAP, "TRAP", "Trace trap"}, ! 24: #if !COHERENT ! 25: {SIGIOT, "IOT", "Abort"}, ! 26: {SIGEMT, "EMT", "EMT trap"}, ! 27: {SIGFPE, "FPE", "Floating exception"}, ! 28: #endif ! 29: {SIGKILL, "KILL", "Killed"}, ! 30: #if !COHERENT ! 31: {SIGBUS, "BUS", "Bus error"}, ! 32: #endif ! 33: {SIGSEGV, "SEGV", "Memory fault"}, ! 34: {SIGSYS, "SYS", "Bad system call"}, ! 35: {SIGPIPE, "PIPE", "Broken pipe"}, ! 36: {SIGALRM, "ALRM", "Alarm clock"}, ! 37: {SIGTERM, "TERM", "Terminated"}, ! 38: #if JOBS /* todo: need to be more portable */ ! 39: {SIGURG, "URG", "Urgent condition"}, /* BSDism */ ! 40: {SIGSTOP, "STOP", "Stop (signal)"}, ! 41: {SIGTSTP, "TSTP", "Stop"}, ! 42: {SIGCONT, "CONT", "Continue"}, ! 43: {SIGCHLD, "CHLD", "Waiting children"}, ! 44: {SIGTTIN, "TTIN", "Stop (tty input)"}, ! 45: {SIGTTOU, "TTOU", "Stop (tty output)"}, ! 46: #endif ! 47: }; ! 48: ! 49: /* ! 50: * compare two strings, mapping the case of the first string in ! 51: * case the second string was lower case. ! 52: */ ! 53: int ! 54: namecmp(s1, s2) ! 55: char *s1, *s2; ! 56: { ! 57: while (*s1) { ! 58: if (*s1 != *s2 && (!isalpha(*s1) || tolower(*s1) != *s2)) ! 59: break; ! 60: ++s1; ++s2; ! 61: } ! 62: return (*s1 - *s2); ! 63: } ! 64: ! 65: Trap * ! 66: gettrap(name) ! 67: char *name; ! 68: { ! 69: int i; ! 70: register Trap *p; ! 71: ! 72: if (digit(*name)) { ! 73: i = getn(name); ! 74: return (0 <= i && i < SIGNALS) ? &sigtraps[i] : NULL; ! 75: } ! 76: #if 0 ! 77: if (strcmp("ERR", name) == 0) ! 78: return &e.loc->err; ! 79: if (strcmp("EXIT", name) == 0) ! 80: return &e.loc->exit; ! 81: #endif ! 82: for (p = sigtraps, i = SIGNALS; --i >= 0; p++) ! 83: if (namecmp(p->name, name) == 0) ! 84: return p; ! 85: return NULL; ! 86: } ! 87: ! 88: /* ! 89: * trap signal handler ! 90: */ ! 91: void ! 92: trapsig(i) ! 93: int i; ! 94: { ! 95: trap = sigtraps[i].set = 1; ! 96: ! 97: if (i == SIGINT && e.type == E_PARSE) { ! 98: if (source && source->type == STTY) ! 99: source->str = null; ! 100: /* dangerous but necessary to deal with BSD silly signals */ ! 101: longjmp(e.jbuf, 1); ! 102: } ! 103: (void) signal(i, trapsig); /* todo: use sigact */ ! 104: } ! 105: ! 106: /* ! 107: * run any pending traps ! 108: */ ! 109: runtraps() ! 110: { ! 111: int i; ! 112: register Trap *p; ! 113: ! 114: for (p = sigtraps, i = SIGNALS; --i >= 0; p++) ! 115: if (p->set) ! 116: runtrap(p); ! 117: trap = 0; ! 118: } ! 119: ! 120: runtrap(p) ! 121: Trap *p; ! 122: { ! 123: char *trapstr; ! 124: ! 125: p->set = 0; ! 126: if ((trapstr = p->trap) == NULL) ! 127: if (p->signal == SIGINT) ! 128: unwind(); /* return to shell() */ ! 129: else ! 130: return; ! 131: if (p->signal == 0) /* ??? */ ! 132: p->trap = 0; ! 133: command(trapstr); ! 134: } ! 135: ! 136: /* restore signals for children */ ! 137: cleartraps() ! 138: { ! 139: int i; ! 140: register Trap *p; ! 141: ! 142: for (i = SIGNALS, p = sigtraps; --i >= 0; p++) { ! 143: p->set = 0; ! 144: if (p->ourtrap && signal(p->signal, SIG_IGN) != SIG_IGN) ! 145: (void) signal(p->signal, SIG_DFL); ! 146: } ! 147: } ! 148: ! 149: ignoresig(i) ! 150: int i; ! 151: { ! 152: if (signal(i, SIG_IGN) != SIG_IGN) ! 153: sigtraps[i].sig_dfl = 1; ! 154: } ! 155: ! 156: restoresigs() ! 157: { ! 158: int i; ! 159: register Trap *p; ! 160: ! 161: for (p = sigtraps, i = SIGNALS; --i >= 0; p++) ! 162: if (p->sig_dfl) { ! 163: p->sig_dfl = 0; ! 164: (void) signal(p->signal, SIG_DFL); ! 165: } ! 166: } ! 167:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.