xref: /csrg-svn/sys/kern/kern_sig.c (revision 44440)
123374Smckusick /*
237580Smckusick  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
337580Smckusick  * All rights reserved.
423374Smckusick  *
5*44440Sbostic  * %sccs.include.redist.c%
637580Smckusick  *
7*44440Sbostic  *	@(#)kern_sig.c	7.23 (Berkeley) 06/28/90
823374Smckusick  */
97421Sroot 
1017092Sbloom #include "param.h"
1117092Sbloom #include "systm.h"
1244405Skarels #include "user.h"
1337580Smckusick #include "vnode.h"
1417092Sbloom #include "proc.h"
1517092Sbloom #include "timeb.h"
1617092Sbloom #include "times.h"
1717092Sbloom #include "buf.h"
1817092Sbloom #include "text.h"
1917092Sbloom #include "seg.h"
2017092Sbloom #include "vm.h"
2117092Sbloom #include "acct.h"
2217092Sbloom #include "uio.h"
2337580Smckusick #include "file.h"
2417092Sbloom #include "kernel.h"
2539513Skarels #include "wait.h"
2640807Smarc #include "ktrace.h"
277421Sroot 
2837581Smckusick #include "machine/reg.h"
2937581Smckusick #include "machine/pte.h"
3037581Smckusick #include "machine/psl.h"
3137581Smckusick #include "machine/mtpr.h"
3237581Smckusick 
3342437Skarels #define	ttystopsigmask	(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU))
3442437Skarels #define	stopsigmask	(sigmask(SIGSTOP)|ttystopsigmask)
3539513Skarels #define defaultignmask	(sigmask(SIGCONT)|sigmask(SIGIO)|sigmask(SIGURG)| \
3639513Skarels 			sigmask(SIGCHLD)|sigmask(SIGWINCH)|sigmask(SIGINFO))
3712951Ssam 
3817013Smckusick /*
3942920Skarels  * Can process p send the signal signo to process q?
4017013Smckusick  */
4142920Skarels #define CANSIGNAL(p, q, signo) \
4242920Skarels 	((p)->p_uid == 0 || \
4342920Skarels 	    (p)->p_ruid == (q)->p_ruid || (p)->p_uid == (q)->p_ruid || \
4442920Skarels 	    (p)->p_ruid == (q)->p_uid || (p)->p_uid == (q)->p_uid || \
4542920Skarels 	    ((signo) == SIGCONT && (q)->p_session == (p)->p_session))
4639513Skarels 
4742920Skarels /* ARGSUSED */
4842920Skarels sigaction(p, uap, retval)
4942920Skarels 	struct proc *p;
5042920Skarels 	register struct args {
5112882Ssam 		int	signo;
5239513Skarels 		struct	sigaction *nsa;
5339513Skarels 		struct	sigaction *osa;
5442920Skarels 	} *uap;
5542920Skarels 	int *retval;
5642920Skarels {
5739513Skarels 	struct sigaction vec;
5839513Skarels 	register struct sigaction *sa;
5912882Ssam 	register int sig;
6039513Skarels 	int bit, error;
617421Sroot 
6212882Ssam 	sig = uap->signo;
6339513Skarels 	if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
6444405Skarels 		return (EINVAL);
6539513Skarels 	sa = &vec;
6639513Skarels 	if (uap->osa) {
6739513Skarels 		sa->sa_handler = u.u_signal[sig];
6839513Skarels 		sa->sa_mask = u.u_sigmask[sig];
6918308Smckusick 		bit = sigmask(sig);
7039513Skarels 		sa->sa_flags = 0;
7118308Smckusick 		if ((u.u_sigonstack & bit) != 0)
7239513Skarels 			sa->sa_flags |= SA_ONSTACK;
7339513Skarels 		if ((u.u_sigintr & bit) == 0)
7439513Skarels 			sa->sa_flags |= SA_RESTART;
7542920Skarels 		if (p->p_flag & SNOCLDSTOP)
7639513Skarels 			sa->sa_flags |= SA_NOCLDSTOP;
7739513Skarels 		if (error = copyout((caddr_t)sa, (caddr_t)uap->osa,
7839513Skarels 		    sizeof (vec)))
7944405Skarels 			return (error);
8012951Ssam 	}
8139513Skarels 	if (uap->nsa) {
8239513Skarels 		if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
8339513Skarels 		    sizeof (vec)))
8444405Skarels 			return (error);
8542920Skarels 		setsigvec(p, sig, sa);
8612951Ssam 	}
8744405Skarels 	return (0);
887421Sroot }
897421Sroot 
9042920Skarels setsigvec(p, sig, sa)
9142920Skarels 	register struct proc *p;
9212951Ssam 	int sig;
9339513Skarels 	register struct sigaction *sa;
9412882Ssam {
9512951Ssam 	register int bit;
9612882Ssam 
9717153Sbloom 	bit = sigmask(sig);
9812882Ssam 	/*
9912882Ssam 	 * Change setting atomically.
10012882Ssam 	 */
10117153Sbloom 	(void) splhigh();
10239513Skarels 	u.u_signal[sig] = sa->sa_handler;
10339513Skarels 	u.u_sigmask[sig] = sa->sa_mask &~ sigcantmask;
10439513Skarels 	if ((sa->sa_flags & SA_RESTART) == 0)
10518308Smckusick 		u.u_sigintr |= bit;
10618308Smckusick 	else
10718308Smckusick 		u.u_sigintr &= ~bit;
10839513Skarels 	if (sa->sa_flags & SA_ONSTACK)
10912951Ssam 		u.u_sigonstack |= bit;
11012951Ssam 	else
11112951Ssam 		u.u_sigonstack &= ~bit;
11239513Skarels 	if (sig == SIGCHLD) {
11339513Skarels 		if (sa->sa_flags & SA_NOCLDSTOP)
11439513Skarels 			p->p_flag |= SNOCLDSTOP;
11539513Skarels 		else
11639513Skarels 			p->p_flag &= ~SNOCLDSTOP;
11739513Skarels 	}
11839513Skarels 	/*
11939513Skarels 	 * Set bit in p_sigignore for signals that are set to SIG_IGN,
12039513Skarels 	 * and for signals set to SIG_DFL where the default is to ignore.
12139513Skarels 	 * However, don't put SIGCONT in p_sigignore,
12239513Skarels 	 * as we have to restart the process.
12339513Skarels 	 */
12439513Skarels 	if (sa->sa_handler == SIG_IGN ||
12539513Skarels 	   (bit & defaultignmask && sa->sa_handler == SIG_DFL)) {
12612951Ssam 		p->p_sig &= ~bit;		/* never to be seen again */
12739513Skarels 		if (sig != SIGCONT)
12839513Skarels 			p->p_sigignore |= bit;	/* easier in psignal */
12912951Ssam 		p->p_sigcatch &= ~bit;
13012882Ssam 	} else {
13112951Ssam 		p->p_sigignore &= ~bit;
13239513Skarels 		if (sa->sa_handler == SIG_DFL)
13312951Ssam 			p->p_sigcatch &= ~bit;
13412882Ssam 		else
13512951Ssam 			p->p_sigcatch |= bit;
13612882Ssam 	}
13712882Ssam 	(void) spl0();
13812882Ssam }
13912882Ssam 
14039513Skarels /*
14139513Skarels  * Initialize signal state for process 0;
14239513Skarels  * set to ignore signals that are ignored by default.
14339513Skarels  */
14439513Skarels siginit(p)
14539513Skarels 	struct proc *p;
1467421Sroot {
14739513Skarels 
14839513Skarels 	p->p_sigignore = defaultignmask &~ sigmask(SIGCONT);
14939513Skarels }
15039513Skarels 
15139513Skarels /*
15239513Skarels  * Reset signals for an exec of the specified process.
15339513Skarels  */
15439513Skarels execsigs(p)
15539513Skarels 	register struct proc *p;
15639513Skarels {
15739513Skarels 	register int nc, mask;
15839513Skarels 
15939513Skarels 	/*
16039513Skarels 	 * Reset caught signals.  Held signals remain held
16139513Skarels 	 * through p_sigmask (unless they were caught,
16239513Skarels 	 * and are now ignored by default).
16339513Skarels 	 */
16439513Skarels 	while (p->p_sigcatch) {
16539513Skarels 		nc = ffs((long)p->p_sigcatch);
16639513Skarels 		mask = sigmask(nc);
16739513Skarels 		p->p_sigcatch &= ~mask;
16839513Skarels 		if (mask & defaultignmask) {
16939513Skarels 			if (nc != SIGCONT)
17039513Skarels 				p->p_sigignore |= mask;
17139513Skarels 			p->p_sig &= ~mask;
17239513Skarels 		}
17339513Skarels 		u.u_signal[nc] = SIG_DFL;
17439513Skarels 	}
17539513Skarels 	/*
17639513Skarels 	 * Reset stack state to the user stack.
17739513Skarels 	 * Clear set of signals caught on the signal stack.
17839513Skarels 	 */
17939513Skarels 	u.u_onstack = 0;
18039513Skarels 	u.u_sigsp = 0;
18139513Skarels 	u.u_sigonstack = 0;
18239513Skarels }
18339513Skarels 
18439513Skarels /*
18539513Skarels  * Manipulate signal mask.
18639513Skarels  * Note that we receive new mask, not pointer,
18739513Skarels  * and return old mask as return value;
18839513Skarels  * the library stub does the rest.
18939513Skarels  */
19042920Skarels sigprocmask(p, uap, retval)
19142920Skarels 	register struct proc *p;
19242920Skarels 	struct args {
19339513Skarels 		int	how;
19439513Skarels 		sigset_t mask;
19542920Skarels 	} *uap;
19642920Skarels 	int *retval;
19742920Skarels {
19839513Skarels 	int error = 0;
19939513Skarels 
20042920Skarels 	*retval = p->p_sigmask;
20139513Skarels 	(void) splhigh();
20239513Skarels 
20339513Skarels 	switch (uap->how) {
20439513Skarels 	case SIG_BLOCK:
20539513Skarels 		p->p_sigmask |= uap->mask &~ sigcantmask;
20639513Skarels 		break;
20739513Skarels 
20839513Skarels 	case SIG_UNBLOCK:
20939513Skarels 		p->p_sigmask &= ~uap->mask;
21039513Skarels 		break;
21139513Skarels 
21239513Skarels 	case SIG_SETMASK:
21339513Skarels 		p->p_sigmask = uap->mask &~ sigcantmask;
21439513Skarels 		break;
21539513Skarels 
21639513Skarels 	default:
21739513Skarels 		error = EINVAL;
21839513Skarels 		break;
21939513Skarels 	}
22039513Skarels 	(void) spl0();
22144405Skarels 	return (error);
22239513Skarels }
22339513Skarels 
22442920Skarels /* ARGSUSED */
22542920Skarels sigpending(p, uap, retval)
22642920Skarels 	struct proc *p;
22742920Skarels 	void *uap;
22842920Skarels 	int *retval;
22939513Skarels {
23039513Skarels 
23142920Skarels 	*retval = p->p_sig;
23244405Skarels 	return (0);
23339513Skarels }
23439513Skarels 
23539513Skarels #ifdef COMPAT_43
23639513Skarels /*
23739513Skarels  * Generalized interface signal handler, 4.3-compatible.
23839513Skarels  */
23942920Skarels /* ARGSUSED */
24042920Skarels osigvec(p, uap, retval)
24142920Skarels 	struct proc *p;
24242920Skarels 	register struct args {
24339513Skarels 		int	signo;
24439513Skarels 		struct	sigvec *nsv;
24539513Skarels 		struct	sigvec *osv;
24642920Skarels 	} *uap;
24742920Skarels 	int *retval;
24842920Skarels {
24939513Skarels 	struct sigvec vec;
25039513Skarels 	register struct sigvec *sv;
25139513Skarels 	register int sig;
25239513Skarels 	int bit, error;
25339513Skarels 
25439513Skarels 	sig = uap->signo;
25539513Skarels 	if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
25644405Skarels 		return (EINVAL);
25739513Skarels 	sv = &vec;
25839513Skarels 	if (uap->osv) {
25939513Skarels 		*(sig_t *)&sv->sv_handler = u.u_signal[sig];
26039513Skarels 		sv->sv_mask = u.u_sigmask[sig];
26139513Skarels 		bit = sigmask(sig);
26239513Skarels 		sv->sv_flags = 0;
26339513Skarels 		if ((u.u_sigonstack & bit) != 0)
26439513Skarels 			sv->sv_flags |= SV_ONSTACK;
26539513Skarels 		if ((u.u_sigintr & bit) != 0)
26639513Skarels 			sv->sv_flags |= SV_INTERRUPT;
26742920Skarels 		if (p->p_flag & SNOCLDSTOP)
26839513Skarels 			sv->sv_flags |= SA_NOCLDSTOP;
26939513Skarels 		if (error = copyout((caddr_t)sv, (caddr_t)uap->osv,
27039513Skarels 		    sizeof (vec)))
27144405Skarels 			return (error);
27239513Skarels 	}
27339513Skarels 	if (uap->nsv) {
27439513Skarels 		if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv,
27539513Skarels 		    sizeof (vec)))
27644405Skarels 			return (error);
27739513Skarels 		sv->sv_flags ^= SA_RESTART;	/* opposite of SV_INTERRUPT */
27842920Skarels 		setsigvec(p, sig, (struct sigaction *)sv);
27939513Skarels 	}
28044405Skarels 	return (0);
28139513Skarels }
28239513Skarels 
28342920Skarels osigblock(p, uap, retval)
28442920Skarels 	register struct proc *p;
28542920Skarels 	struct args {
28642920Skarels 		int	mask;
28742920Skarels 	} *uap;
28842920Skarels 	int *retval;
28939513Skarels {
2907499Sroot 
29117153Sbloom 	(void) splhigh();
29242920Skarels 	*retval = p->p_sigmask;
29339513Skarels 	p->p_sigmask |= uap->mask &~ sigcantmask;
29412882Ssam 	(void) spl0();
29544405Skarels 	return (0);
2967499Sroot }
2977499Sroot 
29842920Skarels osigsetmask(p, uap, retval)
29942920Skarels 	struct proc *p;
30042920Skarels 	struct args {
30142920Skarels 		int	mask;
30242920Skarels 	} *uap;
30342920Skarels 	int *retval;
3047499Sroot {
3057499Sroot 
30617153Sbloom 	(void) splhigh();
30742920Skarels 	*retval = p->p_sigmask;
30839513Skarels 	p->p_sigmask = uap->mask &~ sigcantmask;
30912882Ssam 	(void) spl0();
31044405Skarels 	return (0);
3117499Sroot }
31239513Skarels #endif
3137499Sroot 
31439513Skarels /*
31539513Skarels  * Suspend process until signal, providing mask to be set
31639513Skarels  * in the meantime.  Note nonstandard calling convention:
31739513Skarels  * libc stub passes mask, not pointer, to save a copyin.
31839513Skarels  */
31942920Skarels /* ARGSUSED */
32042920Skarels sigsuspend(p, uap, retval)
32142920Skarels 	register struct proc *p;
32242920Skarels 	struct args {
32342920Skarels 		sigset_t mask;
32442920Skarels 	} *uap;
32542920Skarels 	int *retval;
3267499Sroot {
3277499Sroot 
32812882Ssam 	/*
32912882Ssam 	 * When returning from sigpause, we want
33012882Ssam 	 * the old mask to be restored after the
33112882Ssam 	 * signal handler has finished.  Thus, we
33212882Ssam 	 * save it here and mark the proc structure
33312882Ssam 	 * to indicate this (should be in u.).
33412882Ssam 	 */
33512882Ssam 	u.u_oldmask = p->p_sigmask;
33612882Ssam 	p->p_flag |= SOMASK;
33739513Skarels 	p->p_sigmask = uap->mask &~ sigcantmask;
33840807Smarc 	(void) tsleep((caddr_t)&u, PPAUSE | PCATCH, "pause", 0);
33940807Smarc 	/* always return EINTR rather than ERESTART... */
34044405Skarels 	return (EINTR);
3417499Sroot }
3427499Sroot 
34342920Skarels /* ARGSUSED */
34442920Skarels sigstack(p, uap, retval)
34542920Skarels 	struct proc *p;
34642920Skarels 	register struct args {
34712951Ssam 		struct	sigstack *nss;
34812951Ssam 		struct	sigstack *oss;
34942920Skarels 	} *uap;
35042920Skarels 	int *retval;
35142920Skarels {
35212951Ssam 	struct sigstack ss;
35339513Skarels 	int error = 0;
3547499Sroot 
35539513Skarels 	if (uap->oss && (error = copyout((caddr_t)&u.u_sigstack,
35639513Skarels 	    (caddr_t)uap->oss, sizeof (struct sigstack))))
35744405Skarels 		return (error);
35839513Skarels 	if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
35939513Skarels 	    sizeof (ss))) == 0)
36039513Skarels 		u.u_sigstack = ss;
36144405Skarels 	return (error);
3627499Sroot }
3637499Sroot 
36442920Skarels /* ARGSUSED */
36542920Skarels kill(cp, uap, retval)
36642920Skarels 	register struct proc *cp;
36742920Skarels 	register struct args {
36812882Ssam 		int	pid;
36912882Ssam 		int	signo;
37042920Skarels 	} *uap;
37142920Skarels 	int *retval;
37242920Skarels {
37318336Smckusick 	register struct proc *p;
3748032Sroot 
37539513Skarels 	if ((unsigned) uap->signo >= NSIG)
37644405Skarels 		return (EINVAL);
37718336Smckusick 	if (uap->pid > 0) {
37818336Smckusick 		/* kill single process */
37918336Smckusick 		p = pfind(uap->pid);
38039513Skarels 		if (p == 0)
38144405Skarels 			return (ESRCH);
38242920Skarels 		if (!CANSIGNAL(cp, p, uap->signo))
38344405Skarels 			return (EPERM);
38439513Skarels 		if (uap->signo)
38518336Smckusick 			psignal(p, uap->signo);
38644405Skarels 		return (0);
38718336Smckusick 	}
38818336Smckusick 	switch (uap->pid) {
38918336Smckusick 	case -1:		/* broadcast signal */
39044405Skarels 		return (killpg1(cp, uap->signo, 0, 1));
39118336Smckusick 	case 0:			/* signal own process group */
39244405Skarels 		return (killpg1(cp, uap->signo, 0, 0));
39318336Smckusick 	default:		/* negative explicit process group */
39444405Skarels 		return (killpg1(cp, uap->signo, -uap->pid, 0));
39518336Smckusick 	}
39639513Skarels 	/* NOTREACHED */
3978032Sroot }
3988032Sroot 
39939513Skarels #ifdef COMPAT_43
40042920Skarels /* ARGSUSED */
40142920Skarels okillpg(p, uap, retval)
40242920Skarels 	struct proc *p;
40342920Skarels 	register struct args {
40437581Smckusick 		int	pgid;
4059989Ssam 		int	signo;
40642920Skarels 	} *uap;
40742920Skarels 	int *retval;
40842920Skarels {
4098032Sroot 
41039513Skarels 	if ((unsigned) uap->signo >= NSIG)
41144405Skarels 		return (EINVAL);
41244405Skarels 	return (killpg1(p, uap->signo, uap->pgid, 0));
4138032Sroot }
41439513Skarels #endif
4158032Sroot 
41642920Skarels /*
41742920Skarels  * Common code for kill process group/broadcast kill.
41842920Skarels  * cp is calling process.
41942920Skarels  */
42042920Skarels killpg1(cp, signo, pgid, all)
42142920Skarels 	register struct proc *cp;
42237581Smckusick 	int signo, pgid, all;
4239989Ssam {
4249989Ssam 	register struct proc *p;
42537581Smckusick 	struct pgrp *pgrp;
42643364Smckusick 	int f = 0;
42737581Smckusick 
42837581Smckusick 	if (all)
42937581Smckusick 		/*
43037581Smckusick 		 * broadcast
4317421Sroot 		 */
43237581Smckusick 		for (p = allproc; p != NULL; p = p->p_nxt) {
43337581Smckusick 			if (p->p_ppid == 0 || p->p_flag&SSYS ||
43442920Skarels 			    p == u.u_procp || !CANSIGNAL(cp, p, signo))
43537581Smckusick 				continue;
43637581Smckusick 			f++;
43737581Smckusick 			if (signo)
43837581Smckusick 				psignal(p, signo);
43937581Smckusick 		}
44037581Smckusick 	else {
44137581Smckusick 		if (pgid == 0)
44237581Smckusick 			/*
44337581Smckusick 			 * zero pgid means send to my process group.
44437581Smckusick 			 */
44537581Smckusick 			pgrp = u.u_procp->p_pgrp;
44637581Smckusick 		else {
44737581Smckusick 			pgrp = pgfind(pgid);
44837581Smckusick 			if (pgrp == NULL)
44939513Skarels 				return (ESRCH);
45037581Smckusick 		}
45137581Smckusick 		for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) {
45239513Skarels 			if (p->p_ppid == 0 || p->p_flag&SSYS ||
45342920Skarels 			    !CANSIGNAL(cp, p, signo))
45437581Smckusick 				continue;
45537581Smckusick 			f++;
45637581Smckusick 			if (signo)
45737581Smckusick 				psignal(p, signo);
45818336Smckusick 		}
4597421Sroot 	}
46043364Smckusick 	return (f ? 0 : ESRCH);
4617421Sroot }
4627421Sroot 
46342920Skarels /*
4647421Sroot  * Send the specified signal to
46537581Smckusick  * all processes with 'pgid' as
4667421Sroot  * process group.
4677421Sroot  */
46837581Smckusick gsignal(pgid, sig)
4697421Sroot {
47039513Skarels 	struct pgrp *pgrp;
4717421Sroot 
47239513Skarels 	if (pgid && (pgrp = pgfind(pgid)))
47342207Smarc 		pgsignal(pgrp, sig, 0);
4747421Sroot }
47542920Skarels 
47640807Smarc /*
47742207Smarc  * Send sig to every member of a process group.
47842207Smarc  * If checktty is 1, limit to members which have a controlling
47942207Smarc  * terminal.
48040807Smarc  */
48142207Smarc pgsignal(pgrp, sig, checkctty)
48239513Skarels 	struct pgrp *pgrp;
48337581Smckusick {
48437581Smckusick 	register struct proc *p;
48537581Smckusick 
48640807Smarc 	if (pgrp)
48740807Smarc 		for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt)
48842207Smarc 			if (checkctty == 0 || p->p_flag&SCTTY)
48942207Smarc 				psignal(p, sig);
49037581Smckusick }
49137581Smckusick 
4927421Sroot /*
49339513Skarels  * Send a signal caused by a trap to the current process.
49439513Skarels  * If it will be caught immediately, deliver it with correct code.
49539513Skarels  * Otherwise, post it normally.
49639513Skarels  */
49739513Skarels trapsignal(sig, code)
49839513Skarels 	register int sig;
49939513Skarels 	unsigned code;
50039513Skarels {
50142920Skarels 	register struct proc *p = u.u_procp;	/* XXX */
50239513Skarels 	int mask;
50339513Skarels 
50439513Skarels 	mask = sigmask(sig);
50539513Skarels 	if ((p->p_flag & STRC) == 0 && (p->p_sigcatch & mask) != 0 &&
50639513Skarels 	    (p->p_sigmask & mask) == 0) {
50739513Skarels 		u.u_ru.ru_nsignals++;
50840807Smarc #ifdef KTRACE
50940807Smarc 		if (KTRPOINT(p, KTR_PSIG))
51040807Smarc 			ktrpsig(p->p_tracep, sig, u.u_signal[sig],
51140807Smarc 				p->p_sigmask, code);
51240807Smarc #endif
51339513Skarels 		sendsig(u.u_signal[sig], sig, p->p_sigmask, code);
51439513Skarels 		p->p_sigmask |= u.u_sigmask[sig] | mask;
51539513Skarels 	} else {
51643895Skarels 		u.u_code = code;	/* XXX for core dump/debugger */
51739513Skarels 		psignal(p, sig);
51839513Skarels 	}
51939513Skarels }
52039513Skarels 
52139513Skarels /*
52240807Smarc  * Send the specified signal to the specified process.
52340807Smarc  * Most signals do not do anything directly to a process;
52440807Smarc  * they set a flag that asks the process to do something to itself.
52540807Smarc  * Exceptions:
52640807Smarc  *   o When a stop signal is sent to a sleeping process that takes the default
52740807Smarc  *     action, the process is stopped without awakening it.
52840807Smarc  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
52940807Smarc  *     regardless of the signal action (eg, blocked or ignored).
53040807Smarc  * Other ignored signals are discarded immediately.
5317421Sroot  */
5327421Sroot psignal(p, sig)
5337421Sroot 	register struct proc *p;
5347421Sroot 	register int sig;
5357421Sroot {
5367421Sroot 	register int s;
53739513Skarels 	register sig_t action;
53817153Sbloom 	int mask;
5397421Sroot 
54039513Skarels 	if ((unsigned)sig >= NSIG || sig == 0)
54139513Skarels 		panic("psignal sig");
54217153Sbloom 	mask = sigmask(sig);
5437421Sroot 
5447421Sroot 	/*
5457421Sroot 	 * If proc is traced, always give parent a chance.
5467421Sroot 	 */
5477421Sroot 	if (p->p_flag & STRC)
5487421Sroot 		action = SIG_DFL;
5497421Sroot 	else {
5507421Sroot 		/*
55112882Ssam 		 * If the signal is being ignored,
55212882Ssam 		 * then we forget about it immediately.
55339513Skarels 		 * (Note: we don't set SIGCONT in p_sigignore,
55439513Skarels 		 * and if it is set to SIG_IGN,
55539513Skarels 		 * action will be SIG_DFL here.)
5567421Sroot 		 */
55717153Sbloom 		if (p->p_sigignore & mask)
5587421Sroot 			return;
55917153Sbloom 		if (p->p_sigmask & mask)
56012882Ssam 			action = SIG_HOLD;
56117153Sbloom 		else if (p->p_sigcatch & mask)
56212882Ssam 			action = SIG_CATCH;
56342437Skarels 		else
56412882Ssam 			action = SIG_DFL;
5657421Sroot 	}
56639513Skarels 	switch (sig) {
5677421Sroot 
56839513Skarels 	case SIGTERM:
56939513Skarels 		if ((p->p_flag&STRC) || action != SIG_DFL)
5707421Sroot 			break;
57139513Skarels 		/* FALLTHROUGH */
5727421Sroot 
57339513Skarels 	case SIGKILL:
57439513Skarels 		if (p->p_nice > NZERO)
57539513Skarels 			p->p_nice = NZERO;
57639513Skarels 		break;
5777421Sroot 
57839513Skarels 	case SIGCONT:
57939513Skarels 		p->p_sig &= ~stopsigmask;
58039513Skarels 		break;
58139513Skarels 
58239513Skarels 	case SIGTSTP:
58339513Skarels 	case SIGTTIN:
58439513Skarels 	case SIGTTOU:
58539513Skarels 	case SIGSTOP:
58639513Skarels 		p->p_sig &= ~sigmask(SIGCONT);
58739513Skarels 		break;
5887421Sroot 	}
58939513Skarels 	p->p_sig |= mask;
59039513Skarels 
5917421Sroot 	/*
59239513Skarels 	 * Defer further processing for signals which are held,
59339513Skarels 	 * except that stopped processes must be continued by SIGCONT.
5947421Sroot 	 */
59539513Skarels 	if (action == SIG_HOLD && (sig != SIGCONT || p->p_stat != SSTOP))
5967421Sroot 		return;
59717153Sbloom 	s = splhigh();
5987421Sroot 	switch (p->p_stat) {
5997421Sroot 
6007421Sroot 	case SSLEEP:
6017421Sroot 		/*
60240807Smarc 		 * If process is sleeping uninterruptibly
6037421Sroot 		 * we can't interrupt the sleep... the signal will
6047421Sroot 		 * be noticed when the process returns through
6057421Sroot 		 * trap() or syscall().
6067421Sroot 		 */
60740807Smarc 		if ((p->p_flag & SSINTR) == 0)
6087421Sroot 			goto out;
6097421Sroot 		/*
6107421Sroot 		 * Process is sleeping and traced... make it runnable
6117421Sroot 		 * so it can discover the signal in issig() and stop
6127421Sroot 		 * for the parent.
6137421Sroot 		 */
6147421Sroot 		if (p->p_flag&STRC)
6157421Sroot 			goto run;
61639513Skarels 		/*
61739513Skarels 		 * When a sleeping process receives a stop
61839513Skarels 		 * signal, process immediately if possible.
61939513Skarels 		 * All other (caught or default) signals
62039513Skarels 		 * cause the process to run.
62139513Skarels 		 */
62239513Skarels 		if (mask & stopsigmask) {
6237421Sroot 			if (action != SIG_DFL)
62439513Skarels 				goto runfast;
6257421Sroot 			/*
6267421Sroot 			 * If a child in vfork(), stopping could
6277421Sroot 			 * cause deadlock.
6287421Sroot 			 */
6297421Sroot 			if (p->p_flag&SVFORK)
6307421Sroot 				goto out;
63117153Sbloom 			p->p_sig &= ~mask;
63243895Skarels 			p->p_xstat = sig;
63339513Skarels 			if ((p->p_pptr->p_flag & SNOCLDSTOP) == 0)
63439513Skarels 				psignal(p->p_pptr, SIGCHLD);
6357421Sroot 			stop(p);
6367421Sroot 			goto out;
63739513Skarels 		} else
63839513Skarels 			goto runfast;
6397421Sroot 		/*NOTREACHED*/
6407421Sroot 
6417421Sroot 	case SSTOP:
6427421Sroot 		/*
6437421Sroot 		 * If traced process is already stopped,
6447421Sroot 		 * then no further action is necessary.
6457421Sroot 		 */
6467421Sroot 		if (p->p_flag&STRC)
6477421Sroot 			goto out;
6487421Sroot 		switch (sig) {
6497421Sroot 
6507421Sroot 		case SIGKILL:
6517421Sroot 			/*
6527421Sroot 			 * Kill signal always sets processes running.
6537421Sroot 			 */
65439513Skarels 			goto runfast;
6557421Sroot 
6567421Sroot 		case SIGCONT:
6577421Sroot 			/*
65839513Skarels 			 * If SIGCONT is default (or ignored), we continue
65939513Skarels 			 * the process but don't leave the signal in p_sig,
66039513Skarels 			 * as it has no further action.  If SIGCONT is held,
66139513Skarels 			 * continue the process and leave the signal in p_sig.
6627421Sroot 			 * If the process catches SIGCONT, let it handle
6637421Sroot 			 * the signal itself.  If it isn't waiting on
6647421Sroot 			 * an event, then it goes back to run state.
6657421Sroot 			 * Otherwise, process goes back to sleep state.
6667421Sroot 			 */
66739513Skarels 			if (action == SIG_DFL)
66839513Skarels 				p->p_sig &= ~mask;
66939513Skarels 			if (action == SIG_CATCH)
67039513Skarels 				goto runfast;
67139513Skarels 			if (p->p_wchan == 0)
6727421Sroot 				goto run;
6737421Sroot 			p->p_stat = SSLEEP;
6747421Sroot 			goto out;
6757421Sroot 
6767421Sroot 		case SIGSTOP:
6777421Sroot 		case SIGTSTP:
6787421Sroot 		case SIGTTIN:
6797421Sroot 		case SIGTTOU:
6807421Sroot 			/*
6817421Sroot 			 * Already stopped, don't need to stop again.
6827421Sroot 			 * (If we did the shell could get confused.)
6837421Sroot 			 */
68417153Sbloom 			p->p_sig &= ~mask;		/* take it away */
6857421Sroot 			goto out;
6867421Sroot 
6877421Sroot 		default:
6887421Sroot 			/*
6897421Sroot 			 * If process is sleeping interruptibly, then
69040807Smarc 			 * simulate a wakeup so that when it is continued,
69140807Smarc 			 * it will be made runnable and can look at the signal.
69240807Smarc 			 * But don't setrun the process, leave it stopped.
6937421Sroot 			 */
69440807Smarc 			if (p->p_wchan && p->p_flag & SSINTR)
6957421Sroot 				unsleep(p);
6967421Sroot 			goto out;
6977421Sroot 		}
6987421Sroot 		/*NOTREACHED*/
6997421Sroot 
7007421Sroot 	default:
7017421Sroot 		/*
7027421Sroot 		 * SRUN, SIDL, SZOMB do nothing with the signal,
7037421Sroot 		 * other than kicking ourselves if we are running.
7047421Sroot 		 * It will either never be noticed, or noticed very soon.
7057421Sroot 		 */
7067421Sroot 		if (p == u.u_procp && !noproc)
7077421Sroot 			aston();
7087421Sroot 		goto out;
7097421Sroot 	}
7107421Sroot 	/*NOTREACHED*/
71139513Skarels 
71239513Skarels runfast:
7137421Sroot 	/*
7147421Sroot 	 * Raise priority to at least PUSER.
7157421Sroot 	 */
7167421Sroot 	if (p->p_pri > PUSER)
71717399Skarels 		p->p_pri = PUSER;
71839513Skarels run:
7197421Sroot 	setrun(p);
7207421Sroot out:
7217421Sroot 	splx(s);
7227421Sroot }
7237421Sroot 
7247421Sroot /*
72540807Smarc  * If the current process has a signal to process (should be caught
72640807Smarc  * or cause termination, should interrupt current syscall),
72740807Smarc  * return the signal number.  Stop signals with default action
72840807Smarc  * are processed immediately, then cleared; they aren't returned.
7297421Sroot  * This is asked at least once each time a process enters the
7307421Sroot  * system (though this can usually be done without actually
7317421Sroot  * calling issig by checking the pending signal masks.)
7327421Sroot  */
7337421Sroot issig()
7347421Sroot {
73542926Smckusick 	register struct proc *p = u.u_procp;		/* XXX */
73639513Skarels 	register int sig, mask;
7377421Sroot 
7387421Sroot 	for (;;) {
73939513Skarels 		mask = p->p_sig &~ p->p_sigmask;
7407421Sroot 		if (p->p_flag&SVFORK)
74139513Skarels 			mask &= ~stopsigmask;
74240807Smarc 		if (mask == 0)	 	/* no signal to send */
74340807Smarc 			return (0);
74439513Skarels 		sig = ffs((long)mask);
74517153Sbloom 		mask = sigmask(sig);
74640807Smarc 		/*
74740807Smarc 		 * We should see pending but ignored signals
74840807Smarc 		 * only if STRC was on when they were posted.
74940807Smarc 		 */
75040807Smarc 		if (mask & p->p_sigignore && (p->p_flag&STRC) == 0) {
75140807Smarc 			p->p_sig &= ~mask;
75240807Smarc 			continue;
75340807Smarc 		}
75412882Ssam 		if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) {
7557421Sroot 			/*
7567421Sroot 			 * If traced, always stop, and stay
7577421Sroot 			 * stopped until released by the parent.
7587421Sroot 			 */
75943895Skarels 			p->p_xstat = sig;
76018331Skarels 			psignal(p->p_pptr, SIGCHLD);
7617421Sroot 			do {
7627421Sroot 				stop(p);
7637421Sroot 				swtch();
76442926Smckusick 			} while (!procxmt(p) && p->p_flag&STRC);
7657421Sroot 
7667421Sroot 			/*
76714782Ssam 			 * If the traced bit got turned off,
76840807Smarc 			 * go back up to the top to rescan signals.
76914782Ssam 			 * This ensures that p_sig* and u_signal are consistent.
7707421Sroot 			 */
77140807Smarc 			if ((p->p_flag&STRC) == 0)
7727421Sroot 				continue;
7737421Sroot 
7747421Sroot 			/*
7757421Sroot 			 * If parent wants us to take the signal,
77643895Skarels 			 * then it will leave it in p->p_xstat;
7777421Sroot 			 * otherwise we just look for signals again.
7787421Sroot 			 */
77940807Smarc 			p->p_sig &= ~mask;	/* clear the old signal */
78043895Skarels 			sig = p->p_xstat;
7817421Sroot 			if (sig == 0)
7827421Sroot 				continue;
78314782Ssam 
78414782Ssam 			/*
78540807Smarc 			 * Put the new signal into p_sig.
78640807Smarc 			 * If signal is being masked,
78740807Smarc 			 * look for other signals.
78814782Ssam 			 */
78917153Sbloom 			mask = sigmask(sig);
79040807Smarc 			p->p_sig |= mask;
79140807Smarc 			if (p->p_sigmask & mask)
79214782Ssam 				continue;
7937421Sroot 		}
79440807Smarc 
79540807Smarc 		/*
79640807Smarc 		 * Decide whether the signal should be returned.
79740807Smarc 		 * Return the signal's number, or fall through
79840807Smarc 		 * to clear it from the pending mask.
79940807Smarc 		 */
80024901Skarels 		switch ((int)u.u_signal[sig]) {
8017421Sroot 
8027421Sroot 		case SIG_DFL:
8037421Sroot 			/*
8047421Sroot 			 * Don't take default actions on system processes.
8057421Sroot 			 */
8067421Sroot 			if (p->p_ppid == 0)
80740807Smarc 				break;		/* == ignore */
80840807Smarc 			/*
80940807Smarc 			 * If there is a pending stop signal to process
81040807Smarc 			 * with default action, stop here,
81142437Skarels 			 * then clear the signal.  However,
81242437Skarels 			 * if process is member of an orphaned
81342437Skarels 			 * process group, ignore tty stop signals.
81440807Smarc 			 */
81539513Skarels 			if (mask & stopsigmask) {
81642437Skarels 				if (p->p_flag&STRC ||
81742437Skarels 		    		    (p->p_pgrp->pg_jobc == 0 &&
81842437Skarels 				    mask & ttystopsigmask))
81940807Smarc 					break;	/* == ignore */
82043895Skarels 				p->p_xstat = sig;
8217421Sroot 				stop(p);
82239513Skarels 				if ((p->p_pptr->p_flag & SNOCLDSTOP) == 0)
82339513Skarels 					psignal(p->p_pptr, SIGCHLD);
8247421Sroot 				swtch();
82540807Smarc 				break;
82639513Skarels 			} else if (mask & defaultignmask) {
8277421Sroot 				/*
82839513Skarels 				 * Except for SIGCONT, shouldn't get here.
82939513Skarels 				 * Default action is to ignore; drop it.
8307421Sroot 				 */
83140807Smarc 				break;		/* == ignore */
83239513Skarels 			} else
83340807Smarc 				return (sig);
8347421Sroot 			/*NOTREACHED*/
8357421Sroot 
8367421Sroot 		case SIG_IGN:
8377421Sroot 			/*
83839513Skarels 			 * Masking above should prevent us ever trying
83939513Skarels 			 * to take action on an ignored signal other
84039513Skarels 			 * than SIGCONT, unless process is traced.
8417421Sroot 			 */
84239513Skarels 			if (sig != SIGCONT && (p->p_flag&STRC) == 0)
8437421Sroot 				printf("issig\n");
84440807Smarc 			break;		/* == ignore */
8457421Sroot 
8467421Sroot 		default:
8477421Sroot 			/*
8487421Sroot 			 * This signal has an action, let
8497421Sroot 			 * psig process it.
8507421Sroot 			 */
85140807Smarc 			return (sig);
8527421Sroot 		}
85340807Smarc 		p->p_sig &= ~mask;		/* take the signal! */
8547421Sroot 	}
85540807Smarc 	/* NOTREACHED */
8567421Sroot }
8577421Sroot 
8587421Sroot /*
8597421Sroot  * Put the argument process into the stopped
86018331Skarels  * state and notify the parent via wakeup.
86118331Skarels  * Signals are handled elsewhere.
86240807Smarc  * The process must not be on the run queue.
8637421Sroot  */
8647421Sroot stop(p)
8657421Sroot 	register struct proc *p;
8667421Sroot {
8677421Sroot 
8687421Sroot 	p->p_stat = SSTOP;
8697421Sroot 	p->p_flag &= ~SWTED;
8707421Sroot 	wakeup((caddr_t)p->p_pptr);
8717421Sroot }
8727421Sroot 
8737421Sroot /*
87440807Smarc  * Perform the action specified by the current signal.
8757421Sroot  * The usual sequence is:
87640807Smarc  *	if (sig = CURSIG(p))
87740807Smarc  *		psig(sig);
8787421Sroot  */
87940807Smarc psig(sig)
88040807Smarc 	register int sig;
8817421Sroot {
88212882Ssam 	register struct proc *p = u.u_procp;
88339513Skarels 	int mask, returnmask;
88439513Skarels 	register sig_t action;
8857421Sroot 
88639513Skarels 	do {
88740807Smarc #ifdef DIAGNOSTIC
88839513Skarels 		if (sig == 0)
88939513Skarels 			panic("psig");
89040807Smarc #endif
89140807Smarc 		mask = sigmask(sig);
89240807Smarc 		p->p_sig &= ~mask;
89339513Skarels 		action = u.u_signal[sig];
89440807Smarc #ifdef KTRACE
89540807Smarc 		if (KTRPOINT(p, KTR_PSIG))
89640807Smarc 			ktrpsig(p->p_tracep, sig, action, p->p_flag & SOMASK ?
89740807Smarc 				u.u_oldmask : p->p_sigmask, 0);
89840807Smarc #endif
89939513Skarels 		if (action != SIG_DFL) {
90039513Skarels #ifdef DIAGNOSTIC
90139513Skarels 			if (action == SIG_IGN || (p->p_sigmask & mask))
90239513Skarels 				panic("psig action");
90339513Skarels #endif
90439513Skarels 			/*
90539513Skarels 			 * Set the new mask value and also defer further
90639513Skarels 			 * occurences of this signal.
90739513Skarels 			 *
90839513Skarels 			 * Special case: user has done a sigpause.  Here the
90939513Skarels 			 * current mask is not of interest, but rather the
91039513Skarels 			 * mask from before the sigpause is what we want
91139513Skarels 			 * restored after the signal processing is completed.
91239513Skarels 			 */
91339513Skarels 			(void) splhigh();
91439513Skarels 			if (p->p_flag & SOMASK) {
91539513Skarels 				returnmask = u.u_oldmask;
91639513Skarels 				p->p_flag &= ~SOMASK;
91739513Skarels 			} else
91839513Skarels 				returnmask = p->p_sigmask;
91939513Skarels 			p->p_sigmask |= u.u_sigmask[sig] | mask;
92039513Skarels 			(void) spl0();
92139513Skarels 			u.u_ru.ru_nsignals++;
92239513Skarels 			sendsig(action, sig, returnmask, 0);
92339513Skarels 			continue;
9247421Sroot 		}
92539513Skarels 		u.u_acflag |= AXSIG;
92639513Skarels 		switch (sig) {
9277421Sroot 
92839513Skarels 		case SIGILL:
92939513Skarels 		case SIGIOT:
93039513Skarels 		case SIGBUS:
93139513Skarels 		case SIGQUIT:
93239513Skarels 		case SIGTRAP:
93339513Skarels 		case SIGEMT:
93439513Skarels 		case SIGFPE:
93539513Skarels 		case SIGSEGV:
93639513Skarels 		case SIGSYS:
93743895Skarels 			u.u_sig = sig;
93839513Skarels 			if (core() == 0)
93939513Skarels 				sig |= WCOREFLAG;
94039513Skarels 		}
94142926Smckusick 		exit(p, W_EXITCODE(0, sig));
94239513Skarels 		/* NOTREACHED */
94340807Smarc 	} while (sig = CURSIG(p));
9447421Sroot }
9457421Sroot 
9467421Sroot /*
94739513Skarels  * Create a core image on the file "core".
9487421Sroot  * It writes UPAGES block of the
9497421Sroot  * user.h area followed by the entire
9507421Sroot  * data+stack segments.
9517421Sroot  */
9527421Sroot core()
9537421Sroot {
95437728Smckusick 	register struct vnode *vp;
95539513Skarels 	register struct proc *p = u.u_procp;
95616692Smckusick 	register struct nameidata *ndp = &u.u_nd;
95737580Smckusick 	struct vattr vattr;
95837580Smckusick 	int error;
9597421Sroot 
96039513Skarels 	if (p->p_svuid != p->p_ruid || p->p_svgid != p->p_rgid)
96137580Smckusick 		return (EFAULT);
96237580Smckusick 	if (ctob(UPAGES + u.u_dsize + u.u_ssize) >=
9638032Sroot 	    u.u_rlimit[RLIMIT_CORE].rlim_cur)
96437580Smckusick 		return (EFAULT);
96539513Skarels 	if (p->p_textp) {
96639513Skarels 		VOP_LOCK(p->p_textp->x_vptr);
96739513Skarels 		error = VOP_ACCESS(p->p_textp->x_vptr, VREAD, u.u_cred);
96839513Skarels 		VOP_UNLOCK(p->p_textp->x_vptr);
96937580Smckusick 		if (error)
97037580Smckusick 			return (EFAULT);
97137580Smckusick 	}
97216692Smckusick 	ndp->ni_segflg = UIO_SYSSPACE;
97316692Smckusick 	ndp->ni_dirp = "core";
97437580Smckusick 	if (error = vn_open(ndp, FCREAT|FWRITE, 0644))
97537580Smckusick 		return (error);
97637580Smckusick 	vp = ndp->ni_vp;
97738394Smckusick 	VOP_LOCK(vp);
97837580Smckusick 	if (vp->v_type != VREG ||
97937728Smckusick 	    VOP_GETATTR(vp, &vattr, u.u_cred) ||
98037580Smckusick 	    vattr.va_nlink != 1) {
98138394Smckusick 		vput(vp);
98238394Smckusick 		return (EFAULT);
9837818Sroot 	}
98442004Smckusick #ifdef MAPMEM
98542926Smckusick 	if (error = mmcore(p)) {
98642926Smckusick 		vput(vp);
98742926Smckusick 		return (error);
98842926Smckusick 	}
98930290Ssam #endif
99041362Smckusick 	VATTR_NULL(&vattr);
99137580Smckusick 	vattr.va_size = 0;
99237728Smckusick 	VOP_SETATTR(vp, &vattr, u.u_cred);
9937818Sroot 	u.u_acflag |= ACORE;
99442004Smckusick #ifdef HPUXCOMPAT
99542004Smckusick 	/*
99642004Smckusick 	 * BLETCH!  If we loaded from an HPUX format binary file
99742004Smckusick 	 * we have to dump an HPUX style user struct so that the
99842004Smckusick 	 * HPUX debuggers can grok it.
99942004Smckusick 	 */
100042004Smckusick 	if (u.u_pcb.pcb_flags & PCB_HPUXBIN)
100142004Smckusick 		error = hpuxdumpu(vp, ndp->ni_cred);
100242004Smckusick 	else
100342004Smckusick #endif
100437580Smckusick 	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&u, ctob(UPAGES), (off_t)0,
100538394Smckusick 	    UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, ndp->ni_cred, (int *)0);
100637580Smckusick 	if (error == 0)
100737580Smckusick 		error = vn_rdwr(UIO_WRITE, vp,
100839513Skarels 		    (caddr_t)ctob(dptov(p, 0)),
100938394Smckusick 		    (int)ctob(u.u_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE,
101038394Smckusick 		    IO_NODELOCKED|IO_UNIT, ndp->ni_cred, (int *)0);
101137580Smckusick 	if (error == 0)
101237580Smckusick 		error = vn_rdwr(UIO_WRITE, vp,
101339513Skarels 		    (caddr_t)ctob(sptov(p, u.u_ssize - 1)),
101426354Skarels 		    (int)ctob(u.u_ssize),
101538394Smckusick 		    (off_t)ctob(UPAGES) + ctob(u.u_dsize), UIO_USERSPACE,
101638394Smckusick 		    IO_NODELOCKED|IO_UNIT, ndp->ni_cred, (int *)0);
101738394Smckusick 	vput(vp);
101837580Smckusick 	return (error);
10197421Sroot }
102039513Skarels 
102139513Skarels /*
102239513Skarels  * Nonexistent system call-- signal process (may want to handle it).
102339513Skarels  * Flag error in case process won't see signal immediately (blocked or ignored).
102439513Skarels  */
102543364Smckusick /* ARGSUSED */
102643364Smckusick nosys(p, args, retval)
102743364Smckusick 	struct proc *p;
102843364Smckusick 	void *args;
102943364Smckusick 	int *retval;
103039513Skarels {
103139513Skarels 
103243364Smckusick 	psignal(p, SIGSYS);
103344405Skarels 	return (EINVAL);
103439513Skarels }
1035