|
|
1.1 root 1: /*
2:
3: Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
4:
5: */
6:
7:
8:
9: /* dossig.c:: dos signal handling routines */
10:
11:
12:
13: #include "mint.h"
14:
15:
16:
17: /*
18:
19: * send a signal to another process. If pid > 0, send the signal just to
20:
21: * that process. If pid < 0, send the signal to all processes whose process
22:
23: * group is -pid. If pid == 0, send the signal to all processes with the
24:
25: * same process group id.
26:
27: *
28:
29: * note: post_sig just posts the signal to the process.
30:
31: */
32:
33:
34:
35: long
36:
37: p_kill(pid, sig)
38:
39: int pid, sig;
40:
41: {
42:
43: PROC *p;
44:
45:
46:
47: TRACE("Pkill(%d, %d)", pid, sig);
48:
49: if (sig < 0 || sig >= NSIG) {
50:
51: DEBUG("Pkill: signal out of range");
52:
53: return ERANGE;
54:
55: }
56:
57:
58:
59: if (pid < 0)
60:
61: return killgroup(-pid, sig);
62:
63: else if (pid == 0)
64:
65: return killgroup(curproc->pgrp, sig);
66:
67: else {
68:
69: p = pid2proc(pid);
70:
71: if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
72:
73: DEBUG("Pkill: pid %d not found", pid);
74:
75: return EFILNF;
76:
77: }
78:
79: if (curproc->euid && curproc->ruid != p->ruid) {
80:
81: DEBUG("Pkill: wrong user");
82:
83: return EACCDN;
84:
85: }
86:
87:
88:
89: /* if the user sends signal 0, don't deliver it -- for users, signal
90:
91: * 0 is a null signal used to test the existence of a process
92:
93: */
94:
95: if (sig != 0)
96:
97: post_sig(p, sig);
98:
99: }
100:
101:
102:
103: check_sigs();
104:
105: TRACE("Pkill: returning OK");
106:
107: return 0;
108:
109: }
110:
111:
112:
113: /*
114:
115: * set a user-specified signal handler, POSIX.1 style
116:
117: * "oact", if non-null, gets the old signal handling
118:
119: * behaviour; "act", if non-null, specifies new
120:
121: * behaviour
122:
123: */
124:
125:
126:
127: long
128:
129: p_sigaction(sig, act, oact)
130:
131: int sig;
132:
133: const struct sigaction *act;
134:
135: struct sigaction *oact;
136:
137: {
138:
139: TRACE("Psigaction(%d)", sig);
140:
141: if (sig < 1 || sig >= NSIG)
142:
143: return ERANGE;
144:
145: if (act && (sig == SIGKILL || sig == SIGSTOP))
146:
147: return EACCDN;
148:
149: if (oact) {
150:
151: oact->sa_handler = curproc->sighandle[sig];
152:
153: oact->sa_mask = curproc->sigextra[sig];
154:
155: oact->sa_flags = curproc->sigflags[sig];
156:
157: }
158:
159: if (act) {
160:
161: curproc->sighandle[sig] = act->sa_handler;
162:
163: curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
164:
165: curproc->sigflags[sig] = act->sa_flags;
166:
167:
168:
169: /* various special things that should happen */
170:
171: if (act->sa_handler == SIG_IGN) {
172:
173: /* discard pending signals */
174:
175: curproc->sigpending &= ~(1L<<sig);
176:
177: }
178:
179:
180:
181: /* I dunno if this is right, but bash seems to expect it */
182:
183: curproc->sigmask &= ~(1L<<sig);
184:
185: }
186:
187: return 0;
188:
189: }
190:
191:
192:
193: /*
194:
195: * set a user-specified signal handler
196:
197: */
198:
199:
200:
201: long
202:
203: p_signal(sig, handler)
204:
205: int sig;
206:
207: long handler;
208:
209: {
210:
211: long oldhandle;
212:
213:
214:
215: TRACE("Psignal(%d, %lx)", sig, handler);
216:
217: if (sig < 1 || sig >= NSIG)
218:
219: return ERANGE;
220:
221: if (sig == SIGKILL || sig == SIGSTOP)
222:
223: return EACCDN;
224:
225: oldhandle = curproc->sighandle[sig];
226:
227: curproc->sighandle[sig] = handler;
228:
229: curproc->sigextra[sig] = 0;
230:
231: curproc->sigflags[sig] = 0;
232:
233:
234:
235: /* various special things that should happen */
236:
237: if (handler == SIG_IGN) {
238:
239: /* discard pending signals */
240:
241: curproc->sigpending &= ~(1L<<sig);
242:
243: }
244:
245:
246:
247: /* I dunno if this is right, but bash seems to expect it */
248:
249: curproc->sigmask &= ~(1L<<sig);
250:
251:
252:
253: return oldhandle;
254:
255: }
256:
257:
258:
259: /*
260:
261: * block some signals. Returns the old signal mask.
262:
263: */
264:
265:
266:
267: long
268:
269: p_sigblock(mask)
270:
271: ulong mask;
272:
273: {
274:
275: ulong oldmask;
276:
277:
278:
279: TRACE("Psigblock(%lx)",mask);
280:
281: /* some signals (e.g. SIGKILL) can't be masked */
282:
283: mask &= ~(UNMASKABLE);
284:
285: oldmask = curproc->sigmask;
286:
287: curproc->sigmask |= mask;
288:
289: return oldmask;
290:
291: }
292:
293:
294:
295: /*
296:
297: * set the signals that we're blocking. Some signals (e.g. SIGKILL)
298:
299: * can't be masked.
300:
301: * Returns the old mask.
302:
303: */
304:
305:
306:
307: long
308:
309: p_sigsetmask(mask)
310:
311: ulong mask;
312:
313: {
314:
315: ulong oldmask;
316:
317:
318:
319: TRACE("Psigsetmask(%lx)",mask);
320:
321: oldmask = curproc->sigmask;
322:
323: curproc->sigmask = mask & ~(UNMASKABLE);
324:
325: check_sigs(); /* maybe we unmasked something */
326:
327: return oldmask;
328:
329: }
330:
331:
332:
333: /*
334:
335: * p_sigpending: return which signals are pending delivery
336:
337: */
338:
339:
340:
341: long
342:
343: p_sigpending()
344:
345: {
346:
347: TRACE("Psigpending()");
348:
349: check_sigs(); /* clear out any that are going to be delivered soon */
350:
351: return curproc->sigpending;
352:
353: }
354:
355:
356:
357: /*
358:
359: * p_sigpause: atomically set the signals that we're blocking, then pause.
360:
361: * Some signals (e.g. SIGKILL) can't be masked.
362:
363: */
364:
365:
366:
367: long
368:
369: p_sigpause(mask)
370:
371: ulong mask;
372:
373: {
374:
375: ulong oldmask;
376:
377:
378:
379: TRACE("Psigpause(%lx)", mask);
380:
381: oldmask = curproc->sigmask;
382:
383: curproc->sigmask = mask & ~(UNMASKABLE);
384:
385: if (curproc->sigpending & ~(curproc->sigmask))
386:
387: check_sigs(); /* a signal is immediately pending */
388:
389: else
390:
391: sleep(IO_Q, -1L);
392:
393: curproc->sigmask = oldmask;
394:
395: check_sigs(); /* maybe we unmasked something */
396:
397: TRACE("Psigpause: returning OK");
398:
399: return 0;
400:
401: }
402:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.