xref: /csrg-svn/sys/kern/kern_sig.c (revision 69409)
123374Smckusick /*
263176Sbostic  * Copyright (c) 1982, 1986, 1989, 1991, 1993
363176Sbostic  *	The Regents of the University of California.  All rights reserved.
465771Sbostic  * (c) UNIX System Laboratories, Inc.
565771Sbostic  * All or some portions of this file are derived from material licensed
665771Sbostic  * to the University of California by American Telephone and Telegraph
765771Sbostic  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
865771Sbostic  * the permission of UNIX System Laboratories, Inc.
923374Smckusick  *
1044440Sbostic  * %sccs.include.redist.c%
1137580Smckusick  *
12*69409Smckusick  *	@(#)kern_sig.c	8.14 (Berkeley) 05/14/95
1323374Smckusick  */
147421Sroot 
1547540Skarels #define	SIGPROP		/* include signal properties table */
1656517Sbostic #include <sys/param.h>
1756517Sbostic #include <sys/signalvar.h>
1856517Sbostic #include <sys/resourcevar.h>
1956517Sbostic #include <sys/namei.h>
2056517Sbostic #include <sys/vnode.h>
2156517Sbostic #include <sys/proc.h>
2256517Sbostic #include <sys/systm.h>
2356517Sbostic #include <sys/timeb.h>
2456517Sbostic #include <sys/times.h>
2556517Sbostic #include <sys/buf.h>
2656517Sbostic #include <sys/acct.h>
2756517Sbostic #include <sys/file.h>
2856517Sbostic #include <sys/kernel.h>
2956517Sbostic #include <sys/wait.h>
3056517Sbostic #include <sys/ktrace.h>
3157533Smckusick #include <sys/syslog.h>
3264406Sbostic #include <sys/stat.h>
337421Sroot 
3468310Scgd #include <sys/mount.h>
3568310Scgd #include <sys/syscallargs.h>
3668310Scgd 
3756517Sbostic #include <machine/cpu.h>
3849102Skarels 
3956517Sbostic #include <vm/vm.h>
4056517Sbostic #include <sys/user.h>		/* for coredump */
4137581Smckusick 
4268310Scgd void stop __P((struct proc *p));
4368310Scgd 
4417013Smckusick /*
4564406Sbostic  * Can process p, with pcred pc, send the signal signum to process q?
4617013Smckusick  */
4764406Sbostic #define CANSIGNAL(p, pc, q, signum) \
4847540Skarels 	((pc)->pc_ucred->cr_uid == 0 || \
4947540Skarels 	    (pc)->p_ruid == (q)->p_cred->p_ruid || \
5047540Skarels 	    (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
5147540Skarels 	    (pc)->p_ruid == (q)->p_ucred->cr_uid || \
5247540Skarels 	    (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
5364406Sbostic 	    ((signum) == SIGCONT && (q)->p_session == (p)->p_session))
5439513Skarels 
5542920Skarels /* ARGSUSED */
5668310Scgd int
sigaction(p,uap,retval)5742920Skarels sigaction(p, uap, retval)
5842920Skarels 	struct proc *p;
5968310Scgd 	register struct sigaction_args /* {
6068310Scgd 		syscallarg(int) signum;
6168310Scgd 		syscallarg(struct sigaction *) nsa;
6268310Scgd 		syscallarg(struct sigaction *) osa;
6368310Scgd 	} */ *uap;
6468310Scgd 	register_t *retval;
6542920Skarels {
6639513Skarels 	struct sigaction vec;
6739513Skarels 	register struct sigaction *sa;
6847540Skarels 	register struct sigacts *ps = p->p_sigacts;
6964406Sbostic 	register int signum;
7039513Skarels 	int bit, error;
717421Sroot 
7268310Scgd 	signum = SCARG(uap, signum);
7364406Sbostic 	if (signum <= 0 || signum >= NSIG ||
7464406Sbostic 	    signum == SIGKILL || signum == SIGSTOP)
7544405Skarels 		return (EINVAL);
7639513Skarels 	sa = &vec;
7768310Scgd 	if (SCARG(uap, osa)) {
7864406Sbostic 		sa->sa_handler = ps->ps_sigact[signum];
7964406Sbostic 		sa->sa_mask = ps->ps_catchmask[signum];
8064406Sbostic 		bit = sigmask(signum);
8139513Skarels 		sa->sa_flags = 0;
8247540Skarels 		if ((ps->ps_sigonstack & bit) != 0)
8339513Skarels 			sa->sa_flags |= SA_ONSTACK;
8447540Skarels 		if ((ps->ps_sigintr & bit) == 0)
8539513Skarels 			sa->sa_flags |= SA_RESTART;
8664594Sbostic 		if (p->p_flag & P_NOCLDSTOP)
8739513Skarels 			sa->sa_flags |= SA_NOCLDSTOP;
8868310Scgd 		if (error = copyout((caddr_t)sa, (caddr_t)SCARG(uap, osa),
8939513Skarels 		    sizeof (vec)))
9044405Skarels 			return (error);
9112951Ssam 	}
9268310Scgd 	if (SCARG(uap, nsa)) {
9368310Scgd 		if (error = copyin((caddr_t)SCARG(uap, nsa), (caddr_t)sa,
9439513Skarels 		    sizeof (vec)))
9544405Skarels 			return (error);
9664406Sbostic 		setsigvec(p, signum, sa);
9712951Ssam 	}
9844405Skarels 	return (0);
997421Sroot }
1007421Sroot 
10168310Scgd void
setsigvec(p,signum,sa)10264406Sbostic setsigvec(p, signum, sa)
10342920Skarels 	register struct proc *p;
10464406Sbostic 	int signum;
10539513Skarels 	register struct sigaction *sa;
10612882Ssam {
10747540Skarels 	register struct sigacts *ps = p->p_sigacts;
10812951Ssam 	register int bit;
10912882Ssam 
11064406Sbostic 	bit = sigmask(signum);
11112882Ssam 	/*
11212882Ssam 	 * Change setting atomically.
11312882Ssam 	 */
11417153Sbloom 	(void) splhigh();
11564406Sbostic 	ps->ps_sigact[signum] = sa->sa_handler;
11664406Sbostic 	ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
11739513Skarels 	if ((sa->sa_flags & SA_RESTART) == 0)
11847540Skarels 		ps->ps_sigintr |= bit;
11918308Smckusick 	else
12047540Skarels 		ps->ps_sigintr &= ~bit;
12139513Skarels 	if (sa->sa_flags & SA_ONSTACK)
12247540Skarels 		ps->ps_sigonstack |= bit;
12312951Ssam 	else
12447540Skarels 		ps->ps_sigonstack &= ~bit;
12552400Storek #ifdef COMPAT_SUNOS
12652400Storek 	if (sa->sa_flags & SA_USERTRAMP)
12752400Storek 		ps->ps_usertramp |= bit;
12852400Storek 	else
12952400Storek 		ps->ps_usertramp &= ~bit;
13052400Storek #endif
13164406Sbostic 	if (signum == SIGCHLD) {
13239513Skarels 		if (sa->sa_flags & SA_NOCLDSTOP)
13364594Sbostic 			p->p_flag |= P_NOCLDSTOP;
13439513Skarels 		else
13564594Sbostic 			p->p_flag &= ~P_NOCLDSTOP;
13639513Skarels 	}
13739513Skarels 	/*
13839513Skarels 	 * Set bit in p_sigignore for signals that are set to SIG_IGN,
13939513Skarels 	 * and for signals set to SIG_DFL where the default is to ignore.
14039513Skarels 	 * However, don't put SIGCONT in p_sigignore,
14139513Skarels 	 * as we have to restart the process.
14239513Skarels 	 */
14339513Skarels 	if (sa->sa_handler == SIG_IGN ||
14464406Sbostic 	    (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
14564594Sbostic 		p->p_siglist &= ~bit;		/* never to be seen again */
14664406Sbostic 		if (signum != SIGCONT)
14739513Skarels 			p->p_sigignore |= bit;	/* easier in psignal */
14812951Ssam 		p->p_sigcatch &= ~bit;
14912882Ssam 	} else {
15012951Ssam 		p->p_sigignore &= ~bit;
15139513Skarels 		if (sa->sa_handler == SIG_DFL)
15212951Ssam 			p->p_sigcatch &= ~bit;
15312882Ssam 		else
15412951Ssam 			p->p_sigcatch |= bit;
15512882Ssam 	}
15612882Ssam 	(void) spl0();
15712882Ssam }
15812882Ssam 
15939513Skarels /*
16039513Skarels  * Initialize signal state for process 0;
16139513Skarels  * set to ignore signals that are ignored by default.
16239513Skarels  */
16347540Skarels void
siginit(p)16439513Skarels siginit(p)
16539513Skarels 	struct proc *p;
1667421Sroot {
16747540Skarels 	register int i;
16839513Skarels 
16947540Skarels 	for (i = 0; i < NSIG; i++)
17047540Skarels 		if (sigprop[i] & SA_IGNORE && i != SIGCONT)
17147540Skarels 			p->p_sigignore |= sigmask(i);
17239513Skarels }
17339513Skarels 
17439513Skarels /*
17539513Skarels  * Reset signals for an exec of the specified process.
17639513Skarels  */
17747540Skarels void
execsigs(p)17839513Skarels execsigs(p)
17939513Skarels 	register struct proc *p;
18039513Skarels {
18147540Skarels 	register struct sigacts *ps = p->p_sigacts;
18239513Skarels 	register int nc, mask;
18339513Skarels 
18439513Skarels 	/*
18539513Skarels 	 * Reset caught signals.  Held signals remain held
18639513Skarels 	 * through p_sigmask (unless they were caught,
18739513Skarels 	 * and are now ignored by default).
18839513Skarels 	 */
18939513Skarels 	while (p->p_sigcatch) {
19039513Skarels 		nc = ffs((long)p->p_sigcatch);
19139513Skarels 		mask = sigmask(nc);
19239513Skarels 		p->p_sigcatch &= ~mask;
19347540Skarels 		if (sigprop[nc] & SA_IGNORE) {
19439513Skarels 			if (nc != SIGCONT)
19539513Skarels 				p->p_sigignore |= mask;
19664594Sbostic 			p->p_siglist &= ~mask;
19739513Skarels 		}
19847540Skarels 		ps->ps_sigact[nc] = SIG_DFL;
19939513Skarels 	}
20039513Skarels 	/*
20139513Skarels 	 * Reset stack state to the user stack.
20239513Skarels 	 * Clear set of signals caught on the signal stack.
20339513Skarels 	 */
20453218Smckusick 	ps->ps_sigstk.ss_flags = SA_DISABLE;
20553218Smckusick 	ps->ps_sigstk.ss_size = 0;
20653218Smckusick 	ps->ps_sigstk.ss_base = 0;
20753218Smckusick 	ps->ps_flags = 0;
20839513Skarels }
20939513Skarels 
21039513Skarels /*
21139513Skarels  * Manipulate signal mask.
21239513Skarels  * Note that we receive new mask, not pointer,
21339513Skarels  * and return old mask as return value;
21439513Skarels  * the library stub does the rest.
21539513Skarels  */
21668310Scgd int
sigprocmask(p,uap,retval)21742920Skarels sigprocmask(p, uap, retval)
21842920Skarels 	register struct proc *p;
21968310Scgd 	struct sigprocmask_args /* {
22068310Scgd 		syscallarg(int) how;
22168310Scgd 		syscallarg(sigset_t) mask;
22268310Scgd 	} */ *uap;
22368310Scgd 	register_t *retval;
22442920Skarels {
22539513Skarels 	int error = 0;
22639513Skarels 
22742920Skarels 	*retval = p->p_sigmask;
22839513Skarels 	(void) splhigh();
22939513Skarels 
23068310Scgd 	switch (SCARG(uap, how)) {
23139513Skarels 	case SIG_BLOCK:
23268310Scgd 		p->p_sigmask |= SCARG(uap, mask) &~ sigcantmask;
23339513Skarels 		break;
23439513Skarels 
23539513Skarels 	case SIG_UNBLOCK:
23668310Scgd 		p->p_sigmask &= ~SCARG(uap, mask);
23739513Skarels 		break;
23839513Skarels 
23939513Skarels 	case SIG_SETMASK:
24068310Scgd 		p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
24139513Skarels 		break;
24239513Skarels 
24339513Skarels 	default:
24439513Skarels 		error = EINVAL;
24539513Skarels 		break;
24639513Skarels 	}
24739513Skarels 	(void) spl0();
24844405Skarels 	return (error);
24939513Skarels }
25039513Skarels 
25142920Skarels /* ARGSUSED */
25268310Scgd int
sigpending(p,uap,retval)25342920Skarels sigpending(p, uap, retval)
25442920Skarels 	struct proc *p;
25568310Scgd 	void *uap;
25668310Scgd 	register_t *retval;
25739513Skarels {
25839513Skarels 
25964594Sbostic 	*retval = p->p_siglist;
26044405Skarels 	return (0);
26139513Skarels }
26239513Skarels 
26352400Storek #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
26439513Skarels /*
26539513Skarels  * Generalized interface signal handler, 4.3-compatible.
26639513Skarels  */
26742920Skarels /* ARGSUSED */
26868310Scgd int
compat_43_sigvec(p,uap,retval)26968310Scgd compat_43_sigvec(p, uap, retval)
27042920Skarels 	struct proc *p;
27168310Scgd 	register struct compat_43_sigvec_args /* {
27268310Scgd 		syscallarg(int) signum;
27368310Scgd 		syscallarg(struct sigvec *) nsv;
27468310Scgd 		syscallarg(struct sigvec *) osv;
27568310Scgd 	} */ *uap;
27668310Scgd 	register_t *retval;
27742920Skarels {
27839513Skarels 	struct sigvec vec;
27947540Skarels 	register struct sigacts *ps = p->p_sigacts;
28039513Skarels 	register struct sigvec *sv;
28164406Sbostic 	register int signum;
28239513Skarels 	int bit, error;
28339513Skarels 
28468310Scgd 	signum = SCARG(uap, signum);
28564406Sbostic 	if (signum <= 0 || signum >= NSIG ||
28664406Sbostic 	    signum == SIGKILL || signum == SIGSTOP)
28744405Skarels 		return (EINVAL);
28839513Skarels 	sv = &vec;
28968310Scgd 	if (SCARG(uap, osv)) {
29064406Sbostic 		*(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
29164406Sbostic 		sv->sv_mask = ps->ps_catchmask[signum];
29264406Sbostic 		bit = sigmask(signum);
29339513Skarels 		sv->sv_flags = 0;
29447540Skarels 		if ((ps->ps_sigonstack & bit) != 0)
29539513Skarels 			sv->sv_flags |= SV_ONSTACK;
29647540Skarels 		if ((ps->ps_sigintr & bit) != 0)
29739513Skarels 			sv->sv_flags |= SV_INTERRUPT;
29852400Storek #ifndef COMPAT_SUNOS
29964594Sbostic 		if (p->p_flag & P_NOCLDSTOP)
30039513Skarels 			sv->sv_flags |= SA_NOCLDSTOP;
30152400Storek #endif
30268310Scgd 		if (error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv),
30339513Skarels 		    sizeof (vec)))
30444405Skarels 			return (error);
30539513Skarels 	}
30668310Scgd 	if (SCARG(uap, nsv)) {
30768310Scgd 		if (error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv,
30839513Skarels 		    sizeof (vec)))
30944405Skarels 			return (error);
31052400Storek #ifdef COMPAT_SUNOS
31152400Storek 		/*
31254344Smckusick 		 * SunOS uses this bit (4, aka SA_DISABLE) as SV_RESETHAND,
31354344Smckusick 		 * `reset to SIG_DFL on delivery'. We have no such option
31454344Smckusick 		 * now or ever!
31552400Storek 		 */
31654344Smckusick 		if (sv->sv_flags & SA_DISABLE)
31752400Storek 			return (EINVAL);
31852400Storek 		sv->sv_flags |= SA_USERTRAMP;
31952400Storek #endif
32039513Skarels 		sv->sv_flags ^= SA_RESTART;	/* opposite of SV_INTERRUPT */
32164406Sbostic 		setsigvec(p, signum, (struct sigaction *)sv);
32239513Skarels 	}
32344405Skarels 	return (0);
32439513Skarels }
32539513Skarels 
32668310Scgd int
compat_43_sigblock(p,uap,retval)32768310Scgd compat_43_sigblock(p, uap, retval)
32842920Skarels 	register struct proc *p;
32968310Scgd 	struct compat_43_sigblock_args /* {
33068310Scgd 		syscallarg(int) mask;
33168310Scgd 	} */ *uap;
33268310Scgd 	register_t *retval;
33339513Skarels {
3347499Sroot 
33517153Sbloom 	(void) splhigh();
33642920Skarels 	*retval = p->p_sigmask;
33768310Scgd 	p->p_sigmask |= SCARG(uap, mask) &~ sigcantmask;
33812882Ssam 	(void) spl0();
33944405Skarels 	return (0);
3407499Sroot }
3417499Sroot 
34268310Scgd int
compat_43_sigsetmask(p,uap,retval)34368310Scgd compat_43_sigsetmask(p, uap, retval)
34442920Skarels 	struct proc *p;
34568310Scgd 	struct compat_43_sigsetmask_args /* {
34668310Scgd 		syscallarg(int) mask;
34768310Scgd 	} */ *uap;
34868310Scgd 	register_t *retval;
3497499Sroot {
3507499Sroot 
35117153Sbloom 	(void) splhigh();
35242920Skarels 	*retval = p->p_sigmask;
35368310Scgd 	p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
35412882Ssam 	(void) spl0();
35544405Skarels 	return (0);
3567499Sroot }
35754344Smckusick #endif /* COMPAT_43 || COMPAT_SUNOS */
3587499Sroot 
35939513Skarels /*
36039513Skarels  * Suspend process until signal, providing mask to be set
36139513Skarels  * in the meantime.  Note nonstandard calling convention:
36239513Skarels  * libc stub passes mask, not pointer, to save a copyin.
36339513Skarels  */
36442920Skarels /* ARGSUSED */
36568310Scgd int
sigsuspend(p,uap,retval)36642920Skarels sigsuspend(p, uap, retval)
36742920Skarels 	register struct proc *p;
36868310Scgd 	struct sigsuspend_args /* {
36968310Scgd 		syscallarg(int) mask;
37068310Scgd 	} */ *uap;
37168310Scgd 	register_t *retval;
3727499Sroot {
37347540Skarels 	register struct sigacts *ps = p->p_sigacts;
3747499Sroot 
37512882Ssam 	/*
37612882Ssam 	 * When returning from sigpause, we want
37712882Ssam 	 * the old mask to be restored after the
37812882Ssam 	 * signal handler has finished.  Thus, we
37952115Skarels 	 * save it here and mark the sigacts structure
38052115Skarels 	 * to indicate this.
38112882Ssam 	 */
38247540Skarels 	ps->ps_oldmask = p->p_sigmask;
38353218Smckusick 	ps->ps_flags |= SAS_OLDMASK;
38468310Scgd 	p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
38558230Smckusick 	while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
38658230Smckusick 		/* void */;
38740807Smarc 	/* always return EINTR rather than ERESTART... */
38844405Skarels 	return (EINTR);
3897499Sroot }
3907499Sroot 
39154344Smckusick #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
39242920Skarels /* ARGSUSED */
39368310Scgd int
compat_43_sigstack(p,uap,retval)39468310Scgd compat_43_sigstack(p, uap, retval)
39542920Skarels 	struct proc *p;
39668310Scgd 	register struct compat_43_sigstack_args /* {
39768310Scgd 		syscallarg(struct sigstack *) nss;
39868310Scgd 		syscallarg(struct sigstack *) oss;
39968310Scgd 	} */ *uap;
40068310Scgd 	register_t *retval;
40142920Skarels {
40212951Ssam 	struct sigstack ss;
40353218Smckusick 	struct sigacts *psp;
40439513Skarels 	int error = 0;
4057499Sroot 
40653218Smckusick 	psp = p->p_sigacts;
40753218Smckusick 	ss.ss_sp = psp->ps_sigstk.ss_base;
40853218Smckusick 	ss.ss_onstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
40968310Scgd 	if (SCARG(uap, oss) && (error = copyout((caddr_t)&ss,
41068310Scgd 	    (caddr_t)SCARG(uap, oss), sizeof (struct sigstack))))
41144405Skarels 		return (error);
41268310Scgd 	if (SCARG(uap, nss) && (error = copyin((caddr_t)SCARG(uap, nss),
41368310Scgd 	    (caddr_t)&ss, sizeof (ss))) == 0) {
41453218Smckusick 		psp->ps_sigstk.ss_base = ss.ss_sp;
41553218Smckusick 		psp->ps_sigstk.ss_size = 0;
41653218Smckusick 		psp->ps_sigstk.ss_flags |= ss.ss_onstack & SA_ONSTACK;
41753218Smckusick 		psp->ps_flags |= SAS_ALTSTACK;
41853218Smckusick 	}
41944405Skarels 	return (error);
4207499Sroot }
42154344Smckusick #endif /* COMPAT_43 || COMPAT_SUNOS */
4227499Sroot 
42342920Skarels /* ARGSUSED */
42468310Scgd int
sigaltstack(p,uap,retval)42553218Smckusick sigaltstack(p, uap, retval)
42653218Smckusick 	struct proc *p;
42768310Scgd 	register struct sigaltstack_args /* {
42868310Scgd 		syscallarg(struct sigaltstack *) nss;
42968310Scgd 		syscallarg(struct sigaltstack *) oss;
43068310Scgd 	} */ *uap;
43168310Scgd 	register_t *retval;
43253218Smckusick {
43353218Smckusick 	struct sigacts *psp;
43453218Smckusick 	struct sigaltstack ss;
43553218Smckusick 	int error;
43653218Smckusick 
43753218Smckusick 	psp = p->p_sigacts;
43853218Smckusick 	if ((psp->ps_flags & SAS_ALTSTACK) == 0)
43953218Smckusick 		psp->ps_sigstk.ss_flags |= SA_DISABLE;
44068310Scgd 	if (SCARG(uap, oss) && (error = copyout((caddr_t)&psp->ps_sigstk,
44168310Scgd 	    (caddr_t)SCARG(uap, oss), sizeof (struct sigaltstack))))
44253218Smckusick 		return (error);
44368310Scgd 	if (SCARG(uap, nss) == 0)
44454464Smckusick 		return (0);
44568310Scgd 	if (error = copyin((caddr_t)SCARG(uap, nss), (caddr_t)&ss,
44668310Scgd 	    sizeof (ss)))
44753218Smckusick 		return (error);
44853218Smckusick 	if (ss.ss_flags & SA_DISABLE) {
44953218Smckusick 		if (psp->ps_sigstk.ss_flags & SA_ONSTACK)
45053218Smckusick 			return (EINVAL);
45153218Smckusick 		psp->ps_flags &= ~SAS_ALTSTACK;
45253218Smckusick 		psp->ps_sigstk.ss_flags = ss.ss_flags;
45353218Smckusick 		return (0);
45453218Smckusick 	}
45553218Smckusick 	if (ss.ss_size < MINSIGSTKSZ)
45653218Smckusick 		return (ENOMEM);
45753218Smckusick 	psp->ps_flags |= SAS_ALTSTACK;
45853218Smckusick 	psp->ps_sigstk= ss;
45953218Smckusick 	return (0);
46053218Smckusick }
46153218Smckusick 
46253218Smckusick /* ARGSUSED */
46368310Scgd int
kill(cp,uap,retval)46442920Skarels kill(cp, uap, retval)
46542920Skarels 	register struct proc *cp;
46668310Scgd 	register struct kill_args /* {
46768310Scgd 		syscallarg(int) pid;
46868310Scgd 		syscallarg(int) signum;
46968310Scgd 	} */ *uap;
47068310Scgd 	register_t *retval;
47142920Skarels {
47218336Smckusick 	register struct proc *p;
47347540Skarels 	register struct pcred *pc = cp->p_cred;
4748032Sroot 
47568310Scgd 	if ((u_int)SCARG(uap, signum) >= NSIG)
47644405Skarels 		return (EINVAL);
47768310Scgd 	if (SCARG(uap, pid) > 0) {
47818336Smckusick 		/* kill single process */
47968310Scgd 		if ((p = pfind(SCARG(uap, pid))) == NULL)
48044405Skarels 			return (ESRCH);
48168310Scgd 		if (!CANSIGNAL(cp, pc, p, SCARG(uap, signum)))
48244405Skarels 			return (EPERM);
48368310Scgd 		if (SCARG(uap, signum))
48468310Scgd 			psignal(p, SCARG(uap, signum));
48544405Skarels 		return (0);
48618336Smckusick 	}
48768310Scgd 	switch (SCARG(uap, pid)) {
48818336Smckusick 	case -1:		/* broadcast signal */
48968310Scgd 		return (killpg1(cp, SCARG(uap, signum), 0, 1));
49018336Smckusick 	case 0:			/* signal own process group */
49168310Scgd 		return (killpg1(cp, SCARG(uap, signum), 0, 0));
49218336Smckusick 	default:		/* negative explicit process group */
49368310Scgd 		return (killpg1(cp, SCARG(uap, signum), -SCARG(uap, pid), 0));
49418336Smckusick 	}
49539513Skarels 	/* NOTREACHED */
4968032Sroot }
4978032Sroot 
49852400Storek #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
49942920Skarels /* ARGSUSED */
50068310Scgd int
compat_43_killpg(p,uap,retval)50168310Scgd compat_43_killpg(p, uap, retval)
50242920Skarels 	struct proc *p;
50368310Scgd 	register struct compat_43_killpg_args /* {
50468310Scgd 		syscallarg(int) pgid;
50568310Scgd 		syscallarg(int) signum;
50668310Scgd 	} */ *uap;
50768310Scgd 	register_t *retval;
50842920Skarels {
5098032Sroot 
51068310Scgd 	if ((u_int)SCARG(uap, signum) >= NSIG)
51144405Skarels 		return (EINVAL);
51268310Scgd 	return (killpg1(p, SCARG(uap, signum), SCARG(uap, pgid), 0));
5138032Sroot }
51454344Smckusick #endif /* COMPAT_43 || COMPAT_SUNOS */
5158032Sroot 
51642920Skarels /*
51742920Skarels  * Common code for kill process group/broadcast kill.
51842920Skarels  * cp is calling process.
51942920Skarels  */
52068310Scgd int
killpg1(cp,signum,pgid,all)52164406Sbostic killpg1(cp, signum, pgid, all)
52242920Skarels 	register struct proc *cp;
52364406Sbostic 	int signum, pgid, all;
5249989Ssam {
5259989Ssam 	register struct proc *p;
52647540Skarels 	register struct pcred *pc = cp->p_cred;
52737581Smckusick 	struct pgrp *pgrp;
52847540Skarels 	int nfound = 0;
52937581Smckusick 
53037581Smckusick 	if (all)
53137581Smckusick 		/*
53237581Smckusick 		 * broadcast
5337421Sroot 		 */
53467732Smckusick 		for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
53564594Sbostic 			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
53664406Sbostic 			    p == cp || !CANSIGNAL(cp, pc, p, signum))
53737581Smckusick 				continue;
53847540Skarels 			nfound++;
53964406Sbostic 			if (signum)
54064406Sbostic 				psignal(p, signum);
54137581Smckusick 		}
54237581Smckusick 	else {
54337581Smckusick 		if (pgid == 0)
54437581Smckusick 			/*
54537581Smckusick 			 * zero pgid means send to my process group.
54637581Smckusick 			 */
54747540Skarels 			pgrp = cp->p_pgrp;
54837581Smckusick 		else {
54937581Smckusick 			pgrp = pgfind(pgid);
55037581Smckusick 			if (pgrp == NULL)
55139513Skarels 				return (ESRCH);
55237581Smckusick 		}
55367732Smckusick 		for (p = pgrp->pg_members.lh_first; p != 0;
55467732Smckusick 		     p = p->p_pglist.le_next) {
55564594Sbostic 			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
55664406Sbostic 			    p->p_stat == SZOMB ||
55764406Sbostic 			    !CANSIGNAL(cp, pc, p, signum))
55837581Smckusick 				continue;
55947540Skarels 			nfound++;
56064406Sbostic 			if (signum)
56164406Sbostic 				psignal(p, signum);
56218336Smckusick 		}
5637421Sroot 	}
56447540Skarels 	return (nfound ? 0 : ESRCH);
5657421Sroot }
5667421Sroot 
56742920Skarels /*
56864406Sbostic  * Send a signal to a process group.
5697421Sroot  */
57047540Skarels void
gsignal(pgid,signum)57164406Sbostic gsignal(pgid, signum)
57264406Sbostic 	int pgid, signum;
5737421Sroot {
57439513Skarels 	struct pgrp *pgrp;
5757421Sroot 
57639513Skarels 	if (pgid && (pgrp = pgfind(pgid)))
57764406Sbostic 		pgsignal(pgrp, signum, 0);
5787421Sroot }
57942920Skarels 
58040807Smarc /*
58168310Scgd  * Send a signal to a process group.  If checktty is 1,
58264406Sbostic  * limit to members which have a controlling terminal.
58340807Smarc  */
58447540Skarels void
pgsignal(pgrp,signum,checkctty)58564406Sbostic pgsignal(pgrp, signum, checkctty)
58639513Skarels 	struct pgrp *pgrp;
58764406Sbostic 	int signum, checkctty;
58837581Smckusick {
58937581Smckusick 	register struct proc *p;
59037581Smckusick 
59140807Smarc 	if (pgrp)
59267732Smckusick 		for (p = pgrp->pg_members.lh_first; p != 0;
59367732Smckusick 		     p = p->p_pglist.le_next)
59464594Sbostic 			if (checkctty == 0 || p->p_flag & P_CONTROLT)
59564406Sbostic 				psignal(p, signum);
59637581Smckusick }
59737581Smckusick 
5987421Sroot /*
59939513Skarels  * Send a signal caused by a trap to the current process.
60039513Skarels  * If it will be caught immediately, deliver it with correct code.
60139513Skarels  * Otherwise, post it normally.
60239513Skarels  */
60347540Skarels void
trapsignal(p,signum,code)60464406Sbostic trapsignal(p, signum, code)
60547540Skarels 	struct proc *p;
60664406Sbostic 	register int signum;
60768171Scgd 	u_long code;
60839513Skarels {
60947540Skarels 	register struct sigacts *ps = p->p_sigacts;
61039513Skarels 	int mask;
61139513Skarels 
61264406Sbostic 	mask = sigmask(signum);
61364594Sbostic 	if ((p->p_flag & P_TRACED) == 0 && (p->p_sigcatch & mask) != 0 &&
61439513Skarels 	    (p->p_sigmask & mask) == 0) {
61547540Skarels 		p->p_stats->p_ru.ru_nsignals++;
61640807Smarc #ifdef KTRACE
61740807Smarc 		if (KTRPOINT(p, KTR_PSIG))
61864406Sbostic 			ktrpsig(p->p_tracep, signum, ps->ps_sigact[signum],
61940807Smarc 				p->p_sigmask, code);
62040807Smarc #endif
62164406Sbostic 		sendsig(ps->ps_sigact[signum], signum, p->p_sigmask, code);
62264406Sbostic 		p->p_sigmask |= ps->ps_catchmask[signum] | mask;
62339513Skarels 	} else {
62447540Skarels 		ps->ps_code = code;	/* XXX for core dump/debugger */
62567183Shibler 		ps->ps_sig = signum;	/* XXX to verify code */
62664406Sbostic 		psignal(p, signum);
62739513Skarels 	}
62839513Skarels }
62939513Skarels 
63039513Skarels /*
63164406Sbostic  * Send the signal to the process.  If the signal has an action, the action
63264406Sbostic  * is usually performed by the target process rather than the caller; we add
63347540Skarels  * the signal to the set of pending signals for the process.
63464406Sbostic  *
63540807Smarc  * Exceptions:
63664406Sbostic  *   o When a stop signal is sent to a sleeping process that takes the
63764406Sbostic  *     default action, the process is stopped without awakening it.
63840807Smarc  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
63940807Smarc  *     regardless of the signal action (eg, blocked or ignored).
64064406Sbostic  *
64140807Smarc  * Other ignored signals are discarded immediately.
6427421Sroot  */
64347540Skarels void
psignal(p,signum)64464406Sbostic psignal(p, signum)
6457421Sroot 	register struct proc *p;
64664406Sbostic 	register int signum;
6477421Sroot {
64847540Skarels 	register int s, prop;
64939513Skarels 	register sig_t action;
65017153Sbloom 	int mask;
6517421Sroot 
65264406Sbostic 	if ((u_int)signum >= NSIG || signum == 0)
65364406Sbostic 		panic("psignal signal number");
65464406Sbostic 	mask = sigmask(signum);
65564406Sbostic 	prop = sigprop[signum];
6567421Sroot 
6577421Sroot 	/*
6587421Sroot 	 * If proc is traced, always give parent a chance.
6597421Sroot 	 */
66064594Sbostic 	if (p->p_flag & P_TRACED)
6617421Sroot 		action = SIG_DFL;
6627421Sroot 	else {
6637421Sroot 		/*
66412882Ssam 		 * If the signal is being ignored,
66512882Ssam 		 * then we forget about it immediately.
66639513Skarels 		 * (Note: we don't set SIGCONT in p_sigignore,
66739513Skarels 		 * and if it is set to SIG_IGN,
66839513Skarels 		 * action will be SIG_DFL here.)
6697421Sroot 		 */
67017153Sbloom 		if (p->p_sigignore & mask)
6717421Sroot 			return;
67217153Sbloom 		if (p->p_sigmask & mask)
67312882Ssam 			action = SIG_HOLD;
67417153Sbloom 		else if (p->p_sigcatch & mask)
67512882Ssam 			action = SIG_CATCH;
67642437Skarels 		else
67712882Ssam 			action = SIG_DFL;
6787421Sroot 	}
6797421Sroot 
68058371Smckusick 	if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) &&
68164594Sbostic 	    (p->p_flag & P_TRACED) == 0)
68247540Skarels 		p->p_nice = NZERO;
6837421Sroot 
68447540Skarels 	if (prop & SA_CONT)
68564594Sbostic 		p->p_siglist &= ~stopsigmask;
68639513Skarels 
68747540Skarels 	if (prop & SA_STOP) {
68845672Skarels 		/*
68945672Skarels 		 * If sending a tty stop signal to a member of an orphaned
69045672Skarels 		 * process group, discard the signal here if the action
69145672Skarels 		 * is default; don't stop the process below if sleeping,
69245672Skarels 		 * and don't clear any pending SIGCONT.
69345672Skarels 		 */
69447540Skarels 		if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
69547540Skarels 		    action == SIG_DFL)
69668310Scgd 			return;
69764594Sbostic 		p->p_siglist &= ~contsigmask;
6987421Sroot 	}
69964594Sbostic 	p->p_siglist |= mask;
70039513Skarels 
7017421Sroot 	/*
70239513Skarels 	 * Defer further processing for signals which are held,
70339513Skarels 	 * except that stopped processes must be continued by SIGCONT.
7047421Sroot 	 */
70547540Skarels 	if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
7067421Sroot 		return;
70717153Sbloom 	s = splhigh();
7087421Sroot 	switch (p->p_stat) {
7097421Sroot 
7107421Sroot 	case SSLEEP:
7117421Sroot 		/*
71240807Smarc 		 * If process is sleeping uninterruptibly
7137421Sroot 		 * we can't interrupt the sleep... the signal will
7147421Sroot 		 * be noticed when the process returns through
7157421Sroot 		 * trap() or syscall().
7167421Sroot 		 */
71764594Sbostic 		if ((p->p_flag & P_SINTR) == 0)
7187421Sroot 			goto out;
7197421Sroot 		/*
7207421Sroot 		 * Process is sleeping and traced... make it runnable
72164594Sbostic 		 * so it can discover the signal in issignal() and stop
7227421Sroot 		 * for the parent.
7237421Sroot 		 */
72464594Sbostic 		if (p->p_flag & P_TRACED)
7257421Sroot 			goto run;
72639513Skarels 		/*
72758371Smckusick 		 * If SIGCONT is default (or ignored) and process is
72858371Smckusick 		 * asleep, we are finished; the process should not
72958371Smckusick 		 * be awakened.
73058371Smckusick 		 */
73158371Smckusick 		if ((prop & SA_CONT) && action == SIG_DFL) {
73264594Sbostic 			p->p_siglist &= ~mask;
73358371Smckusick 			goto out;
73458371Smckusick 		}
73558371Smckusick 		/*
73639513Skarels 		 * When a sleeping process receives a stop
73739513Skarels 		 * signal, process immediately if possible.
73839513Skarels 		 * All other (caught or default) signals
73939513Skarels 		 * cause the process to run.
74039513Skarels 		 */
74147540Skarels 		if (prop & SA_STOP) {
7427421Sroot 			if (action != SIG_DFL)
74339513Skarels 				goto runfast;
7447421Sroot 			/*
74547540Skarels 			 * If a child holding parent blocked,
74647540Skarels 			 * stopping could cause deadlock.
7477421Sroot 			 */
74864594Sbostic 			if (p->p_flag & P_PPWAIT)
7497421Sroot 				goto out;
75064594Sbostic 			p->p_siglist &= ~mask;
75164406Sbostic 			p->p_xstat = signum;
75264594Sbostic 			if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
75339513Skarels 				psignal(p->p_pptr, SIGCHLD);
7547421Sroot 			stop(p);
7557421Sroot 			goto out;
75639513Skarels 		} else
75739513Skarels 			goto runfast;
7587421Sroot 		/*NOTREACHED*/
7597421Sroot 
7607421Sroot 	case SSTOP:
7617421Sroot 		/*
7627421Sroot 		 * If traced process is already stopped,
7637421Sroot 		 * then no further action is necessary.
7647421Sroot 		 */
76564594Sbostic 		if (p->p_flag & P_TRACED)
7667421Sroot 			goto out;
7677421Sroot 
76847540Skarels 		/*
76947540Skarels 		 * Kill signal always sets processes running.
77047540Skarels 		 */
77164406Sbostic 		if (signum == SIGKILL)
77239513Skarels 			goto runfast;
7737421Sroot 
77447540Skarels 		if (prop & SA_CONT) {
7757421Sroot 			/*
77664594Sbostic 			 * If SIGCONT is default (or ignored), we continue the
77764594Sbostic 			 * process but don't leave the signal in p_siglist, as
77864594Sbostic 			 * it has no further action.  If SIGCONT is held, we
77964594Sbostic 			 * continue the process and leave the signal in
78064594Sbostic 			 * p_siglist.  If the process catches SIGCONT, let it
78164594Sbostic 			 * handle the signal itself.  If it isn't waiting on
7827421Sroot 			 * an event, then it goes back to run state.
7837421Sroot 			 * Otherwise, process goes back to sleep state.
7847421Sroot 			 */
78539513Skarels 			if (action == SIG_DFL)
78664594Sbostic 				p->p_siglist &= ~mask;
78739513Skarels 			if (action == SIG_CATCH)
78839513Skarels 				goto runfast;
78939513Skarels 			if (p->p_wchan == 0)
7907421Sroot 				goto run;
7917421Sroot 			p->p_stat = SSLEEP;
7927421Sroot 			goto out;
79347540Skarels 		}
7947421Sroot 
79547540Skarels 		if (prop & SA_STOP) {
7967421Sroot 			/*
7977421Sroot 			 * Already stopped, don't need to stop again.
7987421Sroot 			 * (If we did the shell could get confused.)
7997421Sroot 			 */
80064594Sbostic 			p->p_siglist &= ~mask;		/* take it away */
8017421Sroot 			goto out;
8027421Sroot 		}
8037421Sroot 
80447540Skarels 		/*
80564531Sbostic 		 * If process is sleeping interruptibly, then simulate a
80664531Sbostic 		 * wakeup so that when it is continued, it will be made
80764531Sbostic 		 * runnable and can look at the signal.  But don't make
80864531Sbostic 		 * the process runnable, leave it stopped.
80947540Skarels 		 */
81064594Sbostic 		if (p->p_wchan && p->p_flag & P_SINTR)
81147540Skarels 			unsleep(p);
81247540Skarels 		goto out;
81347540Skarels 
8147421Sroot 	default:
8157421Sroot 		/*
8167421Sroot 		 * SRUN, SIDL, SZOMB do nothing with the signal,
8177421Sroot 		 * other than kicking ourselves if we are running.
8187421Sroot 		 * It will either never be noticed, or noticed very soon.
8197421Sroot 		 */
82047650Skarels 		if (p == curproc)
82149102Skarels 			signotify(p);
8227421Sroot 		goto out;
8237421Sroot 	}
8247421Sroot 	/*NOTREACHED*/
82539513Skarels 
82639513Skarels runfast:
8277421Sroot 	/*
8287421Sroot 	 * Raise priority to at least PUSER.
8297421Sroot 	 */
83064594Sbostic 	if (p->p_priority > PUSER)
83164594Sbostic 		p->p_priority = PUSER;
83239513Skarels run:
83364531Sbostic 	setrunnable(p);
8347421Sroot out:
8357421Sroot 	splx(s);
8367421Sroot }
8377421Sroot 
8387421Sroot /*
83964406Sbostic  * If the current process has received a signal (should be caught or cause
84064406Sbostic  * termination, should interrupt current syscall), return the signal number.
84164406Sbostic  * Stop signals with default action are processed immediately, then cleared;
84264406Sbostic  * they aren't returned.  This is checked after each entry to the system for
84364594Sbostic  * a syscall or trap (though this can usually be done without calling issignal
84464406Sbostic  * by checking the pending signal masks in the CURSIG macro.) The normal call
84564406Sbostic  * sequence is
84647540Skarels  *
84764406Sbostic  *	while (signum = CURSIG(curproc))
84864594Sbostic  *		postsig(signum);
8497421Sroot  */
85068310Scgd int
issignal(p)85164594Sbostic issignal(p)
85247540Skarels 	register struct proc *p;
8537421Sroot {
85464406Sbostic 	register int signum, mask, prop;
8557421Sroot 
8567421Sroot 	for (;;) {
85764594Sbostic 		mask = p->p_siglist & ~p->p_sigmask;
85864594Sbostic 		if (p->p_flag & P_PPWAIT)
85939513Skarels 			mask &= ~stopsigmask;
86040807Smarc 		if (mask == 0)	 	/* no signal to send */
86140807Smarc 			return (0);
86264406Sbostic 		signum = ffs((long)mask);
86364406Sbostic 		mask = sigmask(signum);
86464406Sbostic 		prop = sigprop[signum];
86540807Smarc 		/*
86640807Smarc 		 * We should see pending but ignored signals
86764594Sbostic 		 * only if P_TRACED was on when they were posted.
86840807Smarc 		 */
86964594Sbostic 		if (mask & p->p_sigignore && (p->p_flag & P_TRACED) == 0) {
87064594Sbostic 			p->p_siglist &= ~mask;
87140807Smarc 			continue;
87240807Smarc 		}
87364594Sbostic 		if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
8747421Sroot 			/*
8757421Sroot 			 * If traced, always stop, and stay
8767421Sroot 			 * stopped until released by the parent.
87767183Shibler 			 *
87867183Shibler 			 * Note that we must clear the pending signal
87967183Shibler 			 * before we call trace_req since that routine
88067183Shibler 			 * might cause a fault, calling tsleep and
88167183Shibler 			 * leading us back here again with the same signal.
88267183Shibler 			 * Then we would be deadlocked because the tracer
88367183Shibler 			 * would still be blocked on the ipc struct from
88467183Shibler 			 * the initial request.
8857421Sroot 			 */
88664406Sbostic 			p->p_xstat = signum;
88767183Shibler 			p->p_siglist &= ~mask;
88818331Skarels 			psignal(p->p_pptr, SIGCHLD);
8897421Sroot 			do {
8907421Sroot 				stop(p);
89164594Sbostic 				mi_switch();
89264594Sbostic 			} while (!trace_req(p) && p->p_flag & P_TRACED);
8937421Sroot 
8947421Sroot 			/*
8957421Sroot 			 * If parent wants us to take the signal,
89643895Skarels 			 * then it will leave it in p->p_xstat;
8977421Sroot 			 * otherwise we just look for signals again.
8987421Sroot 			 */
89964406Sbostic 			signum = p->p_xstat;
90064406Sbostic 			if (signum == 0)
9017421Sroot 				continue;
90214782Ssam 
90314782Ssam 			/*
90464594Sbostic 			 * Put the new signal into p_siglist.  If the
90564594Sbostic 			 * signal is being masked, look for other signals.
90614782Ssam 			 */
90764406Sbostic 			mask = sigmask(signum);
90864594Sbostic 			p->p_siglist |= mask;
90940807Smarc 			if (p->p_sigmask & mask)
91014782Ssam 				continue;
91167183Shibler 
91267183Shibler 			/*
91367183Shibler 			 * If the traced bit got turned off, go back up
91467183Shibler 			 * to the top to rescan signals.  This ensures
91567183Shibler 			 * that p_sig* and ps_sigact are consistent.
91667183Shibler 			 */
91767183Shibler 			if ((p->p_flag & P_TRACED) == 0)
91867183Shibler 				continue;
9197421Sroot 		}
92040807Smarc 
92140807Smarc 		/*
92240807Smarc 		 * Decide whether the signal should be returned.
92340807Smarc 		 * Return the signal's number, or fall through
92440807Smarc 		 * to clear it from the pending mask.
92540807Smarc 		 */
92668310Scgd 		switch ((long)p->p_sigacts->ps_sigact[signum]) {
9277421Sroot 
92868310Scgd 		case (long)SIG_DFL:
9297421Sroot 			/*
9307421Sroot 			 * Don't take default actions on system processes.
9317421Sroot 			 */
93251019Sralph 			if (p->p_pid <= 1) {
93351019Sralph #ifdef DIAGNOSTIC
93451019Sralph 				/*
93551019Sralph 				 * Are you sure you want to ignore SIGSEGV
93651019Sralph 				 * in init? XXX
93751019Sralph 				 */
93851019Sralph 				printf("Process (pid %d) got signal %d\n",
93964406Sbostic 					p->p_pid, signum);
94051019Sralph #endif
94140807Smarc 				break;		/* == ignore */
94251019Sralph 			}
94340807Smarc 			/*
94440807Smarc 			 * If there is a pending stop signal to process
94540807Smarc 			 * with default action, stop here,
94642437Skarels 			 * then clear the signal.  However,
94742437Skarels 			 * if process is member of an orphaned
94842437Skarels 			 * process group, ignore tty stop signals.
94940807Smarc 			 */
95047540Skarels 			if (prop & SA_STOP) {
95164594Sbostic 				if (p->p_flag & P_TRACED ||
95242437Skarels 		    		    (p->p_pgrp->pg_jobc == 0 &&
95347540Skarels 				    prop & SA_TTYSTOP))
95440807Smarc 					break;	/* == ignore */
95564406Sbostic 				p->p_xstat = signum;
9567421Sroot 				stop(p);
95764594Sbostic 				if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
95839513Skarels 					psignal(p->p_pptr, SIGCHLD);
95964594Sbostic 				mi_switch();
96040807Smarc 				break;
96147540Skarels 			} else if (prop & SA_IGNORE) {
9627421Sroot 				/*
96339513Skarels 				 * Except for SIGCONT, shouldn't get here.
96439513Skarels 				 * Default action is to ignore; drop it.
9657421Sroot 				 */
96640807Smarc 				break;		/* == ignore */
96739513Skarels 			} else
96864406Sbostic 				return (signum);
9697421Sroot 			/*NOTREACHED*/
9707421Sroot 
97168310Scgd 		case (long)SIG_IGN:
9727421Sroot 			/*
97339513Skarels 			 * Masking above should prevent us ever trying
97439513Skarels 			 * to take action on an ignored signal other
97539513Skarels 			 * than SIGCONT, unless process is traced.
9767421Sroot 			 */
97764594Sbostic 			if ((prop & SA_CONT) == 0 &&
97864594Sbostic 			    (p->p_flag & P_TRACED) == 0)
97964594Sbostic 				printf("issignal\n");
98040807Smarc 			break;		/* == ignore */
9817421Sroot 
9827421Sroot 		default:
9837421Sroot 			/*
9847421Sroot 			 * This signal has an action, let
98564594Sbostic 			 * postsig() process it.
9867421Sroot 			 */
98764406Sbostic 			return (signum);
9887421Sroot 		}
98964594Sbostic 		p->p_siglist &= ~mask;		/* take the signal! */
9907421Sroot 	}
99140807Smarc 	/* NOTREACHED */
9927421Sroot }
9937421Sroot 
9947421Sroot /*
99564406Sbostic  * Put the argument process into the stopped state and notify the parent
99664406Sbostic  * via wakeup.  Signals are handled elsewhere.  The process must not be
99764406Sbostic  * on the run queue.
9987421Sroot  */
99968310Scgd void
stop(p)10007421Sroot stop(p)
10017421Sroot 	register struct proc *p;
10027421Sroot {
10037421Sroot 
10047421Sroot 	p->p_stat = SSTOP;
100564594Sbostic 	p->p_flag &= ~P_WAITED;
10067421Sroot 	wakeup((caddr_t)p->p_pptr);
10077421Sroot }
10087421Sroot 
10097421Sroot /*
101047540Skarels  * Take the action for the specified signal
101147540Skarels  * from the current set of pending signals.
10127421Sroot  */
101347540Skarels void
postsig(signum)101464594Sbostic postsig(signum)
101564406Sbostic 	register int signum;
10167421Sroot {
101747540Skarels 	register struct proc *p = curproc;
101847540Skarels 	register struct sigacts *ps = p->p_sigacts;
101947540Skarels 	register sig_t action;
102068310Scgd 	u_long code;
102168310Scgd 	int mask, returnmask;
10227421Sroot 
102340807Smarc #ifdef DIAGNOSTIC
102464406Sbostic 	if (signum == 0)
102564594Sbostic 		panic("postsig");
102640807Smarc #endif
102764406Sbostic 	mask = sigmask(signum);
102864594Sbostic 	p->p_siglist &= ~mask;
102964406Sbostic 	action = ps->ps_sigact[signum];
103040807Smarc #ifdef KTRACE
103147540Skarels 	if (KTRPOINT(p, KTR_PSIG))
103264406Sbostic 		ktrpsig(p->p_tracep,
103364406Sbostic 		    signum, action, ps->ps_flags & SAS_OLDMASK ?
103447540Skarels 		    ps->ps_oldmask : p->p_sigmask, 0);
103540807Smarc #endif
103647540Skarels 	if (action == SIG_DFL) {
103747540Skarels 		/*
103847540Skarels 		 * Default action, where the default is to kill
103947540Skarels 		 * the process.  (Other cases were ignored above.)
104047540Skarels 		 */
104164406Sbostic 		sigexit(p, signum);
104247540Skarels 		/* NOTREACHED */
104347540Skarels 	} else {
104447540Skarels 		/*
104547540Skarels 		 * If we get here, the signal must be caught.
104647540Skarels 		 */
104739513Skarels #ifdef DIAGNOSTIC
104847540Skarels 		if (action == SIG_IGN || (p->p_sigmask & mask))
104964594Sbostic 			panic("postsig action");
105039513Skarels #endif
105147540Skarels 		/*
105247540Skarels 		 * Set the new mask value and also defer further
105347540Skarels 		 * occurences of this signal.
105447540Skarels 		 *
105547540Skarels 		 * Special case: user has done a sigpause.  Here the
105647540Skarels 		 * current mask is not of interest, but rather the
105747540Skarels 		 * mask from before the sigpause is what we want
105847540Skarels 		 * restored after the signal processing is completed.
105947540Skarels 		 */
106047540Skarels 		(void) splhigh();
106153218Smckusick 		if (ps->ps_flags & SAS_OLDMASK) {
106247540Skarels 			returnmask = ps->ps_oldmask;
106353218Smckusick 			ps->ps_flags &= ~SAS_OLDMASK;
106447540Skarels 		} else
106547540Skarels 			returnmask = p->p_sigmask;
106664406Sbostic 		p->p_sigmask |= ps->ps_catchmask[signum] | mask;
106747540Skarels 		(void) spl0();
106847540Skarels 		p->p_stats->p_ru.ru_nsignals++;
106966921Smckusick 		if (ps->ps_sig != signum) {
107066921Smckusick 			code = 0;
107166921Smckusick 		} else {
107266921Smckusick 			code = ps->ps_code;
107366921Smckusick 			ps->ps_code = 0;
107467183Shibler 			ps->ps_sig = 0;
107566921Smckusick 		}
107666921Smckusick 		sendsig(action, signum, returnmask, code);
107747540Skarels 	}
10787421Sroot }
10797421Sroot 
10807421Sroot /*
108157533Smckusick  * Kill the current process for stated reason.
108257533Smckusick  */
108368310Scgd void
killproc(p,why)108457533Smckusick killproc(p, why)
108557533Smckusick 	struct proc *p;
108657533Smckusick 	char *why;
108757533Smckusick {
108857533Smckusick 
108957533Smckusick 	log(LOG_ERR, "pid %d was killed: %s\n", p->p_pid, why);
109057533Smckusick 	uprintf("sorry, pid %d was killed: %s\n", p->p_pid, why);
109157533Smckusick 	psignal(p, SIGKILL);
109257533Smckusick }
109357533Smckusick 
109457533Smckusick /*
109564406Sbostic  * Force the current process to exit with the specified signal, dumping core
109664406Sbostic  * if appropriate.  We bypass the normal tests for masked and caught signals,
109764406Sbostic  * allowing unrecoverable failures to terminate the process without changing
109864406Sbostic  * signal state.  Mark the accounting record with the signal termination.
109964406Sbostic  * If dumping core, save the signal number for the debugger.  Calls exit and
110064406Sbostic  * does not return.
110147650Skarels  */
110268310Scgd void
sigexit(p,signum)110364406Sbostic sigexit(p, signum)
110447650Skarels 	register struct proc *p;
110564406Sbostic 	int signum;
110647650Skarels {
110747650Skarels 
110847650Skarels 	p->p_acflag |= AXSIG;
110964406Sbostic 	if (sigprop[signum] & SA_CORE) {
111064406Sbostic 		p->p_sigacts->ps_sig = signum;
111147650Skarels 		if (coredump(p) == 0)
111264406Sbostic 			signum |= WCOREFLAG;
111347650Skarels 	}
111464406Sbostic 	exit1(p, W_EXITCODE(0, signum));
111547650Skarels 	/* NOTREACHED */
111647650Skarels }
111747650Skarels 
111847650Skarels /*
111966380Sbostic  * Dump core, into a file named "progname.core", unless the process was
112066380Sbostic  * setuid/setgid.
11217421Sroot  */
112268310Scgd int
coredump(p)112347540Skarels coredump(p)
112447540Skarels 	register struct proc *p;
11257421Sroot {
112637728Smckusick 	register struct vnode *vp;
112747540Skarels 	register struct pcred *pcred = p->p_cred;
112847540Skarels 	register struct ucred *cred = pcred->pc_ucred;
112947540Skarels 	register struct vmspace *vm = p->p_vmspace;
113066380Sbostic 	struct nameidata nd;
113137580Smckusick 	struct vattr vattr;
113250105Smckusick 	int error, error1;
113364406Sbostic 	char name[MAXCOMLEN+6];		/* progname.core */
11347421Sroot 
113564406Sbostic 	if (pcred->p_svuid != pcred->p_ruid || pcred->p_svgid != pcred->p_rgid)
113637580Smckusick 		return (EFAULT);
113747540Skarels 	if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
113847540Skarels 	    p->p_rlimit[RLIMIT_CORE].rlim_cur)
113937580Smckusick 		return (EFAULT);
114064406Sbostic 	sprintf(name, "%s.core", p->p_comm);
114152304Sheideman 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
114264406Sbostic 	if (error = vn_open(&nd,
114364406Sbostic 	    O_CREAT | FWRITE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))
114437580Smckusick 		return (error);
114547540Skarels 	vp = nd.ni_vp;
114664406Sbostic 
114764406Sbostic 	/* Don't dump to non-regular files or files with links. */
114864406Sbostic 	if (vp->v_type != VREG ||
114964406Sbostic 	    VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) {
115050105Smckusick 		error = EFAULT;
115150105Smckusick 		goto out;
11527818Sroot 	}
115341362Smckusick 	VATTR_NULL(&vattr);
115437580Smckusick 	vattr.va_size = 0;
115567654Smckusick 	VOP_LEASE(vp, p, cred, LEASE_WRITE);
115648020Smckusick 	VOP_SETATTR(vp, &vattr, cred, p);
115747540Skarels 	p->p_acflag |= ACORE;
115849102Skarels 	bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
115949102Skarels 	fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
116052925Smckusick 	error = cpu_coredump(p, vp, cred);
116137580Smckusick 	if (error == 0)
116247540Skarels 		error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
116347540Skarels 		    (int)ctob(vm->vm_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE,
116449102Skarels 		    IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
116537580Smckusick 	if (error == 0)
116637580Smckusick 		error = vn_rdwr(UIO_WRITE, vp,
116749102Skarels 		    (caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)),
116847540Skarels 		    round_page(ctob(vm->vm_ssize)),
116947540Skarels 		    (off_t)ctob(UPAGES) + ctob(vm->vm_dsize), UIO_USERSPACE,
117049102Skarels 		    IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
117150105Smckusick out:
1172*69409Smckusick 	VOP_UNLOCK(vp, 0, p);
117350105Smckusick 	error1 = vn_close(vp, FWRITE, cred, p);
117450244Skarels 	if (error == 0)
117550105Smckusick 		error = error1;
117637580Smckusick 	return (error);
11777421Sroot }
117839513Skarels 
117939513Skarels /*
118039513Skarels  * Nonexistent system call-- signal process (may want to handle it).
118139513Skarels  * Flag error in case process won't see signal immediately (blocked or ignored).
118239513Skarels  */
118343364Smckusick /* ARGSUSED */
118468171Scgd int
nosys(p,args,retval)118543364Smckusick nosys(p, args, retval)
118643364Smckusick 	struct proc *p;
118768171Scgd 	void *args;
118868171Scgd 	register_t *retval;
118939513Skarels {
119039513Skarels 
119143364Smckusick 	psignal(p, SIGSYS);
119268042Smckusick 	return (ENOSYS);
119339513Skarels }
1194