|
|
1.1 root 1: #include <signal.h>
2: #include <errno.h>
3: /*
4: * signal system call interface package.
5: */
6: extern errno;
7:
8: #ifdef PDP11
9: #define BYTESPERVEC 4 /* size of machine language vector */
10: extern char mvectors[NSIG+1][BYTESPERVEC];
11: #endif
12:
13: static int (*cactions[NSIG+1])(); /* saved callers signal actions */
14: static char setflg[NSIG+1]; /* =1 means action perm ``sigset'' */
15: int (*sigsys())();
16: int _sigcatch();
17:
18: /*
19: * old signal protocol. when signal occurs, further
20: * instances of same signal are not blocked, so that
21: * recursive signals are possible. the action will
22: * not be re-enabled by these routines when return
23: * is made from the interrupt (compare sigset).
24: */
25: int (*
26: signal(signum, action))()
27: register int signum;
28: register int (*action)();
29: {
30: register int (*retval)();
31:
32: if (signum <= 0 || signum > NSIG) {
33: errno = EINVAL;
34: return (BADSIG);
35: }
36: retval = cactions[signum];
37: cactions[signum] = action;
38: if (action != SIG_IGN && action != SIG_DFL && action != SIG_HOLD)
39: if (SIGISDEFER(action))
40: #ifdef PDP11
41: action = DEFERSIG(mvectors[signum]);
42: else
43: action = (int (*)())(int)mvectors[signum];
44: #else
45: action = DEFERSIG(_sigcatch);
46: else
47: action = _sigcatch;
48: #endif
49: action = sigsys(signum, action);
50: if (action == SIG_IGN || action == SIG_DFL || action == SIG_HOLD)
51: retval = action;
52: setflg[signum] = 0; /* 'tis fleeting (madness may take its toll) */
53: return (retval);
54: }
55:
56: /*
57: * set ``permanent'' action for this signal. if a function,
58: * it will be deferred when interupt occurs and enabled again
59: * when return occurs. after sigset, sighold and sigrelse can
60: * be used to protect signum signal critical sections.
61: */
62: int (*
63: sigset(signum, action))()
64: register int signum;
65: register int (*action)();
66: {
67: register int (*retval)();
68:
69: if (signum <= 0 || signum > NSIG) {
70: errno = EINVAL;
71: return (BADSIG);
72: }
73: retval = cactions[signum];
74: cactions[signum] = action;
75: if (action != SIG_IGN && action != SIG_DFL && action != SIG_HOLD)
76: action = DEFERSIG(_sigcatch);
77: action = sigsys(signum, action);
78: if (action == SIG_IGN || action == SIG_DFL || action == SIG_HOLD)
79: retval = action;
80: setflg[signum] = 1; /* don't want to lose control! */
81: return (retval);
82: }
83:
84: /*
85: * temporarily hold a signal until further notice
86: * via sigpause or sigrelse
87: */
88: sighold(signum)
89: register int signum;
90: {
91:
92: if (signum <= 0 || signum > NSIG) {
93: errno = EINVAL;
94: return;
95: }
96: sigsys(signum, SIG_HOLD);
97: }
98:
99: /*
100: * atomically release the signal and pause
101: * if no signals pending. signal will normally
102: * be held on return (unless an routine called at
103: * interrupt time resets it).
104: */
105: sigpause(signum)
106: register signum;
107: {
108:
109: if (signum <= 0 || signum > NSIG || setflg[signum] == 0) {
110: errno = EINVAL;
111: return;
112: }
113: #ifdef PDP11
114: sigsys(signum|SIGDOPAUSE, DEFERSIG(mvectors[signum]));
115: #else
116: sigsys(signum|SIGDOPAUSE, DEFERSIG(_sigcatch));
117: #endif
118: }
119:
120: /*
121: * re-enable signals after sighold or possibly after sigpause
122: */
123: sigrelse(signum)
124: register signum;
125: {
126: if (signum <= 0 || signum > NSIG || setflg[signum] == 0) {
127: errno = EINVAL;
128: return (-1);
129: }
130: #ifdef PDP11
131: sigsys(signum, DEFERSIG(mvectors[signum]));
132: #else
133: sigsys(signum, DEFERSIG(_sigcatch));
134: #endif
135: return (0);
136: }
137:
138: /*
139: * ignore signal
140: */
141: sigignore(signum)
142: int signum;
143: {
144:
145: sigsys(signum, SIG_IGN);
146: }
147:
148: #ifdef PDP11
149: /*
150: * called at interrupt time. on pdp11 assembly language
151: * routine resets signal catch to returned action, if
152: * returned action is not SIG_DFL.
153: */
154: int (*
155: _sigcatch(signum))()
156: register signum;
157: {
158:
159: (*cactions[signum])(signum); /* call the C routine */
160: if (setflg[signum])
161: return (DEFERSIG(mvectors[signum]);
162: else
163: return (SIG_DFL); /* old protocol */
164: }
165: #else
166: /*
167: * called at interrupt time. on vax, sigpeel will peel
168: * off the interrupt frames and reenable the signal with
169: * the argument action (cleanly). if the action is
170: * SIG_DFL sigpeel will do nothing, but we can as well
171: * return ourselves without its help.
172: */
173: _sigcatch(signum, code)
174: register signum;
175: int code;
176: {
177:
178: (*cactions[signum])(signum);
179: if (setflg[signum]) {
180: sigpeel(signum, DEFERSIG(_sigcatch));
181: /*NOTREACHED*/
182: }
183: /* old protocol, just return */
184: }
185: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.