|
|
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.