xref: /csrg-svn/sys/kern/kern_sig.c (revision 53218)
123374Smckusick /*
247540Skarels  * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
337580Smckusick  * All rights reserved.
423374Smckusick  *
544440Sbostic  * %sccs.include.redist.c%
637580Smckusick  *
7*53218Smckusick  *	@(#)kern_sig.c	7.44 (Berkeley) 04/20/92
823374Smckusick  */
97421Sroot 
1047540Skarels #define	SIGPROP		/* include signal properties table */
1117092Sbloom #include "param.h"
1247650Skarels #include "signalvar.h"
1347650Skarels #include "resourcevar.h"
1448020Smckusick #include "namei.h"
1537580Smckusick #include "vnode.h"
1617092Sbloom #include "proc.h"
1747540Skarels #include "systm.h"
1817092Sbloom #include "timeb.h"
1917092Sbloom #include "times.h"
2017092Sbloom #include "buf.h"
2117092Sbloom #include "acct.h"
2237580Smckusick #include "file.h"
2317092Sbloom #include "kernel.h"
2439513Skarels #include "wait.h"
2540807Smarc #include "ktrace.h"
267421Sroot 
2749102Skarels #include "machine/cpu.h"
2849102Skarels 
2947650Skarels #include "vm/vm.h"
3047650Skarels #include "kinfo_proc.h"
3147650Skarels #include "user.h"		/* for coredump */
3237581Smckusick 
3317013Smckusick /*
3447540Skarels  * Can process p, with pcred pc, send the signal signo to process q?
3517013Smckusick  */
3647540Skarels #define CANSIGNAL(p, pc, q, signo) \
3747540Skarels 	((pc)->pc_ucred->cr_uid == 0 || \
3847540Skarels 	    (pc)->p_ruid == (q)->p_cred->p_ruid || \
3947540Skarels 	    (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
4047540Skarels 	    (pc)->p_ruid == (q)->p_ucred->cr_uid || \
4147540Skarels 	    (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
4242920Skarels 	    ((signo) == SIGCONT && (q)->p_session == (p)->p_session))
4339513Skarels 
4442920Skarels /* ARGSUSED */
4542920Skarels sigaction(p, uap, retval)
4642920Skarels 	struct proc *p;
4742920Skarels 	register struct args {
4812882Ssam 		int	signo;
4939513Skarels 		struct	sigaction *nsa;
5039513Skarels 		struct	sigaction *osa;
5142920Skarels 	} *uap;
5242920Skarels 	int *retval;
5342920Skarels {
5439513Skarels 	struct sigaction vec;
5539513Skarels 	register struct sigaction *sa;
5647540Skarels 	register struct sigacts *ps = p->p_sigacts;
5712882Ssam 	register int sig;
5839513Skarels 	int bit, error;
597421Sroot 
6012882Ssam 	sig = uap->signo;
6139513Skarels 	if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
6244405Skarels 		return (EINVAL);
6339513Skarels 	sa = &vec;
6439513Skarels 	if (uap->osa) {
6547540Skarels 		sa->sa_handler = ps->ps_sigact[sig];
6647540Skarels 		sa->sa_mask = ps->ps_catchmask[sig];
6718308Smckusick 		bit = sigmask(sig);
6839513Skarels 		sa->sa_flags = 0;
6947540Skarels 		if ((ps->ps_sigonstack & bit) != 0)
7039513Skarels 			sa->sa_flags |= SA_ONSTACK;
7147540Skarels 		if ((ps->ps_sigintr & bit) == 0)
7239513Skarels 			sa->sa_flags |= SA_RESTART;
7342920Skarels 		if (p->p_flag & SNOCLDSTOP)
7439513Skarels 			sa->sa_flags |= SA_NOCLDSTOP;
7539513Skarels 		if (error = copyout((caddr_t)sa, (caddr_t)uap->osa,
7639513Skarels 		    sizeof (vec)))
7744405Skarels 			return (error);
7812951Ssam 	}
7939513Skarels 	if (uap->nsa) {
8039513Skarels 		if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
8139513Skarels 		    sizeof (vec)))
8244405Skarels 			return (error);
8342920Skarels 		setsigvec(p, sig, sa);
8412951Ssam 	}
8544405Skarels 	return (0);
867421Sroot }
877421Sroot 
8842920Skarels setsigvec(p, sig, sa)
8942920Skarels 	register struct proc *p;
9012951Ssam 	int sig;
9139513Skarels 	register struct sigaction *sa;
9212882Ssam {
9347540Skarels 	register struct sigacts *ps = p->p_sigacts;
9412951Ssam 	register int bit;
9512882Ssam 
9617153Sbloom 	bit = sigmask(sig);
9712882Ssam 	/*
9812882Ssam 	 * Change setting atomically.
9912882Ssam 	 */
10017153Sbloom 	(void) splhigh();
10147540Skarels 	ps->ps_sigact[sig] = sa->sa_handler;
10247540Skarels 	ps->ps_catchmask[sig] = sa->sa_mask &~ sigcantmask;
10339513Skarels 	if ((sa->sa_flags & SA_RESTART) == 0)
10447540Skarels 		ps->ps_sigintr |= bit;
10518308Smckusick 	else
10647540Skarels 		ps->ps_sigintr &= ~bit;
10739513Skarels 	if (sa->sa_flags & SA_ONSTACK)
10847540Skarels 		ps->ps_sigonstack |= bit;
10912951Ssam 	else
11047540Skarels 		ps->ps_sigonstack &= ~bit;
11152400Storek #ifdef COMPAT_SUNOS
11252400Storek 	if (sa->sa_flags & SA_USERTRAMP)
11352400Storek 		ps->ps_usertramp |= bit;
11452400Storek 	else
11552400Storek 		ps->ps_usertramp &= ~bit;
11652400Storek #endif
11739513Skarels 	if (sig == SIGCHLD) {
11839513Skarels 		if (sa->sa_flags & SA_NOCLDSTOP)
11939513Skarels 			p->p_flag |= SNOCLDSTOP;
12039513Skarels 		else
12139513Skarels 			p->p_flag &= ~SNOCLDSTOP;
12239513Skarels 	}
12339513Skarels 	/*
12439513Skarels 	 * Set bit in p_sigignore for signals that are set to SIG_IGN,
12539513Skarels 	 * and for signals set to SIG_DFL where the default is to ignore.
12639513Skarels 	 * However, don't put SIGCONT in p_sigignore,
12739513Skarels 	 * as we have to restart the process.
12839513Skarels 	 */
12939513Skarels 	if (sa->sa_handler == SIG_IGN ||
13047540Skarels 	    (sigprop[sig] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
13112951Ssam 		p->p_sig &= ~bit;		/* never to be seen again */
13239513Skarels 		if (sig != SIGCONT)
13339513Skarels 			p->p_sigignore |= bit;	/* easier in psignal */
13412951Ssam 		p->p_sigcatch &= ~bit;
13512882Ssam 	} else {
13612951Ssam 		p->p_sigignore &= ~bit;
13739513Skarels 		if (sa->sa_handler == SIG_DFL)
13812951Ssam 			p->p_sigcatch &= ~bit;
13912882Ssam 		else
14012951Ssam 			p->p_sigcatch |= bit;
14112882Ssam 	}
14212882Ssam 	(void) spl0();
14312882Ssam }
14412882Ssam 
14539513Skarels /*
14639513Skarels  * Initialize signal state for process 0;
14739513Skarels  * set to ignore signals that are ignored by default.
14839513Skarels  */
14947540Skarels void
15039513Skarels siginit(p)
15139513Skarels 	struct proc *p;
1527421Sroot {
15347540Skarels 	register int i;
15439513Skarels 
15547540Skarels 	for (i = 0; i < NSIG; i++)
15647540Skarels 		if (sigprop[i] & SA_IGNORE && i != SIGCONT)
15747540Skarels 			p->p_sigignore |= sigmask(i);
15839513Skarels }
15939513Skarels 
16039513Skarels /*
16139513Skarels  * Reset signals for an exec of the specified process.
16239513Skarels  */
16347540Skarels void
16439513Skarels execsigs(p)
16539513Skarels 	register struct proc *p;
16639513Skarels {
16747540Skarels 	register struct sigacts *ps = p->p_sigacts;
16839513Skarels 	register int nc, mask;
16939513Skarels 
17039513Skarels 	/*
17139513Skarels 	 * Reset caught signals.  Held signals remain held
17239513Skarels 	 * through p_sigmask (unless they were caught,
17339513Skarels 	 * and are now ignored by default).
17439513Skarels 	 */
17539513Skarels 	while (p->p_sigcatch) {
17639513Skarels 		nc = ffs((long)p->p_sigcatch);
17739513Skarels 		mask = sigmask(nc);
17839513Skarels 		p->p_sigcatch &= ~mask;
17947540Skarels 		if (sigprop[nc] & SA_IGNORE) {
18039513Skarels 			if (nc != SIGCONT)
18139513Skarels 				p->p_sigignore |= mask;
18239513Skarels 			p->p_sig &= ~mask;
18339513Skarels 		}
18447540Skarels 		ps->ps_sigact[nc] = SIG_DFL;
18539513Skarels 	}
18639513Skarels 	/*
18739513Skarels 	 * Reset stack state to the user stack.
18839513Skarels 	 * Clear set of signals caught on the signal stack.
18939513Skarels 	 */
190*53218Smckusick 	ps->ps_sigstk.ss_flags = SA_DISABLE;
191*53218Smckusick 	ps->ps_sigstk.ss_size = 0;
192*53218Smckusick 	ps->ps_sigstk.ss_base = 0;
193*53218Smckusick 	ps->ps_flags = 0;
19439513Skarels }
19539513Skarels 
19639513Skarels /*
19739513Skarels  * Manipulate signal mask.
19839513Skarels  * Note that we receive new mask, not pointer,
19939513Skarels  * and return old mask as return value;
20039513Skarels  * the library stub does the rest.
20139513Skarels  */
20242920Skarels sigprocmask(p, uap, retval)
20342920Skarels 	register struct proc *p;
20442920Skarels 	struct args {
20539513Skarels 		int	how;
20639513Skarels 		sigset_t mask;
20742920Skarels 	} *uap;
20842920Skarels 	int *retval;
20942920Skarels {
21039513Skarels 	int error = 0;
21139513Skarels 
21242920Skarels 	*retval = p->p_sigmask;
21339513Skarels 	(void) splhigh();
21439513Skarels 
21539513Skarels 	switch (uap->how) {
21639513Skarels 	case SIG_BLOCK:
21739513Skarels 		p->p_sigmask |= uap->mask &~ sigcantmask;
21839513Skarels 		break;
21939513Skarels 
22039513Skarels 	case SIG_UNBLOCK:
22139513Skarels 		p->p_sigmask &= ~uap->mask;
22239513Skarels 		break;
22339513Skarels 
22439513Skarels 	case SIG_SETMASK:
22539513Skarels 		p->p_sigmask = uap->mask &~ sigcantmask;
22639513Skarels 		break;
22739513Skarels 
22839513Skarels 	default:
22939513Skarels 		error = EINVAL;
23039513Skarels 		break;
23139513Skarels 	}
23239513Skarels 	(void) spl0();
23344405Skarels 	return (error);
23439513Skarels }
23539513Skarels 
23642920Skarels /* ARGSUSED */
23742920Skarels sigpending(p, uap, retval)
23842920Skarels 	struct proc *p;
23942920Skarels 	void *uap;
24042920Skarels 	int *retval;
24139513Skarels {
24239513Skarels 
24342920Skarels 	*retval = p->p_sig;
24444405Skarels 	return (0);
24539513Skarels }
24639513Skarels 
24752400Storek #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
24839513Skarels /*
24939513Skarels  * Generalized interface signal handler, 4.3-compatible.
25039513Skarels  */
25142920Skarels /* ARGSUSED */
25242920Skarels osigvec(p, uap, retval)
25342920Skarels 	struct proc *p;
25442920Skarels 	register struct args {
25539513Skarels 		int	signo;
25639513Skarels 		struct	sigvec *nsv;
25739513Skarels 		struct	sigvec *osv;
25842920Skarels 	} *uap;
25942920Skarels 	int *retval;
26042920Skarels {
26139513Skarels 	struct sigvec vec;
26247540Skarels 	register struct sigacts *ps = p->p_sigacts;
26339513Skarels 	register struct sigvec *sv;
26439513Skarels 	register int sig;
26539513Skarels 	int bit, error;
26639513Skarels 
26739513Skarels 	sig = uap->signo;
26839513Skarels 	if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
26944405Skarels 		return (EINVAL);
27039513Skarels 	sv = &vec;
27139513Skarels 	if (uap->osv) {
27247540Skarels 		*(sig_t *)&sv->sv_handler = ps->ps_sigact[sig];
27347540Skarels 		sv->sv_mask = ps->ps_catchmask[sig];
27439513Skarels 		bit = sigmask(sig);
27539513Skarels 		sv->sv_flags = 0;
27647540Skarels 		if ((ps->ps_sigonstack & bit) != 0)
27739513Skarels 			sv->sv_flags |= SV_ONSTACK;
27847540Skarels 		if ((ps->ps_sigintr & bit) != 0)
27939513Skarels 			sv->sv_flags |= SV_INTERRUPT;
28052400Storek #ifndef COMPAT_SUNOS
28142920Skarels 		if (p->p_flag & SNOCLDSTOP)
28239513Skarels 			sv->sv_flags |= SA_NOCLDSTOP;
28352400Storek #endif
28439513Skarels 		if (error = copyout((caddr_t)sv, (caddr_t)uap->osv,
28539513Skarels 		    sizeof (vec)))
28644405Skarels 			return (error);
28739513Skarels 	}
28839513Skarels 	if (uap->nsv) {
28939513Skarels 		if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv,
29039513Skarels 		    sizeof (vec)))
29144405Skarels 			return (error);
29252400Storek #ifdef COMPAT_SUNOS
29352400Storek 		/*
29452400Storek 		 * SunOS uses this bit (SA_NOCLDSTOP) as SV_RESETHAND,
29552400Storek 		 * `reset to SIG_DFL on delivery'. We have no such
29652400Storek 		 * option now or ever!
29752400Storek 		 */
29852400Storek 		if (sv->sv_flags & SA_NOCLDSTOP)
29952400Storek 			return (EINVAL);
30052400Storek 		sv->sv_flags |= SA_USERTRAMP;
30152400Storek #endif
30239513Skarels 		sv->sv_flags ^= SA_RESTART;	/* opposite of SV_INTERRUPT */
30342920Skarels 		setsigvec(p, sig, (struct sigaction *)sv);
30439513Skarels 	}
30544405Skarels 	return (0);
30639513Skarels }
30739513Skarels 
30842920Skarels osigblock(p, uap, retval)
30942920Skarels 	register struct proc *p;
31042920Skarels 	struct args {
31142920Skarels 		int	mask;
31242920Skarels 	} *uap;
31342920Skarels 	int *retval;
31439513Skarels {
3157499Sroot 
31617153Sbloom 	(void) splhigh();
31742920Skarels 	*retval = p->p_sigmask;
31839513Skarels 	p->p_sigmask |= uap->mask &~ sigcantmask;
31912882Ssam 	(void) spl0();
32044405Skarels 	return (0);
3217499Sroot }
3227499Sroot 
32342920Skarels osigsetmask(p, uap, retval)
32442920Skarels 	struct proc *p;
32542920Skarels 	struct args {
32642920Skarels 		int	mask;
32742920Skarels 	} *uap;
32842920Skarels 	int *retval;
3297499Sroot {
3307499Sroot 
33117153Sbloom 	(void) splhigh();
33242920Skarels 	*retval = p->p_sigmask;
33339513Skarels 	p->p_sigmask = uap->mask &~ sigcantmask;
33412882Ssam 	(void) spl0();
33544405Skarels 	return (0);
3367499Sroot }
33739513Skarels #endif
3387499Sroot 
33939513Skarels /*
34039513Skarels  * Suspend process until signal, providing mask to be set
34139513Skarels  * in the meantime.  Note nonstandard calling convention:
34239513Skarels  * libc stub passes mask, not pointer, to save a copyin.
34339513Skarels  */
34442920Skarels /* ARGSUSED */
34542920Skarels sigsuspend(p, uap, retval)
34642920Skarels 	register struct proc *p;
34742920Skarels 	struct args {
34842920Skarels 		sigset_t mask;
34942920Skarels 	} *uap;
35042920Skarels 	int *retval;
3517499Sroot {
35247540Skarels 	register struct sigacts *ps = p->p_sigacts;
3537499Sroot 
35412882Ssam 	/*
35512882Ssam 	 * When returning from sigpause, we want
35612882Ssam 	 * the old mask to be restored after the
35712882Ssam 	 * signal handler has finished.  Thus, we
35852115Skarels 	 * save it here and mark the sigacts structure
35952115Skarels 	 * to indicate this.
36012882Ssam 	 */
36147540Skarels 	ps->ps_oldmask = p->p_sigmask;
362*53218Smckusick 	ps->ps_flags |= SAS_OLDMASK;
36339513Skarels 	p->p_sigmask = uap->mask &~ sigcantmask;
36447540Skarels 	(void) tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0);
36540807Smarc 	/* always return EINTR rather than ERESTART... */
36644405Skarels 	return (EINTR);
3677499Sroot }
3687499Sroot 
369*53218Smckusick #ifdef COMPAT_43
37042920Skarels /* ARGSUSED */
371*53218Smckusick osigstack(p, uap, retval)
37242920Skarels 	struct proc *p;
37342920Skarels 	register struct args {
37412951Ssam 		struct	sigstack *nss;
37512951Ssam 		struct	sigstack *oss;
37642920Skarels 	} *uap;
37742920Skarels 	int *retval;
37842920Skarels {
37912951Ssam 	struct sigstack ss;
380*53218Smckusick 	struct sigacts *psp;
38139513Skarels 	int error = 0;
3827499Sroot 
383*53218Smckusick 	psp = p->p_sigacts;
384*53218Smckusick 	ss.ss_sp = psp->ps_sigstk.ss_base;
385*53218Smckusick 	ss.ss_onstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
386*53218Smckusick 	if (uap->oss && (error = copyout((caddr_t)&ss, (caddr_t)uap->oss,
387*53218Smckusick 	    sizeof (struct sigstack))))
38844405Skarels 		return (error);
38939513Skarels 	if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
390*53218Smckusick 	    sizeof (ss))) == 0) {
391*53218Smckusick 		psp->ps_sigstk.ss_base = ss.ss_sp;
392*53218Smckusick 		psp->ps_sigstk.ss_size = 0;
393*53218Smckusick 		psp->ps_sigstk.ss_flags |= ss.ss_onstack & SA_ONSTACK;
394*53218Smckusick 		psp->ps_flags |= SAS_ALTSTACK;
395*53218Smckusick 	}
39644405Skarels 	return (error);
3977499Sroot }
398*53218Smckusick #endif /* COMPAT_43 */
3997499Sroot 
40042920Skarels /* ARGSUSED */
401*53218Smckusick sigaltstack(p, uap, retval)
402*53218Smckusick 	struct proc *p;
403*53218Smckusick 	register struct args {
404*53218Smckusick 		struct	sigaltstack *nss;
405*53218Smckusick 		struct	sigaltstack *oss;
406*53218Smckusick 	} *uap;
407*53218Smckusick 	int *retval;
408*53218Smckusick {
409*53218Smckusick 	struct sigacts *psp;
410*53218Smckusick 	struct sigaltstack ss;
411*53218Smckusick 	int error;
412*53218Smckusick 
413*53218Smckusick 	psp = p->p_sigacts;
414*53218Smckusick 	if ((psp->ps_flags & SAS_ALTSTACK) == 0)
415*53218Smckusick 		psp->ps_sigstk.ss_flags |= SA_DISABLE;
416*53218Smckusick 	if (uap->oss && (error = copyout((caddr_t)&psp->ps_sigstk,
417*53218Smckusick 	    (caddr_t)uap->oss, sizeof (struct sigaltstack))))
418*53218Smckusick 		return (error);
419*53218Smckusick 	if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
420*53218Smckusick 	    sizeof (ss))))
421*53218Smckusick 		return (error);
422*53218Smckusick 	if (ss.ss_flags & SA_DISABLE) {
423*53218Smckusick 		if (psp->ps_sigstk.ss_flags & SA_ONSTACK)
424*53218Smckusick 			return (EINVAL);
425*53218Smckusick 		psp->ps_flags &= ~SAS_ALTSTACK;
426*53218Smckusick 		psp->ps_sigstk.ss_flags = ss.ss_flags;
427*53218Smckusick 		return (0);
428*53218Smckusick 	}
429*53218Smckusick 	if (ss.ss_size < MINSIGSTKSZ)
430*53218Smckusick 		return (ENOMEM);
431*53218Smckusick 	psp->ps_flags |= SAS_ALTSTACK;
432*53218Smckusick 	psp->ps_sigstk= ss;
433*53218Smckusick 	return (0);
434*53218Smckusick }
435*53218Smckusick 
436*53218Smckusick /* ARGSUSED */
43742920Skarels kill(cp, uap, retval)
43842920Skarels 	register struct proc *cp;
43942920Skarels 	register struct args {
44012882Ssam 		int	pid;
44112882Ssam 		int	signo;
44242920Skarels 	} *uap;
44342920Skarels 	int *retval;
44442920Skarels {
44518336Smckusick 	register struct proc *p;
44647540Skarels 	register struct pcred *pc = cp->p_cred;
4478032Sroot 
44839513Skarels 	if ((unsigned) uap->signo >= NSIG)
44944405Skarels 		return (EINVAL);
45018336Smckusick 	if (uap->pid > 0) {
45118336Smckusick 		/* kill single process */
45218336Smckusick 		p = pfind(uap->pid);
45339513Skarels 		if (p == 0)
45444405Skarels 			return (ESRCH);
45547540Skarels 		if (!CANSIGNAL(cp, pc, p, uap->signo))
45644405Skarels 			return (EPERM);
45739513Skarels 		if (uap->signo)
45818336Smckusick 			psignal(p, uap->signo);
45944405Skarels 		return (0);
46018336Smckusick 	}
46118336Smckusick 	switch (uap->pid) {
46218336Smckusick 	case -1:		/* broadcast signal */
46344405Skarels 		return (killpg1(cp, uap->signo, 0, 1));
46418336Smckusick 	case 0:			/* signal own process group */
46544405Skarels 		return (killpg1(cp, uap->signo, 0, 0));
46618336Smckusick 	default:		/* negative explicit process group */
46744405Skarels 		return (killpg1(cp, uap->signo, -uap->pid, 0));
46818336Smckusick 	}
46939513Skarels 	/* NOTREACHED */
4708032Sroot }
4718032Sroot 
47252400Storek #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
47342920Skarels /* ARGSUSED */
47442920Skarels okillpg(p, uap, retval)
47542920Skarels 	struct proc *p;
47642920Skarels 	register struct args {
47737581Smckusick 		int	pgid;
4789989Ssam 		int	signo;
47942920Skarels 	} *uap;
48042920Skarels 	int *retval;
48142920Skarels {
4828032Sroot 
48339513Skarels 	if ((unsigned) uap->signo >= NSIG)
48444405Skarels 		return (EINVAL);
48544405Skarels 	return (killpg1(p, uap->signo, uap->pgid, 0));
4868032Sroot }
48739513Skarels #endif
4888032Sroot 
48942920Skarels /*
49042920Skarels  * Common code for kill process group/broadcast kill.
49142920Skarels  * cp is calling process.
49242920Skarels  */
49342920Skarels killpg1(cp, signo, pgid, all)
49442920Skarels 	register struct proc *cp;
49537581Smckusick 	int signo, pgid, all;
4969989Ssam {
4979989Ssam 	register struct proc *p;
49847540Skarels 	register struct pcred *pc = cp->p_cred;
49937581Smckusick 	struct pgrp *pgrp;
50047540Skarels 	int nfound = 0;
50137581Smckusick 
50237581Smckusick 	if (all)
50337581Smckusick 		/*
50437581Smckusick 		 * broadcast
5057421Sroot 		 */
50637581Smckusick 		for (p = allproc; p != NULL; p = p->p_nxt) {
50747540Skarels 			if (p->p_pid <= 1 || p->p_flag&SSYS ||
50847540Skarels 			    p == cp || !CANSIGNAL(cp, pc, p, signo))
50937581Smckusick 				continue;
51047540Skarels 			nfound++;
51137581Smckusick 			if (signo)
51237581Smckusick 				psignal(p, signo);
51337581Smckusick 		}
51437581Smckusick 	else {
51537581Smckusick 		if (pgid == 0)
51637581Smckusick 			/*
51737581Smckusick 			 * zero pgid means send to my process group.
51837581Smckusick 			 */
51947540Skarels 			pgrp = cp->p_pgrp;
52037581Smckusick 		else {
52137581Smckusick 			pgrp = pgfind(pgid);
52237581Smckusick 			if (pgrp == NULL)
52339513Skarels 				return (ESRCH);
52437581Smckusick 		}
52537581Smckusick 		for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) {
52647540Skarels 			if (p->p_pid <= 1 || p->p_flag&SSYS ||
52750128Skarels 			    p->p_stat == SZOMB || !CANSIGNAL(cp, pc, p, signo))
52837581Smckusick 				continue;
52947540Skarels 			nfound++;
53037581Smckusick 			if (signo)
53137581Smckusick 				psignal(p, signo);
53218336Smckusick 		}
5337421Sroot 	}
53447540Skarels 	return (nfound ? 0 : ESRCH);
5357421Sroot }
5367421Sroot 
53742920Skarels /*
5387421Sroot  * Send the specified signal to
53937581Smckusick  * all processes with 'pgid' as
5407421Sroot  * process group.
5417421Sroot  */
54247540Skarels void
54337581Smckusick gsignal(pgid, sig)
54447540Skarels 	int pgid, sig;
5457421Sroot {
54639513Skarels 	struct pgrp *pgrp;
5477421Sroot 
54839513Skarels 	if (pgid && (pgrp = pgfind(pgid)))
54942207Smarc 		pgsignal(pgrp, sig, 0);
5507421Sroot }
55142920Skarels 
55240807Smarc /*
55342207Smarc  * Send sig to every member of a process group.
55442207Smarc  * If checktty is 1, limit to members which have a controlling
55542207Smarc  * terminal.
55640807Smarc  */
55747540Skarels void
55842207Smarc pgsignal(pgrp, sig, checkctty)
55939513Skarels 	struct pgrp *pgrp;
56047540Skarels 	int sig, checkctty;
56137581Smckusick {
56237581Smckusick 	register struct proc *p;
56337581Smckusick 
56440807Smarc 	if (pgrp)
56540807Smarc 		for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt)
56642207Smarc 			if (checkctty == 0 || p->p_flag&SCTTY)
56742207Smarc 				psignal(p, sig);
56837581Smckusick }
56937581Smckusick 
5707421Sroot /*
57139513Skarels  * Send a signal caused by a trap to the current process.
57239513Skarels  * If it will be caught immediately, deliver it with correct code.
57339513Skarels  * Otherwise, post it normally.
57439513Skarels  */
57547540Skarels void
57647540Skarels trapsignal(p, sig, code)
57747540Skarels 	struct proc *p;
57839513Skarels 	register int sig;
57939513Skarels 	unsigned code;
58039513Skarels {
58147540Skarels 	register struct sigacts *ps = p->p_sigacts;
58239513Skarels 	int mask;
58339513Skarels 
58439513Skarels 	mask = sigmask(sig);
58539513Skarels 	if ((p->p_flag & STRC) == 0 && (p->p_sigcatch & mask) != 0 &&
58639513Skarels 	    (p->p_sigmask & mask) == 0) {
58747540Skarels 		p->p_stats->p_ru.ru_nsignals++;
58840807Smarc #ifdef KTRACE
58940807Smarc 		if (KTRPOINT(p, KTR_PSIG))
59047540Skarels 			ktrpsig(p->p_tracep, sig, ps->ps_sigact[sig],
59140807Smarc 				p->p_sigmask, code);
59240807Smarc #endif
59347540Skarels 		sendsig(ps->ps_sigact[sig], sig, p->p_sigmask, code);
59447540Skarels 		p->p_sigmask |= ps->ps_catchmask[sig] | mask;
59539513Skarels 	} else {
59647540Skarels 		ps->ps_code = code;	/* XXX for core dump/debugger */
59739513Skarels 		psignal(p, sig);
59839513Skarels 	}
59939513Skarels }
60039513Skarels 
60139513Skarels /*
60240807Smarc  * Send the specified signal to the specified process.
60347540Skarels  * If the signal has an action, the action is usually performed
60447540Skarels  * by the target process rather than the caller; we simply add
60547540Skarels  * the signal to the set of pending signals for the process.
60640807Smarc  * Exceptions:
60740807Smarc  *   o When a stop signal is sent to a sleeping process that takes the default
60840807Smarc  *     action, the process is stopped without awakening it.
60940807Smarc  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
61040807Smarc  *     regardless of the signal action (eg, blocked or ignored).
61140807Smarc  * Other ignored signals are discarded immediately.
6127421Sroot  */
61347540Skarels void
6147421Sroot psignal(p, sig)
6157421Sroot 	register struct proc *p;
6167421Sroot 	register int sig;
6177421Sroot {
61847540Skarels 	register int s, prop;
61939513Skarels 	register sig_t action;
62017153Sbloom 	int mask;
6217421Sroot 
62239513Skarels 	if ((unsigned)sig >= NSIG || sig == 0)
62339513Skarels 		panic("psignal sig");
62417153Sbloom 	mask = sigmask(sig);
62547540Skarels 	prop = sigprop[sig];
6267421Sroot 
6277421Sroot 	/*
6287421Sroot 	 * If proc is traced, always give parent a chance.
6297421Sroot 	 */
6307421Sroot 	if (p->p_flag & STRC)
6317421Sroot 		action = SIG_DFL;
6327421Sroot 	else {
6337421Sroot 		/*
63412882Ssam 		 * If the signal is being ignored,
63512882Ssam 		 * then we forget about it immediately.
63639513Skarels 		 * (Note: we don't set SIGCONT in p_sigignore,
63739513Skarels 		 * and if it is set to SIG_IGN,
63839513Skarels 		 * action will be SIG_DFL here.)
6397421Sroot 		 */
64017153Sbloom 		if (p->p_sigignore & mask)
6417421Sroot 			return;
64217153Sbloom 		if (p->p_sigmask & mask)
64312882Ssam 			action = SIG_HOLD;
64417153Sbloom 		else if (p->p_sigcatch & mask)
64512882Ssam 			action = SIG_CATCH;
64642437Skarels 		else
64712882Ssam 			action = SIG_DFL;
6487421Sroot 	}
6497421Sroot 
65047540Skarels 	if (p->p_nice > NZERO && (sig == SIGKILL ||
65147540Skarels 	    sig == SIGTERM && (p->p_flag&STRC || action != SIG_DFL)))
65247540Skarels 		p->p_nice = NZERO;
6537421Sroot 
65447540Skarels 	if (prop & SA_CONT)
65539513Skarels 		p->p_sig &= ~stopsigmask;
65639513Skarels 
65747540Skarels 	if (prop & SA_STOP) {
65845672Skarels 		/*
65945672Skarels 		 * If sending a tty stop signal to a member of an orphaned
66045672Skarels 		 * process group, discard the signal here if the action
66145672Skarels 		 * is default; don't stop the process below if sleeping,
66245672Skarels 		 * and don't clear any pending SIGCONT.
66345672Skarels 		 */
66447540Skarels 		if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
66547540Skarels 		    action == SIG_DFL)
66645741Smckusick 		        return;
66747540Skarels 		p->p_sig &= ~contsigmask;
6687421Sroot 	}
66939513Skarels 	p->p_sig |= mask;
67039513Skarels 
6717421Sroot 	/*
67239513Skarels 	 * Defer further processing for signals which are held,
67339513Skarels 	 * except that stopped processes must be continued by SIGCONT.
6747421Sroot 	 */
67547540Skarels 	if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
6767421Sroot 		return;
67717153Sbloom 	s = splhigh();
6787421Sroot 	switch (p->p_stat) {
6797421Sroot 
6807421Sroot 	case SSLEEP:
6817421Sroot 		/*
68240807Smarc 		 * If process is sleeping uninterruptibly
6837421Sroot 		 * we can't interrupt the sleep... the signal will
6847421Sroot 		 * be noticed when the process returns through
6857421Sroot 		 * trap() or syscall().
6867421Sroot 		 */
68740807Smarc 		if ((p->p_flag & SSINTR) == 0)
6887421Sroot 			goto out;
6897421Sroot 		/*
6907421Sroot 		 * Process is sleeping and traced... make it runnable
6917421Sroot 		 * so it can discover the signal in issig() and stop
6927421Sroot 		 * for the parent.
6937421Sroot 		 */
6947421Sroot 		if (p->p_flag&STRC)
6957421Sroot 			goto run;
69639513Skarels 		/*
69739513Skarels 		 * When a sleeping process receives a stop
69839513Skarels 		 * signal, process immediately if possible.
69939513Skarels 		 * All other (caught or default) signals
70039513Skarels 		 * cause the process to run.
70139513Skarels 		 */
70247540Skarels 		if (prop & SA_STOP) {
7037421Sroot 			if (action != SIG_DFL)
70439513Skarels 				goto runfast;
7057421Sroot 			/*
70647540Skarels 			 * If a child holding parent blocked,
70747540Skarels 			 * stopping could cause deadlock.
7087421Sroot 			 */
70947540Skarels 			if (p->p_flag&SPPWAIT)
7107421Sroot 				goto out;
71117153Sbloom 			p->p_sig &= ~mask;
71243895Skarels 			p->p_xstat = sig;
71339513Skarels 			if ((p->p_pptr->p_flag & SNOCLDSTOP) == 0)
71439513Skarels 				psignal(p->p_pptr, SIGCHLD);
7157421Sroot 			stop(p);
7167421Sroot 			goto out;
71739513Skarels 		} else
71839513Skarels 			goto runfast;
7197421Sroot 		/*NOTREACHED*/
7207421Sroot 
7217421Sroot 	case SSTOP:
7227421Sroot 		/*
7237421Sroot 		 * If traced process is already stopped,
7247421Sroot 		 * then no further action is necessary.
7257421Sroot 		 */
7267421Sroot 		if (p->p_flag&STRC)
7277421Sroot 			goto out;
7287421Sroot 
72947540Skarels 		/*
73047540Skarels 		 * Kill signal always sets processes running.
73147540Skarels 		 */
73247540Skarels 		if (sig == SIGKILL)
73339513Skarels 			goto runfast;
7347421Sroot 
73547540Skarels 		if (prop & SA_CONT) {
7367421Sroot 			/*
73739513Skarels 			 * If SIGCONT is default (or ignored), we continue
73839513Skarels 			 * the process but don't leave the signal in p_sig,
73939513Skarels 			 * as it has no further action.  If SIGCONT is held,
74039513Skarels 			 * continue the process and leave the signal in p_sig.
7417421Sroot 			 * If the process catches SIGCONT, let it handle
7427421Sroot 			 * the signal itself.  If it isn't waiting on
7437421Sroot 			 * an event, then it goes back to run state.
7447421Sroot 			 * Otherwise, process goes back to sleep state.
7457421Sroot 			 */
74639513Skarels 			if (action == SIG_DFL)
74739513Skarels 				p->p_sig &= ~mask;
74839513Skarels 			if (action == SIG_CATCH)
74939513Skarels 				goto runfast;
75039513Skarels 			if (p->p_wchan == 0)
7517421Sroot 				goto run;
7527421Sroot 			p->p_stat = SSLEEP;
7537421Sroot 			goto out;
75447540Skarels 		}
7557421Sroot 
75647540Skarels 		if (prop & SA_STOP) {
7577421Sroot 			/*
7587421Sroot 			 * Already stopped, don't need to stop again.
7597421Sroot 			 * (If we did the shell could get confused.)
7607421Sroot 			 */
76117153Sbloom 			p->p_sig &= ~mask;		/* take it away */
7627421Sroot 			goto out;
7637421Sroot 		}
7647421Sroot 
76547540Skarels 		/*
76647540Skarels 		 * If process is sleeping interruptibly, then
76747540Skarels 		 * simulate a wakeup so that when it is continued,
76847540Skarels 		 * it will be made runnable and can look at the signal.
76947540Skarels 		 * But don't setrun the process, leave it stopped.
77047540Skarels 		 */
77147540Skarels 		if (p->p_wchan && p->p_flag & SSINTR)
77247540Skarels 			unsleep(p);
77347540Skarels 		goto out;
77447540Skarels 
7757421Sroot 	default:
7767421Sroot 		/*
7777421Sroot 		 * SRUN, SIDL, SZOMB do nothing with the signal,
7787421Sroot 		 * other than kicking ourselves if we are running.
7797421Sroot 		 * It will either never be noticed, or noticed very soon.
7807421Sroot 		 */
78147650Skarels 		if (p == curproc)
78249102Skarels 			signotify(p);
7837421Sroot 		goto out;
7847421Sroot 	}
7857421Sroot 	/*NOTREACHED*/
78639513Skarels 
78739513Skarels runfast:
7887421Sroot 	/*
7897421Sroot 	 * Raise priority to at least PUSER.
7907421Sroot 	 */
7917421Sroot 	if (p->p_pri > PUSER)
79217399Skarels 		p->p_pri = PUSER;
79339513Skarels run:
7947421Sroot 	setrun(p);
7957421Sroot out:
7967421Sroot 	splx(s);
7977421Sroot }
7987421Sroot 
7997421Sroot /*
80040807Smarc  * If the current process has a signal to process (should be caught
80140807Smarc  * or cause termination, should interrupt current syscall),
80240807Smarc  * return the signal number.  Stop signals with default action
80340807Smarc  * are processed immediately, then cleared; they aren't returned.
80447540Skarels  * This is checked after each entry to the system for a syscall
80547540Skarels  * or trap (though this can usually be done without actually calling
80647540Skarels  * issig by checking the pending signal masks in the CURSIG macro.)
80747540Skarels  * The normal call sequence is
80847540Skarels  *
80947540Skarels  *	while (sig = CURSIG(curproc))
81047540Skarels  *		psig(sig);
8117421Sroot  */
81247540Skarels issig(p)
81347540Skarels 	register struct proc *p;
8147421Sroot {
81547540Skarels 	register int sig, mask, prop;
8167421Sroot 
8177421Sroot 	for (;;) {
81839513Skarels 		mask = p->p_sig &~ p->p_sigmask;
81947540Skarels 		if (p->p_flag&SPPWAIT)
82039513Skarels 			mask &= ~stopsigmask;
82140807Smarc 		if (mask == 0)	 	/* no signal to send */
82240807Smarc 			return (0);
82339513Skarels 		sig = ffs((long)mask);
82417153Sbloom 		mask = sigmask(sig);
82547540Skarels 		prop = sigprop[sig];
82640807Smarc 		/*
82740807Smarc 		 * We should see pending but ignored signals
82840807Smarc 		 * only if STRC was on when they were posted.
82940807Smarc 		 */
83040807Smarc 		if (mask & p->p_sigignore && (p->p_flag&STRC) == 0) {
83140807Smarc 			p->p_sig &= ~mask;
83240807Smarc 			continue;
83340807Smarc 		}
83447540Skarels 		if (p->p_flag&STRC && (p->p_flag&SPPWAIT) == 0) {
8357421Sroot 			/*
8367421Sroot 			 * If traced, always stop, and stay
8377421Sroot 			 * stopped until released by the parent.
8387421Sroot 			 */
83943895Skarels 			p->p_xstat = sig;
84018331Skarels 			psignal(p->p_pptr, SIGCHLD);
8417421Sroot 			do {
8427421Sroot 				stop(p);
8437421Sroot 				swtch();
84442926Smckusick 			} while (!procxmt(p) && p->p_flag&STRC);
8457421Sroot 
8467421Sroot 			/*
84714782Ssam 			 * If the traced bit got turned off,
84840807Smarc 			 * go back up to the top to rescan signals.
84947650Skarels 			 * This ensures that p_sig* and ps_sigact
85047650Skarels 			 * are consistent.
8517421Sroot 			 */
85240807Smarc 			if ((p->p_flag&STRC) == 0)
8537421Sroot 				continue;
8547421Sroot 
8557421Sroot 			/*
8567421Sroot 			 * If parent wants us to take the signal,
85743895Skarels 			 * then it will leave it in p->p_xstat;
8587421Sroot 			 * otherwise we just look for signals again.
8597421Sroot 			 */
86040807Smarc 			p->p_sig &= ~mask;	/* clear the old signal */
86143895Skarels 			sig = p->p_xstat;
8627421Sroot 			if (sig == 0)
8637421Sroot 				continue;
86414782Ssam 
86514782Ssam 			/*
86640807Smarc 			 * Put the new signal into p_sig.
86740807Smarc 			 * If signal is being masked,
86840807Smarc 			 * look for other signals.
86914782Ssam 			 */
87017153Sbloom 			mask = sigmask(sig);
87140807Smarc 			p->p_sig |= mask;
87240807Smarc 			if (p->p_sigmask & mask)
87314782Ssam 				continue;
8747421Sroot 		}
87540807Smarc 
87640807Smarc 		/*
87740807Smarc 		 * Decide whether the signal should be returned.
87840807Smarc 		 * Return the signal's number, or fall through
87940807Smarc 		 * to clear it from the pending mask.
88040807Smarc 		 */
88147540Skarels 		switch ((int)p->p_sigacts->ps_sigact[sig]) {
8827421Sroot 
8837421Sroot 		case SIG_DFL:
8847421Sroot 			/*
8857421Sroot 			 * Don't take default actions on system processes.
8867421Sroot 			 */
88751019Sralph 			if (p->p_pid <= 1) {
88851019Sralph #ifdef DIAGNOSTIC
88951019Sralph 				/*
89051019Sralph 				 * Are you sure you want to ignore SIGSEGV
89151019Sralph 				 * in init? XXX
89251019Sralph 				 */
89351019Sralph 				printf("Process (pid %d) got signal %d\n",
89451019Sralph 					p->p_pid, sig);
89551019Sralph #endif
89640807Smarc 				break;		/* == ignore */
89751019Sralph 			}
89840807Smarc 			/*
89940807Smarc 			 * If there is a pending stop signal to process
90040807Smarc 			 * with default action, stop here,
90142437Skarels 			 * then clear the signal.  However,
90242437Skarels 			 * if process is member of an orphaned
90342437Skarels 			 * process group, ignore tty stop signals.
90440807Smarc 			 */
90547540Skarels 			if (prop & SA_STOP) {
90642437Skarels 				if (p->p_flag&STRC ||
90742437Skarels 		    		    (p->p_pgrp->pg_jobc == 0 &&
90847540Skarels 				    prop & SA_TTYSTOP))
90940807Smarc 					break;	/* == ignore */
91043895Skarels 				p->p_xstat = sig;
9117421Sroot 				stop(p);
91239513Skarels 				if ((p->p_pptr->p_flag & SNOCLDSTOP) == 0)
91339513Skarels 					psignal(p->p_pptr, SIGCHLD);
9147421Sroot 				swtch();
91540807Smarc 				break;
91647540Skarels 			} else if (prop & SA_IGNORE) {
9177421Sroot 				/*
91839513Skarels 				 * Except for SIGCONT, shouldn't get here.
91939513Skarels 				 * Default action is to ignore; drop it.
9207421Sroot 				 */
92140807Smarc 				break;		/* == ignore */
92239513Skarels 			} else
92340807Smarc 				return (sig);
9247421Sroot 			/*NOTREACHED*/
9257421Sroot 
9267421Sroot 		case SIG_IGN:
9277421Sroot 			/*
92839513Skarels 			 * Masking above should prevent us ever trying
92939513Skarels 			 * to take action on an ignored signal other
93039513Skarels 			 * than SIGCONT, unless process is traced.
9317421Sroot 			 */
93247540Skarels 			if ((prop & SA_CONT) == 0 && (p->p_flag&STRC) == 0)
9337421Sroot 				printf("issig\n");
93440807Smarc 			break;		/* == ignore */
9357421Sroot 
9367421Sroot 		default:
9377421Sroot 			/*
9387421Sroot 			 * This signal has an action, let
9397421Sroot 			 * psig process it.
9407421Sroot 			 */
94140807Smarc 			return (sig);
9427421Sroot 		}
94340807Smarc 		p->p_sig &= ~mask;		/* take the signal! */
9447421Sroot 	}
94540807Smarc 	/* NOTREACHED */
9467421Sroot }
9477421Sroot 
9487421Sroot /*
9497421Sroot  * Put the argument process into the stopped
95018331Skarels  * state and notify the parent via wakeup.
95118331Skarels  * Signals are handled elsewhere.
95240807Smarc  * The process must not be on the run queue.
9537421Sroot  */
9547421Sroot stop(p)
9557421Sroot 	register struct proc *p;
9567421Sroot {
9577421Sroot 
9587421Sroot 	p->p_stat = SSTOP;
9597421Sroot 	p->p_flag &= ~SWTED;
9607421Sroot 	wakeup((caddr_t)p->p_pptr);
9617421Sroot }
9627421Sroot 
9637421Sroot /*
96447540Skarels  * Take the action for the specified signal
96547540Skarels  * from the current set of pending signals.
9667421Sroot  */
96747540Skarels void
96840807Smarc psig(sig)
96940807Smarc 	register int sig;
9707421Sroot {
97147540Skarels 	register struct proc *p = curproc;
97247540Skarels 	register struct sigacts *ps = p->p_sigacts;
97347540Skarels 	register sig_t action;
97439513Skarels 	int mask, returnmask;
9757421Sroot 
97640807Smarc #ifdef DIAGNOSTIC
97747540Skarels 	if (sig == 0)
97847540Skarels 		panic("psig");
97940807Smarc #endif
98047540Skarels 	mask = sigmask(sig);
98147540Skarels 	p->p_sig &= ~mask;
98247540Skarels 	action = ps->ps_sigact[sig];
98340807Smarc #ifdef KTRACE
98447540Skarels 	if (KTRPOINT(p, KTR_PSIG))
985*53218Smckusick 		ktrpsig(p->p_tracep, sig, action, ps->ps_flags & SAS_OLDMASK ?
98647540Skarels 		    ps->ps_oldmask : p->p_sigmask, 0);
98740807Smarc #endif
98847540Skarels 	if (action == SIG_DFL) {
98947540Skarels 		/*
99047540Skarels 		 * Default action, where the default is to kill
99147540Skarels 		 * the process.  (Other cases were ignored above.)
99247540Skarels 		 */
99347650Skarels 		sigexit(p, sig);
99447540Skarels 		/* NOTREACHED */
99547540Skarels 	} else {
99647540Skarels 		/*
99747540Skarels 		 * If we get here, the signal must be caught.
99847540Skarels 		 */
99939513Skarels #ifdef DIAGNOSTIC
100047540Skarels 		if (action == SIG_IGN || (p->p_sigmask & mask))
100147540Skarels 			panic("psig action");
100239513Skarels #endif
100347540Skarels 		/*
100447540Skarels 		 * Set the new mask value and also defer further
100547540Skarels 		 * occurences of this signal.
100647540Skarels 		 *
100747540Skarels 		 * Special case: user has done a sigpause.  Here the
100847540Skarels 		 * current mask is not of interest, but rather the
100947540Skarels 		 * mask from before the sigpause is what we want
101047540Skarels 		 * restored after the signal processing is completed.
101147540Skarels 		 */
101247540Skarels 		(void) splhigh();
1013*53218Smckusick 		if (ps->ps_flags & SAS_OLDMASK) {
101447540Skarels 			returnmask = ps->ps_oldmask;
1015*53218Smckusick 			ps->ps_flags &= ~SAS_OLDMASK;
101647540Skarels 		} else
101747540Skarels 			returnmask = p->p_sigmask;
101847540Skarels 		p->p_sigmask |= ps->ps_catchmask[sig] | mask;
101947540Skarels 		(void) spl0();
102047540Skarels 		p->p_stats->p_ru.ru_nsignals++;
102147540Skarels 		sendsig(action, sig, returnmask, 0);
102247540Skarels 	}
10237421Sroot }
10247421Sroot 
10257421Sroot /*
102647650Skarels  * Force the current process to exit with the specified
102747650Skarels  * signal, dumping core if appropriate.  We bypass the normal
102847650Skarels  * tests for masked and caught signals, allowing unrecoverable
102947650Skarels  * failures to terminate the process without changing signal state.
103047650Skarels  * Mark the accounting record with the signal termination.
103147650Skarels  * If dumping core, save the signal number for the debugger.
103247650Skarels  * Calls exit and does not return.
103347650Skarels  */
103447650Skarels sigexit(p, sig)
103547650Skarels 	register struct proc *p;
103647650Skarels 	int sig;
103747650Skarels {
103847650Skarels 
103947650Skarels 	p->p_acflag |= AXSIG;
104047650Skarels 	if (sigprop[sig] & SA_CORE) {
104147650Skarels 		p->p_sigacts->ps_sig = sig;
104247650Skarels 		if (coredump(p) == 0)
104347650Skarels 			sig |= WCOREFLAG;
104447650Skarels 	}
104547650Skarels 	exit(p, W_EXITCODE(0, sig));
104647650Skarels 	/* NOTREACHED */
104747650Skarels }
104847650Skarels 
104947650Skarels /*
105047540Skarels  * Create a core dump.
105150244Skarels  * The file name is "core.progname".
105250099Smckusick  * Core dumps are not created if the process is setuid.
10537421Sroot  */
105447540Skarels coredump(p)
105547540Skarels 	register struct proc *p;
10567421Sroot {
105737728Smckusick 	register struct vnode *vp;
105847540Skarels 	register struct pcred *pcred = p->p_cred;
105947540Skarels 	register struct ucred *cred = pcred->pc_ucred;
106047540Skarels 	register struct vmspace *vm = p->p_vmspace;
106137580Smckusick 	struct vattr vattr;
106250105Smckusick 	int error, error1;
106347540Skarels 	struct nameidata nd;
106450244Skarels 	char name[MAXCOMLEN+6];	/* core.progname */
10657421Sroot 
106647540Skarels 	if (pcred->p_svuid != pcred->p_ruid ||
106747540Skarels 	    pcred->p_svgid != pcred->p_rgid)
106837580Smckusick 		return (EFAULT);
106947540Skarels 	if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
107047540Skarels 	    p->p_rlimit[RLIMIT_CORE].rlim_cur)
107137580Smckusick 		return (EFAULT);
107250244Skarels 	sprintf(name, "core.%s", p->p_comm);
107352304Sheideman 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
107452304Sheideman 	if (error = vn_open(&nd, O_CREAT|FWRITE, 0644))
107537580Smckusick 		return (error);
107647540Skarels 	vp = nd.ni_vp;
107748020Smckusick 	if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred, p) ||
107837580Smckusick 	    vattr.va_nlink != 1) {
107950105Smckusick 		error = EFAULT;
108050105Smckusick 		goto out;
10817818Sroot 	}
108241362Smckusick 	VATTR_NULL(&vattr);
108337580Smckusick 	vattr.va_size = 0;
108452183Smckusick 	LEASE_CHECK(vp, p, cred, LEASE_WRITE);
108548020Smckusick 	VOP_SETATTR(vp, &vattr, cred, p);
108647540Skarels 	p->p_acflag |= ACORE;
108749102Skarels 	bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
108849102Skarels 	fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
108952925Smckusick 	error = cpu_coredump(p, vp, cred);
109037580Smckusick 	if (error == 0)
109147540Skarels 		error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
109247540Skarels 		    (int)ctob(vm->vm_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE,
109349102Skarels 		    IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
109437580Smckusick 	if (error == 0)
109537580Smckusick 		error = vn_rdwr(UIO_WRITE, vp,
109649102Skarels 		    (caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)),
109747540Skarels 		    round_page(ctob(vm->vm_ssize)),
109847540Skarels 		    (off_t)ctob(UPAGES) + ctob(vm->vm_dsize), UIO_USERSPACE,
109949102Skarels 		    IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
110050105Smckusick out:
110150105Smckusick 	VOP_UNLOCK(vp);
110250105Smckusick 	error1 = vn_close(vp, FWRITE, cred, p);
110350244Skarels 	if (error == 0)
110450105Smckusick 		error = error1;
110537580Smckusick 	return (error);
11067421Sroot }
110739513Skarels 
110839513Skarels /*
110939513Skarels  * Nonexistent system call-- signal process (may want to handle it).
111039513Skarels  * Flag error in case process won't see signal immediately (blocked or ignored).
111139513Skarels  */
111243364Smckusick /* ARGSUSED */
111343364Smckusick nosys(p, args, retval)
111443364Smckusick 	struct proc *p;
111543364Smckusick 	void *args;
111643364Smckusick 	int *retval;
111739513Skarels {
111839513Skarels 
111943364Smckusick 	psignal(p, SIGSYS);
112044405Skarels 	return (EINVAL);
112139513Skarels }
1122