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