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