|
|
1.1 root 1: /*
2:
1.1.1.4 ! root 3: Copyright 1990,1991,1992,1994 Eric R. Smith.
1.1.1.3 root 4:
5: All rights reserved.
1.1 root 6:
7: */
8:
9:
10:
11: /* dossig.c:: dos signal handling routines */
12:
13:
14:
15: #include "mint.h"
16:
17:
18:
1.1.1.4 ! root 19: void ARGS_ON_STACK sig_user P_((int vec));
! 20:
! 21:
! 22:
1.1 root 23: /*
24:
25: * send a signal to another process. If pid > 0, send the signal just to
26:
27: * that process. If pid < 0, send the signal to all processes whose process
28:
29: * group is -pid. If pid == 0, send the signal to all processes with the
30:
31: * same process group id.
32:
33: *
34:
35: * note: post_sig just posts the signal to the process.
36:
37: */
38:
39:
40:
1.1.1.2 root 41: long ARGS_ON_STACK
1.1 root 42:
43: p_kill(pid, sig)
44:
45: int pid, sig;
46:
47: {
48:
49: PROC *p;
50:
1.1.1.4 ! root 51: long r;
! 52:
1.1 root 53:
54:
1.1.1.2 root 55: TRACE(("Pkill(%d, %d)", pid, sig));
1.1 root 56:
57: if (sig < 0 || sig >= NSIG) {
58:
1.1.1.2 root 59: DEBUG(("Pkill: signal out of range"));
1.1 root 60:
61: return ERANGE;
62:
63: }
64:
65:
66:
67: if (pid < 0)
68:
1.1.1.4 ! root 69: r = killgroup(-pid, sig, 0);
1.1 root 70:
71: else if (pid == 0)
72:
1.1.1.4 ! root 73: r = killgroup(curproc->pgrp, sig, 0);
1.1 root 74:
75: else {
76:
77: p = pid2proc(pid);
78:
79: if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
80:
1.1.1.2 root 81: DEBUG(("Pkill: pid %d not found", pid));
1.1 root 82:
83: return EFILNF;
84:
85: }
86:
87: if (curproc->euid && curproc->ruid != p->ruid) {
88:
1.1.1.2 root 89: DEBUG(("Pkill: wrong user"));
1.1 root 90:
91: return EACCDN;
92:
93: }
94:
95:
96:
97: /* if the user sends signal 0, don't deliver it -- for users, signal
98:
99: * 0 is a null signal used to test the existence of a process
100:
101: */
102:
103: if (sig != 0)
104:
105: post_sig(p, sig);
106:
1.1.1.4 ! root 107: r = 0;
! 108:
1.1 root 109: }
110:
111:
112:
1.1.1.4 ! root 113: if (r == 0) {
1.1 root 114:
1.1.1.4 ! root 115: check_sigs();
1.1 root 116:
1.1.1.4 ! root 117: TRACE(("Pkill: returning OK"));
! 118:
! 119: }
! 120:
! 121: return r;
1.1 root 122:
123: }
124:
125:
126:
127: /*
128:
129: * set a user-specified signal handler, POSIX.1 style
130:
131: * "oact", if non-null, gets the old signal handling
132:
133: * behaviour; "act", if non-null, specifies new
134:
135: * behaviour
136:
137: */
138:
139:
140:
1.1.1.2 root 141: long ARGS_ON_STACK
1.1 root 142:
143: p_sigaction(sig, act, oact)
144:
145: int sig;
146:
147: const struct sigaction *act;
148:
149: struct sigaction *oact;
150:
151: {
152:
1.1.1.2 root 153: TRACE(("Psigaction(%d)", sig));
1.1 root 154:
155: if (sig < 1 || sig >= NSIG)
156:
157: return ERANGE;
158:
159: if (act && (sig == SIGKILL || sig == SIGSTOP))
160:
161: return EACCDN;
162:
163: if (oact) {
164:
165: oact->sa_handler = curproc->sighandle[sig];
166:
167: oact->sa_mask = curproc->sigextra[sig];
168:
1.1.1.2 root 169: oact->sa_flags = curproc->sigflags[sig] & SAUSER;
1.1 root 170:
171: }
172:
173: if (act) {
174:
1.1.1.2 root 175: ushort flags;
176:
177:
178:
1.1 root 179: curproc->sighandle[sig] = act->sa_handler;
180:
181: curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
182:
1.1.1.2 root 183:
184:
185: /* only the flags in SAUSER can be changed by the user */
186:
187: flags = curproc->sigflags[sig] & ~SAUSER;
188:
189: flags |= act->sa_flags & SAUSER;
190:
191: curproc->sigflags[sig] = flags;
1.1 root 192:
193:
194:
195: /* various special things that should happen */
196:
197: if (act->sa_handler == SIG_IGN) {
198:
199: /* discard pending signals */
200:
201: curproc->sigpending &= ~(1L<<sig);
202:
203: }
204:
205:
206:
207: /* I dunno if this is right, but bash seems to expect it */
208:
209: curproc->sigmask &= ~(1L<<sig);
210:
211: }
212:
213: return 0;
214:
215: }
216:
217:
218:
219: /*
220:
221: * set a user-specified signal handler
222:
223: */
224:
225:
226:
1.1.1.2 root 227: long ARGS_ON_STACK
1.1 root 228:
229: p_signal(sig, handler)
230:
231: int sig;
232:
233: long handler;
234:
235: {
236:
237: long oldhandle;
238:
239:
240:
1.1.1.2 root 241: TRACE(("Psignal(%d, %lx)", sig, handler));
1.1 root 242:
243: if (sig < 1 || sig >= NSIG)
244:
245: return ERANGE;
246:
247: if (sig == SIGKILL || sig == SIGSTOP)
248:
249: return EACCDN;
250:
251: oldhandle = curproc->sighandle[sig];
252:
253: curproc->sighandle[sig] = handler;
254:
255: curproc->sigextra[sig] = 0;
256:
257: curproc->sigflags[sig] = 0;
258:
259:
260:
261: /* various special things that should happen */
262:
263: if (handler == SIG_IGN) {
264:
265: /* discard pending signals */
266:
267: curproc->sigpending &= ~(1L<<sig);
268:
269: }
270:
271:
272:
273: /* I dunno if this is right, but bash seems to expect it */
274:
275: curproc->sigmask &= ~(1L<<sig);
276:
277:
278:
279: return oldhandle;
280:
281: }
282:
283:
284:
285: /*
286:
287: * block some signals. Returns the old signal mask.
288:
289: */
290:
291:
292:
1.1.1.2 root 293: long ARGS_ON_STACK
1.1 root 294:
295: p_sigblock(mask)
296:
297: ulong mask;
298:
299: {
300:
301: ulong oldmask;
302:
303:
304:
1.1.1.2 root 305: TRACE(("Psigblock(%lx)",mask));
1.1 root 306:
307: /* some signals (e.g. SIGKILL) can't be masked */
308:
309: mask &= ~(UNMASKABLE);
310:
311: oldmask = curproc->sigmask;
312:
313: curproc->sigmask |= mask;
314:
315: return oldmask;
316:
317: }
318:
319:
320:
321: /*
322:
323: * set the signals that we're blocking. Some signals (e.g. SIGKILL)
324:
325: * can't be masked.
326:
327: * Returns the old mask.
328:
329: */
330:
331:
332:
1.1.1.2 root 333: long ARGS_ON_STACK
1.1 root 334:
335: p_sigsetmask(mask)
336:
337: ulong mask;
338:
339: {
340:
341: ulong oldmask;
342:
343:
344:
1.1.1.2 root 345: TRACE(("Psigsetmask(%lx)",mask));
1.1 root 346:
347: oldmask = curproc->sigmask;
348:
349: curproc->sigmask = mask & ~(UNMASKABLE);
350:
351: check_sigs(); /* maybe we unmasked something */
352:
353: return oldmask;
354:
355: }
356:
357:
358:
359: /*
360:
361: * p_sigpending: return which signals are pending delivery
362:
363: */
364:
365:
366:
1.1.1.2 root 367: long ARGS_ON_STACK
1.1 root 368:
369: p_sigpending()
370:
371: {
372:
1.1.1.2 root 373: TRACE(("Psigpending()"));
1.1 root 374:
375: check_sigs(); /* clear out any that are going to be delivered soon */
376:
1.1.1.2 root 377:
378:
379: /* note that signal #0 is used internally, so we don't tell the process
380:
381: * about it
382:
383: */
384:
385: return curproc->sigpending & ~1L;
1.1 root 386:
387: }
388:
389:
390:
391: /*
392:
393: * p_sigpause: atomically set the signals that we're blocking, then pause.
394:
395: * Some signals (e.g. SIGKILL) can't be masked.
396:
397: */
398:
399:
400:
1.1.1.2 root 401: long ARGS_ON_STACK
1.1 root 402:
403: p_sigpause(mask)
404:
405: ulong mask;
406:
407: {
408:
409: ulong oldmask;
410:
411:
412:
1.1.1.2 root 413: TRACE(("Psigpause(%lx)", mask));
1.1 root 414:
415: oldmask = curproc->sigmask;
416:
417: curproc->sigmask = mask & ~(UNMASKABLE);
418:
419: if (curproc->sigpending & ~(curproc->sigmask))
420:
421: check_sigs(); /* a signal is immediately pending */
422:
423: else
424:
425: sleep(IO_Q, -1L);
426:
427: curproc->sigmask = oldmask;
428:
429: check_sigs(); /* maybe we unmasked something */
430:
1.1.1.2 root 431: TRACE(("Psigpause: returning OK"));
1.1 root 432:
433: return 0;
434:
435: }
436:
1.1.1.4 ! root 437:
! 438:
! 439: /*
! 440:
! 441: * p_sigintr: Set an exception vector to send us the specified signal.
! 442:
! 443: */
! 444:
! 445:
! 446:
! 447: typedef struct usig {
! 448:
! 449: int vec; /* exception vector number */
! 450:
! 451: int sig; /* signal to send */
! 452:
! 453: PROC *proc; /* process to get signal */
! 454:
! 455: long oldv; /* old exception vector value */
! 456:
! 457: struct usig *next; /* next entry ... */
! 458:
! 459: } usig;
! 460:
! 461:
! 462:
! 463: static usig *usiglst;
! 464:
! 465: extern long mcpu;
! 466:
! 467:
! 468:
! 469: long ARGS_ON_STACK
! 470:
! 471: p_sigintr(vec, sig)
! 472:
! 473: int vec;
! 474:
! 475: int sig;
! 476:
! 477: {
! 478:
! 479: extern void new_intr(); /* in intr.spp */
! 480:
! 481: long vec2;
! 482:
! 483: usig *new;
! 484:
! 485:
! 486:
! 487: if (!sig) /* ignore signal 0 */
! 488:
! 489: return 0;
! 490:
! 491:
! 492:
! 493: vec2 = (long) new_intr;
! 494:
! 495:
! 496:
! 497: #ifndef ONLY030
! 498:
! 499: if (mcpu == 0)
! 500:
! 501: /* put vector number in high byte of vector address */
! 502:
! 503: vec2 |= ((long) vec) << 24;
! 504:
! 505: #endif
! 506:
! 507: new = kmalloc(sizeof(usig));
! 508:
! 509: if (!new) /* hope this never happens...! */
! 510:
! 511: return ENSMEM;
! 512:
! 513: new->vec = vec;
! 514:
! 515: new->sig = sig;
! 516:
! 517: new->proc = curproc;
! 518:
! 519: new->next = usiglst; /* simple unsorted list... */
! 520:
! 521: usiglst = new;
! 522:
! 523:
! 524:
! 525: new->oldv = setexc(vec, vec2);
! 526:
! 527: return new->oldv;
! 528:
! 529: }
! 530:
! 531:
! 532:
! 533: /*
! 534:
! 535: * Find the process that requested this interrupt, and send it a signal.
! 536:
! 537: * Called at interrupt time by new_intr() from intr.spp, with interrupt
! 538:
! 539: * vector number on the stack.
! 540:
! 541: */
! 542:
! 543:
! 544:
! 545: void ARGS_ON_STACK
! 546:
! 547: sig_user(vec)
! 548:
! 549: int vec;
! 550:
! 551: {
! 552:
! 553: usig *ptr;
! 554:
! 555:
! 556:
! 557: for (ptr = usiglst; ptr; ptr=ptr->next)
! 558:
! 559: if (vec == ptr->vec) {
! 560:
! 561: if (ptr->proc->wait_q != ZOMBIE_Q &&
! 562:
! 563: ptr->proc->wait_q != TSR_Q) {
! 564:
! 565: post_sig(ptr->proc, ptr->sig);
! 566:
! 567: }
! 568:
! 569: #if 0 /* Search entire list, to allow multiple processes to respond to
! 570:
! 571: the same interrupt. (Why/when would you want that?) */
! 572:
! 573: break;
! 574:
! 575: #endif
! 576:
! 577: }
! 578:
! 579: /*
! 580:
! 581: * Clear in-service bit for ST MFP interrupts
! 582:
! 583: */
! 584:
! 585: if (vec >= 64 && vec < 80) {
! 586:
! 587: char *mfp, c;
! 588:
! 589:
! 590:
! 591: if (vec < 72) /* Register B */
! 592:
! 593: mfp = (char *)0xfffffa11L;
! 594:
! 595: else /* Register A */
! 596:
! 597: mfp = (char *)0xfffffa0fL;
! 598:
! 599: c = 1 << (vec & 7);
! 600:
! 601:
! 602:
! 603: *mfp = ~c;
! 604:
! 605: }
! 606:
! 607: }
! 608:
! 609:
! 610:
! 611: /*
! 612:
! 613: * cancelsigintrs: remove any interrupts requested by this process, called
! 614:
! 615: * at process termination.
! 616:
! 617: */
! 618:
! 619: void
! 620:
! 621: cancelsigintrs()
! 622:
! 623: {
! 624:
! 625: usig *ptr, **old, *nxt;
! 626:
! 627: short s = spl7();
! 628:
! 629:
! 630:
! 631: for (old=&usiglst, ptr=usiglst; ptr; ) {
! 632:
! 633: nxt = ptr->next;
! 634:
! 635: if (ptr->proc == curproc) {
! 636:
! 637: setexc(ptr->vec, ptr->oldv);
! 638:
! 639: *old = nxt;
! 640:
! 641: kfree(ptr);
! 642:
! 643: } else {
! 644:
! 645: old = &(ptr->next);
! 646:
! 647: }
! 648:
! 649: ptr = nxt;
! 650:
! 651: }
! 652:
! 653: spl(s);
! 654:
! 655: }
! 656:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.