|
|
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: if (i < 0 || i >= (sizeof(sigtraps)/sizeof(sigtraps[0]))) { ! 96: printf("ksh: trapsig(%08x)\n", i); ! 97: exit(1); ! 98: } ! 99: ! 100: trap = sigtraps[i].set = 1; ! 101: ! 102: if (i == SIGINT && e.type == E_PARSE) { ! 103: if (source && source->type == STTY) ! 104: source->str = null; ! 105: /* dangerous but necessary to deal with BSD silly signals ! 106: printf("SIGINT caught, ready to longjmp...\n"); */ ! 107: longjmp(e.jbuf, 1); ! 108: } ! 109: (void) signal(i, trapsig); /* todo: use sigact */ ! 110: } ! 111: ! 112: /* ! 113: * run any pending traps ! 114: */ ! 115: runtraps() ! 116: { ! 117: int i; ! 118: register Trap *p; ! 119: ! 120: for (p = sigtraps, i = SIGNALS; --i >= 0; p++) ! 121: if (p->set) ! 122: runtrap(p); ! 123: trap = 0; ! 124: } ! 125: ! 126: runtrap(p) ! 127: Trap *p; ! 128: { ! 129: char *trapstr; ! 130: ! 131: p->set = 0; ! 132: if ((trapstr = p->trap) == NULL) ! 133: if (p->signal == SIGINT) ! 134: unwind(); /* return to shell() */ ! 135: else ! 136: return; ! 137: if (p->signal == 0) /* ??? */ ! 138: p->trap = 0; ! 139: command(trapstr); ! 140: } ! 141: ! 142: /* restore signals for children */ ! 143: cleartraps() ! 144: { ! 145: int i; ! 146: register Trap *p; ! 147: ! 148: for (i = SIGNALS, p = sigtraps; --i >= 0; p++) { ! 149: p->set = 0; ! 150: if (p->ourtrap && signal(p->signal, SIG_IGN) != SIG_IGN) ! 151: (void) signal(p->signal, SIG_DFL); ! 152: } ! 153: } ! 154: ! 155: ignoresig(i) ! 156: int i; ! 157: { ! 158: if (signal(i, SIG_IGN) != SIG_IGN) ! 159: sigtraps[i].sig_dfl = 1; ! 160: } ! 161: ! 162: restoresigs() ! 163: { ! 164: int i; ! 165: register Trap *p; ! 166: ! 167: for (p = sigtraps, i = SIGNALS; --i >= 0; p++) ! 168: if (p->sig_dfl) { ! 169: p->sig_dfl = 0; ! 170: (void) signal(p->signal, SIG_DFL); ! 171: } ! 172: } ! 173:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.