|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* Copyright (c) 1995-1998 Apple Computer, Inc. All Rights Reserved */
23: /*
24: * Copyright (c) 1982, 1986, 1989, 1991, 1993
25: * The Regents of the University of California. All rights reserved.
26: * (c) UNIX System Laboratories, Inc.
27: * All or some portions of this file are derived from material licensed
28: * to the University of California by American Telephone and Telegraph
29: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
30: * the permission of UNIX System Laboratories, Inc.
31: *
32: * Redistribution and use in source and binary forms, with or without
33: * modification, are permitted provided that the following conditions
34: * are met:
35: * 1. Redistributions of source code must retain the above copyright
36: * notice, this list of conditions and the following disclaimer.
37: * 2. Redistributions in binary form must reproduce the above copyright
38: * notice, this list of conditions and the following disclaimer in the
39: * documentation and/or other materials provided with the distribution.
40: * 3. All advertising materials mentioning features or use of this software
41: * must display the following acknowledgement:
42: * This product includes software developed by the University of
43: * California, Berkeley and its contributors.
44: * 4. Neither the name of the University nor the names of its contributors
45: * may be used to endorse or promote products derived from this software
46: * without specific prior written permission.
47: *
48: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58: * SUCH DAMAGE.
59: *
60: * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
61: */
62:
63: #define SIGPROP /* include signal properties table */
64: #include <sys/param.h>
65: #include <sys/signalvar.h>
66: #include <sys/resourcevar.h>
67: #include <sys/namei.h>
68: #include <sys/vnode.h>
69: #include <sys/proc.h>
70: #include <sys/systm.h>
71: #include <sys/timeb.h>
72: #include <sys/times.h>
73: #include <sys/buf.h>
74: #include <sys/acct.h>
75: #include <sys/file.h>
76: #include <sys/kernel.h>
77: #include <sys/wait.h>
78: #include <sys/ktrace.h>
79: #include <sys/syslog.h>
80: #include <sys/stat.h>
81:
82: #include <sys/mount.h>
83:
84: #include <kern/cpu_number.h>
85:
86: #include <sys/vm.h>
87: #include <sys/user.h> /* for coredump */
88: #include <kern/ast.h> /* for APC support */
89: #include <kern/thread.h>
90:
91: void stop __P((struct proc *p));
92: int cansignal __P((struct proc *, struct pcred *, struct proc *, int));
93: int killpg1 __P((struct proc *, int, int, int));
94: void sigexit __P((struct proc *, int));
95: void setsigvec __P((struct proc *, int, struct sigaction *));
96: void exit1 __P((struct proc *, int));
97:
98: /*
99: * Can process p, with pcred pc, send the signal signum to process q?
100: */
101: int
102: cansignal(p, pc, q, signum)
103: struct proc *p;
104: struct pcred *pc;
105: struct proc *q;
106: int signum;
107: {
108: if (pc->pc_ucred->cr_uid == 0)
109: return (1); /* root can always signal */
110:
111: if (signum == SIGCONT && q->p_session == p->p_session)
112: return (1); /* SIGCONT in session */
113:
114: /*
115: * Using kill(), only certain signals can be sent to setugid
116: * child processes
117: */
118: if (q->p_flag & P_SUGID) {
119: switch (signum) {
120: case 0:
121: case SIGKILL:
122: case SIGINT:
123: case SIGTERM:
124: case SIGSTOP:
125: case SIGTTIN:
126: case SIGTTOU:
127: case SIGTSTP:
128: case SIGHUP:
129: case SIGUSR1:
130: case SIGUSR2:
131: if (pc->p_ruid == q->p_cred->p_ruid ||
132: pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
133: pc->p_ruid == q->p_ucred->cr_uid ||
134: pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
135: return (1);
136: }
137: return (0);
138: }
139:
140: /* XXX
141: * because the P_SUGID test exists, this has extra tests which
142: * could be removed.
143: */
144: if (pc->p_ruid == q->p_cred->p_ruid ||
145: pc->p_ruid == q->p_cred->p_svuid ||
146: pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
147: pc->pc_ucred->cr_uid == q->p_cred->p_svuid ||
148: pc->p_ruid == q->p_ucred->cr_uid ||
149: pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
150: return (1);
151: return (0);
152: }
153:
154: struct sigaction_args {
155: int signum;
156: struct sigaction *nsa;
157: struct sigaction *osa;
158: };
159: /* ARGSUSED */
160: int
161: sigaction(p, uap, retval)
162: struct proc *p;
163: register struct sigaction_args *uap;
164: register_t *retval;
165: {
166: struct sigaction vec;
167: register struct sigaction *sa;
168: register struct sigacts *ps = p->p_sigacts;
169: register int signum;
170: int bit, error;
171:
172: signum = uap->signum;
173: if (signum <= 0 || signum >= NSIG ||
174: signum == SIGKILL || signum == SIGSTOP)
175: return (EINVAL);
176: sa = &vec;
177: if (uap->osa) {
178: sa->sa_handler = ps->ps_sigact[signum];
179: sa->sa_mask = ps->ps_catchmask[signum];
180: bit = sigmask(signum);
181: sa->sa_flags = 0;
182: if ((ps->ps_sigonstack & bit) != 0)
183: sa->sa_flags |= SA_ONSTACK;
184: if ((ps->ps_sigintr & bit) == 0)
185: sa->sa_flags |= SA_RESTART;
186: if (p->p_flag & P_NOCLDSTOP)
187: sa->sa_flags |= SA_NOCLDSTOP;
188: if (error = copyout((caddr_t)sa, (caddr_t)uap->osa,
189: sizeof (vec)))
190: return (error);
191: }
192: if (uap->nsa) {
193: if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
194: sizeof (vec)))
195: return (error);
196: setsigvec(p, signum, sa);
197: }
198: return (0);
199: }
200: bsd_resetbit(thread_act_t th_act, int bit)
201: {
202: struct uthread *ut;
203: ut = get_bsdthread_info(th_act);
204: if (ut) {
205: ut->uu_sig &= ~bit;
206: }
207: }
208:
209: void
210: setsigvec(p, signum, sa)
211: register struct proc *p;
212: int signum;
213: register struct sigaction *sa;
214: {
215: register struct sigacts *ps = p->p_sigacts;
216: register int bit;
217:
218: bit = sigmask(signum);
219: /*
220: * Change setting atomically.
221: */
222: (void) splhigh();
223: simple_lock(&p->siglock);
224: ps->ps_sigact[signum] = sa->sa_handler;
225: ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
226: if ((sa->sa_flags & SA_RESTART) == 0)
227: ps->ps_sigintr |= bit;
228: else
229: ps->ps_sigintr &= ~bit;
230: if (sa->sa_flags & SA_ONSTACK)
231: ps->ps_sigonstack |= bit;
232: else
233: ps->ps_sigonstack &= ~bit;
234: if (sa->sa_flags & SA_USERTRAMP)
235: ps->ps_usertramp |= bit;
236: else
237: ps->ps_usertramp &= ~bit;
238: if (signum == SIGCHLD) {
239: if (sa->sa_flags & SA_NOCLDSTOP)
240: p->p_flag |= P_NOCLDSTOP;
241: else
242: p->p_flag &= ~P_NOCLDSTOP;
243: }
244: /*
245: * Set bit in p_sigignore for signals that are set to SIG_IGN,
246: * and for signals set to SIG_DFL where the default is to ignore.
247: * However, don't put SIGCONT in p_sigignore,
248: * as we have to restart the process.
249: */
250: if (sa->sa_handler == SIG_IGN ||
251: (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
252: p->p_siglist &= ~bit; /* never to be seen again */
253: /*
254: * If this is a thread signal, clean out the
255: * threads as well.
256: */
257: if (bit & threadmask) {
258: register task_t task = p->task;
259:
260: task_act_iterate_wth_args(task, bsd_resetbit, bit);
261: }
262: if (signum != SIGCONT)
263: p->p_sigignore |= bit; /* easier in psignal */
264: p->p_sigcatch &= ~bit;
265: } else {
266: p->p_sigignore &= ~bit;
267: if (sa->sa_handler == SIG_DFL)
268: p->p_sigcatch &= ~bit;
269: else
270: p->p_sigcatch |= bit;
271: }
272: simple_unlock(&p->siglock);
273: (void) spl0();
274: }
275:
276: /*
277: * Initialize signal state for process 0;
278: * set to ignore signals that are ignored by default.
279: */
280: void
281: siginit(p)
282: struct proc *p;
283: {
284: register int i;
285:
286: for (i = 0; i < NSIG; i++)
287: if (sigprop[i] & SA_IGNORE && i != SIGCONT)
288: p->p_sigignore |= sigmask(i);
289: }
290:
291: /*
292: * Reset signals for an exec of the specified process.
293: */
294: void
295: execsigs(p)
296: register struct proc *p;
297: {
298: register struct sigacts *ps = p->p_sigacts;
299: register int nc, mask;
300:
301: /*
302: * Reset caught signals. Held signals remain held
303: * through p_sigmask (unless they were caught,
304: * and are now ignored by default).
305: */
306: while (p->p_sigcatch) {
307: nc = ffs((long)p->p_sigcatch);
308: mask = sigmask(nc);
309: p->p_sigcatch &= ~mask;
310: if (sigprop[nc] & SA_IGNORE) {
311: if (nc != SIGCONT)
312: p->p_sigignore |= mask;
313: p->p_siglist &= ~mask;
314: }
315: ps->ps_sigact[nc] = SIG_DFL;
316: }
317: /*
318: * Reset stack state to the user stack.
319: * Clear set of signals caught on the signal stack.
320: */
321: ps->ps_sigstk.ss_flags = SA_DISABLE;
322: ps->ps_sigstk.ss_size = 0;
323: ps->ps_sigstk.ss_sp = 0;
324: ps->ps_flags = 0;
325: }
326:
327: /*
328: * Manipulate signal mask.
329: * Note that we receive new mask, not pointer,
330: * and return old mask as return value;
331: * the library stub does the rest.
332: */
333: struct sigprocmask_args {
334: int how;
335: sigset_t mask;
336: };
337: int
338: sigprocmask(p, uap, retval)
339: register struct proc *p;
340: struct sigprocmask_args *uap;
341: register_t *retval;
342: {
343: int error = 0;
344:
345: *retval = p->p_sigmask;
346: (void) splhigh();
347:
348: switch (uap->how) {
349: case SIG_BLOCK:
350: p->p_sigmask |= uap->mask &~ sigcantmask;
351: break;
352:
353: case SIG_UNBLOCK:
354: p->p_sigmask &= ~(uap->mask);
355: #ifdef BSD_USE_APC
356: thread_apc_set(current_act(), bsd_ast);
357: #else
358: thread_ast_set(current_act(), AST_BSD);
359: ast_on(AST_BSD);
360: #endif
361: break;
362:
363: case SIG_SETMASK:
364: p->p_sigmask = uap->mask &~ sigcantmask;
365: #ifdef BSD_USE_APC
366: thread_apc_set(current_act(), bsd_ast);
367: #else
368: thread_ast_set(current_act(), AST_BSD);
369: ast_on(AST_BSD);
370: #endif
371: break;
372:
373: default:
374: error = EINVAL;
375: break;
376: }
377: (void) spl0();
378: return (error);
379: }
380:
381: /* ARGSUSED */
382: int
383: sigpending(p, uap, retval)
384: struct proc *p;
385: void *uap;
386: register_t *retval;
387: {
388:
389: *retval = p->p_siglist;
390: return (0);
391: }
392:
393: #if COMPAT_43
394: /*
395: * Generalized interface signal handler, 4.3-compatible.
396: */
397: struct osigvec_args {
398: int signum;
399: struct sigvec *nsv;
400: struct sigvec *osv;
401: };
402: /* ARGSUSED */
403: int
404: osigvec(p, uap, retval)
405: struct proc *p;
406: register struct osigvec_args *uap;
407: register_t *retval;
408: {
409: struct sigvec vec;
410: register struct sigacts *ps = p->p_sigacts;
411: register struct sigvec *sv;
412: register int signum;
413: int bit, error;
414:
415: signum = uap->signum;
416: if (signum <= 0 || signum >= NSIG ||
417: signum == SIGKILL || signum == SIGSTOP)
418: return (EINVAL);
419: sv = &vec;
420: if (uap->osv) {
421: *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
422: sv->sv_mask = ps->ps_catchmask[signum];
423: bit = sigmask(signum);
424: sv->sv_flags = 0;
425: if ((ps->ps_sigonstack & bit) != 0)
426: sv->sv_flags |= SV_ONSTACK;
427: if ((ps->ps_sigintr & bit) != 0)
428: sv->sv_flags |= SV_INTERRUPT;
429: if (p->p_flag & P_NOCLDSTOP)
430: sv->sv_flags |= SA_NOCLDSTOP;
431: if (error = copyout((caddr_t)sv, (caddr_t)uap->osv,
432: sizeof (vec)))
433: return (error);
434: }
435: if (uap->nsv) {
436: if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv,
437: sizeof (vec)))
438: return (error);
439: sv->sv_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */
440: setsigvec(p, signum, (struct sigaction *)sv);
441: }
442: return (0);
443: }
444:
445: struct osigblock_args {
446: int mask;
447: };
448: int
449: osigblock(p, uap, retval)
450: register struct proc *p;
451: struct osigblock_args *uap;
452: register_t *retval;
453: {
454:
455: (void) splhigh();
456: *retval = p->p_sigmask;
457: p->p_sigmask |= uap->mask &~ sigcantmask;
458: (void) spl0();
459: return (0);
460: }
461:
462: struct osigsetmask_args {
463: int mask;
464: };
465: int
466: osigsetmask(p, uap, retval)
467: struct proc *p;
468: struct osigsetmask_args *uap;
469: register_t *retval;
470: {
471:
472: (void) splhigh();
473: *retval = p->p_sigmask;
474: p->p_sigmask = uap->mask &~ sigcantmask;
475: (void) spl0();
476: return (0);
477: }
478: #endif /* COMPAT_43 */
479:
480: /*
481: * Suspend process until signal, providing mask to be set
482: * in the meantime. Note nonstandard calling convention:
483: * libc stub passes mask, not pointer, to save a copyin.
484: */
485:
486: int
487: sigcontinue(error)
488: {
489: unix_syscall_return(EINTR);
490: }
491:
492: struct sigsuspend_args {
493: int mask;
494: };
495: /* ARGSUSED */
496: int
497: sigsuspend(p, uap, retval)
498: register struct proc *p;
499: struct sigsuspend_args *uap;
500: register_t *retval;
501: {
502: register struct sigacts *ps = p->p_sigacts;
503:
504: /*
505: * When returning from sigpause, we want
506: * the old mask to be restored after the
507: * signal handler has finished. Thus, we
508: * save it here and mark the sigacts structure
509: * to indicate this.
510: */
511: ps->ps_oldmask = p->p_sigmask;
512: ps->ps_flags |= SAS_OLDMASK;
513: p->p_sigmask = uap->mask &~ sigcantmask;
514: (void) tsleep0((caddr_t) p, PPAUSE|PCATCH, "pause", 0, sigcontinue);
515: /* always return EINTR rather than ERESTART... */
516: return (EINTR);
517: }
518:
519: #if COMPAT_43
520: struct osigstack_args {
521: struct sigstack *nss;
522: struct sigstack *oss;
523: };
524: /* ARGSUSED */
525: int
526: osigstack(p, uap, retval)
527: struct proc *p;
528: register struct osigstack_args *uap;
529: register_t *retval;
530: {
531: struct sigstack ss;
532: struct sigacts *psp;
533: int error = 0;
534:
535: psp = p->p_sigacts;
536: ss.ss_sp = psp->ps_sigstk.ss_sp;
537: ss.ss_onstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
538: if (uap->oss && (error = copyout((caddr_t)&ss,
539: (caddr_t)uap->oss, sizeof (struct sigstack))))
540: return (error);
541: if (uap->nss && (error = copyin((caddr_t)uap->nss,
542: (caddr_t)&ss, sizeof (ss))) == 0) {
543: psp->ps_sigstk.ss_sp = ss.ss_sp;
544: psp->ps_sigstk.ss_size = 0;
545: psp->ps_sigstk.ss_flags |= ss.ss_onstack & SA_ONSTACK;
546: psp->ps_flags |= SAS_ALTSTACK;
547: }
548: return (error);
549: }
550: #endif /* COMPAT_43 */
551:
552: struct sigaltstack_args {
553: struct sigaltstack *nss;
554: struct sigaltstack *oss;
555: };
556: /* ARGSUSED */
557: int
558: sigaltstack(p, uap, retval)
559: struct proc *p;
560: register struct sigaltstack_args *uap;
561: register_t *retval;
562: {
563: struct sigacts *psp;
564: struct sigaltstack ss;
565: int error;
566:
567: psp = p->p_sigacts;
568: if ((psp->ps_flags & SAS_ALTSTACK) == 0)
569: psp->ps_sigstk.ss_flags |= SA_DISABLE;
570: if (uap->oss && (error = copyout((caddr_t)&psp->ps_sigstk,
571: (caddr_t)uap->oss, sizeof (struct sigaltstack))))
572: return (error);
573: if (uap->nss == 0)
574: return (0);
575: if (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
576: sizeof (ss)))
577: return (error);
578: if (ss.ss_flags & SA_DISABLE) {
579: if (psp->ps_sigstk.ss_flags & SA_ONSTACK)
580: return (EINVAL);
581: psp->ps_flags &= ~SAS_ALTSTACK;
582: psp->ps_sigstk.ss_flags = ss.ss_flags;
583: return (0);
584: }
585: if (ss.ss_size < MINSIGSTKSZ)
586: return (ENOMEM);
587: psp->ps_flags |= SAS_ALTSTACK;
588: psp->ps_sigstk= ss;
589: return (0);
590: }
591:
592: struct kill_args {
593: int pid;
594: int signum;
595: };
596: /* ARGSUSED */
597: int
598: kill(cp, uap, retval)
599: register struct proc *cp;
600: register struct kill_args *uap;
601: register_t *retval;
602: {
603: register struct proc *p;
604: register struct pcred *pc = cp->p_cred;
605:
606: if ((u_int)uap->signum >= NSIG)
607: return (EINVAL);
608: if (uap->pid > 0) {
609: /* kill single process */
610: if ((p = pfind(uap->pid)) == NULL)
611: return (ESRCH);
612: if (!cansignal(cp, pc, p, uap->signum))
613: return (EPERM);
614: if (uap->signum)
615: psignal(p, uap->signum);
616: return (0);
617: }
618: switch (uap->pid) {
619: case -1: /* broadcast signal */
620: return (killpg1(cp, uap->signum, 0, 1));
621: case 0: /* signal own process group */
622: return (killpg1(cp, uap->signum, 0, 0));
623: default: /* negative explicit process group */
624: return (killpg1(cp, uap->signum, -(uap->pid), 0));
625: }
626: /* NOTREACHED */
627: }
628:
629: #if COMPAT_43
630: struct okillpg_args {
631: int pgid;
632: int signum;
633: };
634: /* ARGSUSED */
635: int
636: okillpg(p, uap, retval)
637: struct proc *p;
638: register struct okillpg_args *uap;
639: register_t *retval;
640: {
641:
642: if ((u_int)uap->signum >= NSIG)
643: return (EINVAL);
644: return (killpg1(p, uap->signum, uap->pgid, 0));
645: }
646: #endif /* COMPAT_43 */
647:
648: /*
649: * Common code for kill process group/broadcast kill.
650: * cp is calling process.
651: */
652: int
653: killpg1(cp, signum, pgid, all)
654: register struct proc *cp;
655: int signum, pgid, all;
656: {
657: register struct proc *p;
658: register struct pcred *pc = cp->p_cred;
659: struct pgrp *pgrp;
660: int nfound = 0;
661:
662: if (all)
663: /*
664: * broadcast
665: */
666: for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
667: if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
668: p == cp || !cansignal(cp, pc, p, signum))
669: continue;
670: nfound++;
671: if (signum)
672: psignal(p, signum);
673: }
674: else {
675: if (pgid == 0)
676: /*
677: * zero pgid means send to my process group.
678: */
679: pgrp = cp->p_pgrp;
680: else {
681: pgrp = pgfind(pgid);
682: if (pgrp == NULL)
683: return (ESRCH);
684: }
685: for (p = pgrp->pg_members.lh_first; p != 0;
686: p = p->p_pglist.le_next) {
687: if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
688: p->p_stat == SZOMB ||
689: !cansignal(cp, pc, p, signum))
690: continue;
691: nfound++;
692: if (signum)
693: psignal(p, signum);
694: }
695: }
696: return (nfound ? 0 : ESRCH);
697: }
698:
699: /*
700: * Send a signal to a process group.
701: */
702: void
703: gsignal(pgid, signum)
704: int pgid, signum;
705: {
706: struct pgrp *pgrp;
707:
708: if (pgid && (pgrp = pgfind(pgid)))
709: pgsignal(pgrp, signum, 0);
710: }
711:
712: /*
713: * Send a signal to a process group. If checktty is 1,
714: * limit to members which have a controlling terminal.
715: */
716: void
717: pgsignal(pgrp, signum, checkctty)
718: struct pgrp *pgrp;
719: int signum, checkctty;
720: {
721: register struct proc *p;
722:
723: if (pgrp)
724: for (p = pgrp->pg_members.lh_first; p != 0;
725: p = p->p_pglist.le_next)
726: if (checkctty == 0 || p->p_flag & P_CONTROLT)
727: psignal(p, signum);
728: }
729:
730: /*
731: * Send a signal caused by a trap to a specific thread.
732: */
733: void
734: threadsignal(sig_actthread, signum, code)
735: register thread_act_t *sig_actthread;
736: register int signum;
737: u_long code;
738: {
739: register struct uthread *uth;
740: register struct task * sig_task;
741: register struct proc *p ;
742: int mask;
743:
744: if ((u_int)signum >= NSIG || signum == 0)
745: return;
746:
747: mask = sigmask(signum);
748: if ((mask & threadmask) == 0)
749: return;
750: sig_task = get_threadtask(sig_actthread);
751: /* p = sig_task->proc; */
752: p = (struct proc *)(get_bsdtask_info(sig_task));
753:
754: if (!(p->p_flag & P_TRACED) && (p->p_sigignore & mask))
755: return;
756:
757: uth = get_bsdthread_info(sig_actthread);
758: simple_lock(&p->siglock);
759: uth->uu_sig |= mask;
760: uth->uu_code = code;
761: #ifdef BSD_USE_APC
762: thread_apc_set(sig_actthread, bsd_ast);
763: #else
764: thread_ast_set(sig_actthread,AST_BSD);
765: if (current_act() == sig_actthread)
766: ast_on(AST_BSD);
767: #endif
768: simple_unlock(&p->siglock);
769: }
770:
771: /*
772: * Send the signal to the process. If the signal has an action, the action
773: * is usually performed by the target process rather than the caller; we add
774: * the signal to the set of pending signals for the process.
775: *
776: * Exceptions:
777: * o When a stop signal is sent to a sleeping process that takes the
778: * default action, the process is stopped without awakening it.
779: * o SIGCONT restarts stopped processes (or puts them back to sleep)
780: * regardless of the signal action (eg, blocked or ignored).
781: *
782: * Other ignored signals are discarded immediately.
783: */
784: void
785: psignal(p, signum)
786: register struct proc *p;
787: register int signum;
788: {
789: register int s, prop;
790: register sig_t action;
791: register thread_act_t sig_thread_act;
792: register thread_t sig_thread;
793: register task_t sig_task;
794: register thread_t cur_thread;
795: thread_act_t *cur_act;
796: int mask;
797:
798: if ((u_int)signum >= NSIG || signum == 0)
799: panic("psignal signal number");
800: mask = sigmask(signum);
801: prop = sigprop[signum];
802:
803: /*
804: * We will need the task pointer later. Grab it now to
805: * check for a zombie process. Also don't send signals
806: * to kernel internal tasks.
807: */
808: if (((sig_task = p->task) == TASK_NULL) || is_kerneltask(sig_task))
809: return;
810:
811: /*
812: * If proc is traced, always give parent a chance.
813: */
814: if (p->p_flag & P_TRACED)
815: action = SIG_DFL;
816: else {
817: /*
818: * If the signal is being ignored,
819: * then we forget about it immediately.
820: * (Note: we don't set SIGCONT in p_sigignore,
821: * and if it is set to SIG_IGN,
822: * action will be SIG_DFL here.)
823: */
824: if (p->p_sigignore & mask)
825: return;
826: if (p->p_sigmask & mask)
827: action = SIG_HOLD;
828: else if (p->p_sigcatch & mask)
829: action = SIG_CATCH;
830: else
831: action = SIG_DFL;
832: }
833:
834: if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) &&
835: (p->p_flag & P_TRACED) == 0)
836: p->p_nice = NZERO;
837:
838: if (prop & SA_CONT)
839: p->p_siglist &= ~stopsigmask;
840:
841: if (prop & SA_STOP) {
842: /*
843: * If sending a tty stop signal to a member of an orphaned
844: * process group, discard the signal here if the action
845: * is default; don't stop the process below if sleeping,
846: * and don't clear any pending SIGCONT.
847: */
848: if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
849: action == SIG_DFL)
850: return;
851: p->p_siglist &= ~contsigmask;
852: }
853: p->p_siglist |= mask;
854:
855: /*
856: * Defer further processing for signals which are held,
857: * except that stopped processes must be continued by SIGCONT.
858: */
859: if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
860: return;
861:
862: /*
863: * Deliver the signal to the first thread in the task. This
864: * allows single threaded applications which use signals to
865: * be able to be linked with multithreaded libraries. We have
866: * an implicit reference to the current_thread, but need
867: * an explicit one otherwise. The thread reference keeps
868: * the corresponding task data structures around too. This
869: * reference is released by thread_deallocate.
870: */
871:
872: s = splhigh();
873: cur_thread = current_thread(); /* this is a shuttle */
874: cur_act = current_act();
875:
876: task_tllock(sig_task);
877: sig_thread_act = (thread_t) get_firstthread(sig_task);
878:
879: if (sig_thread_act == THREAD_NULL) {
880: task_tlunlock(sig_task);
881: (void) splx(s);
882: return;
883: }
884: sig_thread = getshuttle_thread(sig_thread_act);
885: if (sig_thread == THREAD_NULL) {
886: printf("WARNING: valid act; but no shutte in psignal\n");
887: #if 0
888: /* FIXME : NO VALID SHUTTLE */
889: task_tlunlock(sig_task);
890: (void) splx(s);
891: return;
892: #endif
893: }
894: #ifdef BSD_USE_APC
895: thread_apc_set(sig_thread_act, bsd_ast);
896: #else
897: thread_ast_set(sig_thread_act,AST_BSD);
898: if (cur_act == sig_thread_act)
899: ast_on(AST_BSD);
900: #endif
901:
902: /* #if FIXME */
903: if (sig_thread != cur_thread)
904: act_reference(sig_thread_act);
905: /* #endif */
906: task_tlunlock(sig_task);
907:
908: /*
909: * SIGKILL priority twiddling moved here from above because
910: * it needs sig_thread. Could merge it into large switch
911: * below if we didn't care about priority for tracing
912: * as SIGKILL's action is always SIG_DFL.
913: */
914: if ((signum == SIGKILL) && (p->p_nice > NZERO)) {
915: p->p_nice = NZERO;
916: #if FIXME /* [ */
917: thread_max_priority(sig_thread, sig_thread->processor_set,
918: BASEPRI_USER);
919: thread_priority(sig_thread, BASEPRI_USER, FALSE);
920: #endif /* FIXME ] */
921: }
922:
923: /*
924: * Process is traced - wake it up (if not already
925: * stopped) so that it can discover the signal in
926: * issig() and stop for the parent.
927: */
928: if (p->p_flag & P_TRACED) {
929: if (p->p_stat != SSTOP)
930: goto run;
931: else
932: goto out;
933: }
934:
935: if (action != SIG_DFL) {
936: /*
937: * User wants to catch the signal.
938: * Wake up the thread, but don't un-suspend it
939: * (except for SIGCONT).
940: */
941: if (prop & SA_CONT)
942: (void) task_resume(sig_task);
943: goto run;
944: } else {
945: /* Default action - varies */
946:
947: if (mask & stopsigmask) {
948: /*
949: * These are the signals which by default
950: * stop a process.
951: *
952: * Don't clog system with children of init
953: * stopped from the keyboard.
954: */
955: if (!(prop & SA_STOP) && p->p_pptr == initproc) {
956: psignal(p, SIGKILL);
957: p->p_siglist &= ~mask;
958: goto out;
959: }
960: /*
961: * Stop the task.
962: */
963: if (!is_thread_running(sig_thread)) {
964: /* Thread is not running
965: * If task hasn't already been stopped by
966: * a signal, stop it.
967: */
968: p->p_siglist &= ~mask;
969: if (get_task_userstop(sig_task) == 0) {
970: /*
971: * p_cursig must not be set, because
972: * it will be psig()'d if it is not
973: * zero, and the signal is being
974: * handled here. But save the signal
975: * in p_stopsig so WUNTRACED
976: * option to wait can find it.
977: */
978: p->p_xstat = signum;
979: if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
980: psignal(p->p_pptr, SIGCHLD);
981: stop(p);
982: }
983: goto out;
984: } else {
985: if ((p == current_proc()) && (p->p_stat != SZOMB)) {
986:
987: #ifdef BSD_USE_APC
988: thread_apc_set(cur_act, bsd_ast);
989: #else
990: thread_ast_set(cur_act, AST_BSD);
991: ast_on(AST_BSD);
992: #endif
993:
994: }
995: goto out;
996: }
997: }
998:
999: switch (signum) {
1000: /*
1001: * Signals ignored by default have been dealt
1002: * with already, since their bits are on in
1003: * p_sigignore.
1004: */
1005:
1006: case SIGKILL:
1007: /*
1008: * Kill signal always sets process running and
1009: * unsuspends it.
1010: */
1011: while (get_task_userstop(sig_task) > 0)
1012: (void) task_resume(sig_task);
1013: /*
1014: * Process will be running after 'run'
1015: */
1016: p->p_stat = SRUN;
1017:
1018: /*
1019: * Break it out of user wait, as well.
1020: */
1021: while (get_thread_userstop(sig_thread_act) > 0)
1022: (void) thread_resume(sig_thread_act);
1023:
1024: /*
1025: * Clear system wait if possible.
1026: */
1027: clear_wait(sig_thread, THREAD_INTERRUPTED, FALSE);
1028: #if MACH_HOST
1029: /*
1030: * Make sure it can run.
1031: */
1032: if (sig_thread->processor_set->empty)
1033: thread_assign(sig_thread, &default_pset);
1034: #endif
1035: /*
1036: * If we're delivering the signal to some other
1037: * thread, that thread might be stuck in an
1038: * exception. Break it out. Can't call
1039: * thread_exception_abort from high spl, but
1040: * SIGKILL can't be sent from interrupt level, so
1041: * it's ok to drop spl. Can call thread_deallocate
1042: * for same reason.
1043: */
1044: splx(s);
1045: if (sig_thread != cur_thread) {
1046: thread_abort(sig_thread_act);
1047: /* #if FIXME */
1048: act_deallocate(sig_thread_act);
1049: /* #endif */
1050: }
1051: return;
1052:
1053: case SIGCONT:
1054: /*
1055: * Let the process run. If it's sleeping on an
1056: * event, it remains so.
1057: */
1058: (void) task_resume(sig_task);
1059: p->p_stat = SRUN;
1060: goto out;
1061:
1062: default:
1063: /*
1064: * All other signals wake up the process, but don't
1065: * resume it.
1066: */
1067: goto run;
1068: }
1069: }
1070: /*NOTREACHED*/
1071: run:
1072: /*
1073: * If we're being traced (possibly because someone attached us
1074: * while we were stopped), check for a signal from the debugger.
1075: */
1076: if (p->p_stat == SSTOP) {
1077: if ((p->p_flag & P_TRACED) != 0 && p->p_xstat != 0)
1078: p->p_siglist |= sigmask(p->p_xstat);
1079: }
1080:
1081: /*
1082: * setrunnable(p) in BSD
1083: */
1084:
1085: p->p_stat = SRUN;
1086:
1087: /*
1088: * Wake up the thread if it is interruptible.
1089: */
1090: clear_wait(sig_thread, THREAD_INTERRUPTED, TRUE);
1091: out:
1092: splx(s);
1093: /*** FIXME revisit this->who calls up ipc_thread_deallocate?? ***/
1094: if (sig_thread != cur_thread)
1095: act_deallocate(sig_thread_act);
1096: }
1097:
1098: __inline__ void
1099: sig_lock_to_exit(
1100: struct proc *p)
1101: {
1102: thread_t self = current_thread();
1103:
1104: p->exit_thread = self;
1105: simple_unlock(&p->siglock);
1106: (void) task_hold(p->task);
1107: (void) task_dowait(p->task, FALSE);
1108: }
1109:
1110: __inline__ int
1111: sig_try_lock(
1112: struct proc *p)
1113: {
1114: thread_t self = current_thread();
1115:
1116: simple_lock(&p->siglock);
1117: while (p->sigwait || p->exit_thread) {
1118: simple_unlock(&p->siglock);
1119: if (p->exit_thread) {
1120: if (p->exit_thread == self) {
1121: /*
1122: * Already exiting - no signals.
1123: */
1124: return 0;
1125: }
1126: else {
1127: /*
1128: * Another thread has called exit -
1129: * stop (until terminate request).
1130: */
1131: thread_hold(current_act());
1132: }
1133: }
1134: if(assert_wait_possible()) {
1135: assert_wait((caddr_t)&p->sigwait_thread, THREAD_UNINT);
1136: }
1137: thread_block(0);
1138: if (thread_should_abort(self)) {
1139: /*
1140: * Terminate request - clean up.
1141: */
1142: return -1;
1143: }
1144: simple_lock(&p->siglock);
1145: }
1146:
1147: return 1;
1148: }
1149:
1150: /*
1151: * If the current process has received a signal (should be caught or cause
1152: * termination, should interrupt current syscall), return the signal number.
1153: * Stop signals with default action are processed immediately, then cleared;
1154: * they aren't returned. This is checked after each entry to the system for
1155: * a syscall or trap (though this can usually be done without calling issignal
1156: * by checking the pending signal masks in the CURSIG macro.) The normal call
1157: * sequence is
1158: *
1159: * while (signum = CURSIG(curproc))
1160: * postsig(signum);
1161: */
1162: int
1163: issignal(p)
1164: register struct proc *p;
1165: {
1166: register int signum, mask, prop, sigbits;
1167: task_t task = p->task;
1168: thread_act_t initial_threadact;
1169: thread_t cur_thread;
1170: thread_act_t cur_act;
1171: int s;
1172: struct uthread * ut;
1173:
1174: #if DIAGNOSTIC
1175: /*
1176: * This must be called on master cpu
1177: */
1178: if (cpu_number() != master_cpu)
1179: panic("issig not on master");
1180: #endif /* DIAGNOSTIC */
1181:
1182: /*
1183: * Try to grab the signal lock.
1184: */
1185: if (sig_try_lock(p) <= 0)
1186: return (0);
1187:
1188: /*
1189: * only allow delivery of process signals (asynchronous)
1190: * to the initial thread. This is the first thread in
1191: * the tasks thread list.
1192: */
1193: initial_threadact = (thread_t)get_firstthread(task);
1194: cur_thread = current_thread();
1195: cur_act = current_act();
1196:
1197:
1198: ut = get_bsdthread_info(cur_act);
1199: for(;;) {
1200: sigbits = (ut->uu_sig |p->p_siglist) & ~p->p_sigmask;
1201:
1202: for (;;) {
1203: if (p->p_flag & P_PPWAIT)
1204: sigbits &= ~stopsigmask;
1205: if (sigbits == 0) { /* no signal to send */
1206: simple_unlock(&p->siglock);
1207: return (0);
1208: }
1209: signum = ffs((long)sigbits);
1210: mask = sigmask(signum);
1211: prop = sigprop[signum];
1212:
1213: if (mask & threadmask) {
1214: /* we can take this signal */
1215: ut->uu_sig &= ~mask;
1216: break;
1217: } else {
1218: if (cur_act != initial_threadact)
1219: sigbits &= ~mask;
1220: else
1221: break;
1222: }
1223: }
1224:
1225:
1226: /*
1227: * We should see pending but ignored signals
1228: * only if P_TRACED was on when they were posted.
1229: */
1230: if (mask & p->p_sigignore && (p->p_flag & P_TRACED) == 0) {
1231: p->p_siglist &= ~mask; /* take the signal! */
1232: continue;
1233: }
1234: if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
1235: register int hold;
1236: register task_t task;
1237: /*
1238: * If traced, always stop, and stay
1239: * stopped until released by the debugger.
1240: */
1241:
1242: if (p->p_flag & P_FSTRACE) {
1243: #if PROCFS
1244: /* procfs debugging */
1245: p->p_stat = SSTOP;
1246: wakeup((caddr_t)p);
1247: #error need to implement
1248: panic("procfs debugging");
1249: #endif
1250: } else {
1251: #ifndef _WANT_GDB_TO_PANIC_
1252: /*
1253: * We may have already been assert_waited as
1254: * part of a sleep, but we are going to
1255: * subvert what we are sleeping on here.
1256: * Since task_hold()/task_dowait() can
1257: * block themselves, clear out the old
1258: * condition here.
1259: */
1260: clear_wait(cur_thread, THREAD_INTERRUPTED, FALSE);
1261: #endif /* !_WANT_GDB_TO_PANIC_ */
1262:
1263: /* ptrace debugging */
1264: p->p_xstat = signum;
1265: psignal(p->p_pptr, SIGCHLD);
1266: pcb_synch(cur_thread);
1267: /*
1268: * XXX Have to really stop for debuggers;
1269: * XXX stop() doesn't do the right thing.
1270: * XXX Inline the task_suspend because we
1271: * XXX have to diddle Unix state in the
1272: * XXX middle of it.
1273: */
1274: task = p->task;
1275: hold = FALSE;
1276: if (inc_task_userstop(task) == 0)
1277: hold = TRUE;
1278: if (hold) {
1279: (void) task_hold(task);
1280: act_reference(cur_act);
1281: p->sigwait = TRUE;
1282: p->sigwait_thread = cur_act;
1283: simple_unlock(&p->siglock);
1284: (void) task_dowait(task, TRUE);
1285: }
1286: else {
1287: act_reference(cur_act);
1288: p->sigwait = TRUE;
1289: p->sigwait_thread = cur_act;
1290: simple_unlock(&p->siglock);
1291: }
1292: p->p_stat = SSTOP;
1293: p->p_flag &= ~P_WAITED;
1294: p->p_siglist &= ~mask; /* clear the old signal */
1295:
1296: wakeup((caddr_t)p->p_pptr);
1297: assert_wait((caddr_t)&p->sigwait, THREAD_UNINT);
1298: thread_block(0);
1299: simple_lock(&p->siglock);
1300: p->sigwait = FALSE;
1301: p->sigwait_thread = NULL;
1302: wakeup((caddr_t)&p->sigwait_thread);
1303: act_deallocate(cur_act);
1304:
1305: /*
1306: * We get here only if task
1307: * is continued or killed. Kill condition
1308: * is signalled by adding NSIG to p_cursig.
1309: * Pass original p_cursig as exit value in
1310: * this case.
1311: */
1312: if (p->p_siglist & sigmask(SIGKILL)) {
1313: /*
1314: * Wait event may still be outstanding;
1315: * clear it, since sig_lock_to_exit will
1316: * wait.
1317: */
1318: clear_wait(current_thread(),
1319: THREAD_INTERRUPTED,
1320: FALSE);
1321: sig_lock_to_exit(p);
1322: /*
1323: * Since this thread will be resumed
1324: * to allow the current syscall to
1325: * be completed, must save u_qsave
1326: * before calling exit(). (Since exit()
1327: * calls closef() which can trash u_qsave.)
1328: */
1329: exit1(p,signum);
1330: }
1331:
1332: /*
1333: * We may have to quit
1334: */
1335: if (thread_should_abort(current_thread())) {
1336: simple_unlock(&p->siglock);
1337: return(0);
1338: }
1339:
1340: /*
1341: * If the traced bit got turned off, go back up
1342: * to the top to rescan signals. This ensures
1343: * that p_sig* and ps_sigact are consistent.
1344: */
1345: if ((p->p_flag & P_TRACED) == 0) {
1346: if (mask & threadmask)
1347: ut->uu_sig |= mask;
1348: else
1349: p->p_siglist |= mask;
1350: continue;
1351: }
1352:
1353: /*
1354: * If parent wants us to take the signal,
1355: * then it will leave it in p->p_xstat;
1356: * otherwise we just look for signals again.
1357: */
1358: signum = p->p_xstat;
1359: if (signum == 0)
1360: continue;
1361: /*
1362: * Put the new signal into p_siglist. If the
1363: * signal is being masked, look for other signals.
1364: */
1365: mask = sigmask(signum);
1366: if (mask & threadmask)
1367: ut->uu_sig |= mask;
1368: else
1369: p->p_siglist |= mask;
1370: if (p->p_sigmask & mask)
1371: continue;
1372: }
1373: }
1374:
1375: /*
1376: * Decide whether the signal should be returned.
1377: * Return the signal's number, or fall through
1378: * to clear it from the pending mask.
1379: */
1380:
1381: switch ((long)p->p_sigacts->ps_sigact[signum]) {
1382:
1383: case (long)SIG_DFL:
1384: /*
1385: * Don't take default actions on system processes.
1386: */
1387: if (p->p_pptr->p_pid == 0) {
1388: #if DIAGNOSTIC
1389: /*
1390: * Are you sure you want to ignore SIGSEGV
1391: * in init? XXX
1392: */
1393: printf("Process (pid %d) got signal %d\n",
1394: p->p_pid, signum);
1395: #endif
1396: break; /* == ignore */
1397: }
1398:
1399: /*
1400: * If there is a pending stop signal to process
1401: * with default action, stop here,
1402: * then clear the signal. However,
1403: * if process is member of an orphaned
1404: * process group, ignore tty stop signals.
1405: */
1406: if (prop & SA_STOP) {
1407: if (p->p_flag & P_TRACED ||
1408: (p->p_pgrp->pg_jobc == 0 &&
1409: prop & SA_TTYSTOP))
1410: break; /* == ignore */
1411: p->p_xstat = signum;
1412: stop(p);
1413: if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
1414: psignal(p->p_pptr, SIGCHLD);
1415: act_reference(cur_act);
1416: p->sigwait = TRUE;
1417: p->sigwait_thread = cur_act;
1418: simple_unlock(&p->siglock);
1419: thread_block(0);
1420: simple_lock(&p->siglock);
1421: p->sigwait = FALSE;
1422: p->sigwait_thread = NULL;
1423: wakeup((caddr_t)&p->sigwait_thread);
1424: act_deallocate(cur_act);
1425: /*
1426: * We may have to quit
1427: */
1428: if (thread_should_abort(current_thread())) {
1429: simple_unlock(&p->siglock);
1430: return(0);
1431: }
1432: break;
1433: } else if (prop & SA_IGNORE) {
1434: /*
1435: * Except for SIGCONT, shouldn't get here.
1436: * Default action is to ignore; drop it.
1437: */
1438: break; /* == ignore */
1439: } else {
1440: simple_unlock(&p->siglock);
1441: return (signum);
1442: }
1443: /*NOTREACHED*/
1444:
1445: case (long)SIG_IGN:
1446: /*
1447: * Masking above should prevent us ever trying
1448: * to take action on an ignored signal other
1449: * than SIGCONT, unless process is traced.
1450: */
1451: if ((prop & SA_CONT) == 0 &&
1452: (p->p_flag & P_TRACED) == 0)
1453: printf("issignal\n");
1454: break; /* == ignore */
1455:
1456: default:
1457: /*
1458: * This signal has an action, let
1459: * postsig() process it.
1460: */
1461: simple_unlock(&p->siglock);
1462: return (signum);
1463: }
1464: p->p_siglist &= ~mask; /* take the signal! */
1465: }
1466: /* NOTREACHED */
1467: }
1468:
1469: /*
1470: * Put the argument process into the stopped state and notify the parent
1471: * via wakeup. Signals are handled elsewhere. The process must not be
1472: * on the run queue.
1473: */
1474: void
1475: stop(p)
1476: register struct proc *p;
1477: {
1478:
1479: /*
1480: * Call special task_suspend routine,
1481: * because this routine is called from interrupts
1482: * (psignal) and cannot sleep.
1483: */
1484: #ifdef FIXME
1485: /* not clear why moving thread suspend matters*/
1486: (void) task_suspend_nowait(p->task); /*XXX*/
1487:
1488: p->p_stat = SSTOP;
1489: p->p_flag &= ~P_WAITED;
1490: wakeup((caddr_t)p->p_pptr);
1491: #else
1492:
1493: p->p_stat = SSTOP;
1494: p->p_flag &= ~P_WAITED;
1495: wakeup((caddr_t)p->p_pptr);
1496: (void) task_suspend_nowait(p->task); /*XXX*/
1497:
1498: #endif /* FIXME */
1499: }
1500:
1501: /*
1502: * Take the action for the specified signal
1503: * from the current set of pending signals.
1504: */
1505: void
1506: postsig(signum)
1507: register int signum;
1508: {
1509: register struct proc *p = current_proc();
1510: register struct sigacts *ps = p->p_sigacts;
1511: register sig_t action;
1512: u_long code;
1513: int mask, returnmask;
1514:
1515: #if DIAGNOSTIC
1516: if (signum == 0)
1517: panic("postsig");
1518: /*
1519: * This must be called on master cpu
1520: */
1521: if (cpu_number() != master_cpu)
1522: panic("psig not on master");
1523: #endif
1524:
1525: /*
1526: * Try to grab the signal lock.
1527: */
1528: if (sig_try_lock(p) <= 0)
1529: return;
1530:
1531: mask = sigmask(signum);
1532: p->p_siglist &= ~mask;
1533: action = ps->ps_sigact[signum];
1534: #if KTRACE
1535: if (KTRPOINT(p, KTR_PSIG))
1536: ktrpsig(p->p_tracep,
1537: signum, action, ps->ps_flags & SAS_OLDMASK ?
1538: ps->ps_oldmask : p->p_sigmask, 0);
1539: #endif
1540: if (action == SIG_DFL) {
1541: /*
1542: * Default action, where the default is to kill
1543: * the process. (Other cases were ignored above.)
1544: */
1545: /* called with sig_lock() held */
1546: sigexit(p, signum);
1547: /* NOTREACHED */
1548: } else {
1549: /*
1550: * If we get here, the signal must be caught.
1551: */
1552: #if DIAGNOSTIC
1553: if (action == SIG_IGN || (p->p_sigmask & mask))
1554: log(LOG_WARNING,
1555: "postsig: processing masked or ignored signal\n");
1556: #endif
1557: /*
1558: * Set the new mask value and also defer further
1559: * occurences of this signal.
1560: *
1561: * Special case: user has done a sigpause. Here the
1562: * current mask is not of interest, but rather the
1563: * mask from before the sigpause is what we want
1564: * restored after the signal processing is completed.
1565: */
1566: (void) splhigh();
1567: if (ps->ps_flags & SAS_OLDMASK) {
1568: returnmask = ps->ps_oldmask;
1569: ps->ps_flags &= ~SAS_OLDMASK;
1570: } else
1571: returnmask = p->p_sigmask;
1572: p->p_sigmask |= ps->ps_catchmask[signum] | mask;
1573: if (ps->ps_sig != signum) {
1574: code = 0;
1575: } else {
1576: code = ps->ps_code;
1577: ps->ps_code = 0;
1578: }
1579: simple_unlock(&p->siglock);
1580: (void) spl0();
1581: p->p_stats->p_ru.ru_nsignals++;
1582: sendsig(p, action, signum, returnmask, code);
1583: }
1584: }
1585:
1586: /*
1587: * Force the current process to exit with the specified signal, dumping core
1588: * if appropriate. We bypass the normal tests for masked and caught signals,
1589: * allowing unrecoverable failures to terminate the process without changing
1590: * signal state. Mark the accounting record with the signal termination.
1591: * If dumping core, save the signal number for the debugger. Calls exit and
1592: * does not return.
1593: */
1594: void
1595: sigexit(p, signum)
1596: register struct proc *p;
1597: int signum;
1598: {
1599:
1600: sig_lock_to_exit(p);
1601: p->p_acflag |= AXSIG;
1602: if (sigprop[signum] & SA_CORE) {
1603: p->p_sigacts->ps_sig = signum;
1604: if (coredump(p) == 0)
1605: signum |= WCOREFLAG;
1606: }
1607: exit1(p, W_EXITCODE(0, signum));
1608: /* NOTREACHED */
1609: }
1610:
1611: void
1612: bsd_ast(thread_act_t thr_act)
1613: {
1614: struct proc *p = current_proc();
1615: struct uthread *ut = get_bsdthread_info(thr_act);
1616: int signum;
1617: unsigned int pc;
1618: boolean_t funnel_state;
1619:
1620: if (p == NULL)
1621: return;
1622:
1623: funnel_state = thread_set_funneled(TRUE);
1624:
1625: if ((p->p_flag & P_OWEUPC) && (p->p_flag & P_PROFIL)) {
1626: pc = get_useraddr();
1627: addupc_task(p, pc, 1);
1628: p->p_flag &= ~P_OWEUPC;
1629: }
1630:
1631: if (CHECK_SIGNALS(p, current_thread(), ut)) {
1632: while (signum = issignal(p))
1633: postsig(signum);
1634: }
1635: #ifdef BSD_USE_APC
1636: thread_apc_clear(thr_act, bsd_ast);
1637: #else
1638: ast_off(AST_BSD);
1639: #endif
1640:
1641: (void) thread_set_funneled(funnel_state);
1642: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.