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