X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/79583d0df86efc00385a90f7049a15705019a8dd..a18538c92b3fbcaa835cae4bc38a5b50faa13519:/usr/src/sys/kern/kern_sig.c diff --git a/usr/src/sys/kern/kern_sig.c b/usr/src/sys/kern/kern_sig.c index a36218bc2f..9a2fc94217 100644 --- a/usr/src/sys/kern/kern_sig.c +++ b/usr/src/sys/kern/kern_sig.c @@ -4,7 +4,7 @@ * * %sccs.include.redist.c% * - * @(#)kern_sig.c 7.33 (Berkeley) %G% + * @(#)kern_sig.c 7.50 (Berkeley) %G% */ #define SIGPROP /* include signal properties table */ @@ -18,7 +18,6 @@ #include "timeb.h" #include "times.h" #include "buf.h" -#include "seg.h" #include "acct.h" #include "file.h" #include "kernel.h" @@ -42,14 +41,15 @@ (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \ ((signo) == SIGCONT && (q)->p_session == (p)->p_session)) +struct sigaction_args { + int signo; + struct sigaction *nsa; + struct sigaction *osa; +}; /* ARGSUSED */ sigaction(p, uap, retval) struct proc *p; - register struct args { - int signo; - struct sigaction *nsa; - struct sigaction *osa; - } *uap; + register struct sigaction_args *uap; int *retval; { struct sigaction vec; @@ -109,6 +109,12 @@ setsigvec(p, sig, sa) ps->ps_sigonstack |= bit; else ps->ps_sigonstack &= ~bit; +#ifdef COMPAT_SUNOS + if (sa->sa_flags & SA_USERTRAMP) + ps->ps_usertramp |= bit; + else + ps->ps_usertramp &= ~bit; +#endif if (sig == SIGCHLD) { if (sa->sa_flags & SA_NOCLDSTOP) p->p_flag |= SNOCLDSTOP; @@ -182,9 +188,10 @@ execsigs(p) * Reset stack state to the user stack. * Clear set of signals caught on the signal stack. */ - ps->ps_onstack = 0; - ps->ps_sigsp = 0; - ps->ps_sigonstack = 0; + ps->ps_sigstk.ss_flags = SA_DISABLE; + ps->ps_sigstk.ss_size = 0; + ps->ps_sigstk.ss_base = 0; + ps->ps_flags = 0; } /* @@ -193,12 +200,13 @@ execsigs(p) * and return old mask as return value; * the library stub does the rest. */ +struct sigprocmask_args { + int how; + sigset_t mask; +}; sigprocmask(p, uap, retval) register struct proc *p; - struct args { - int how; - sigset_t mask; - } *uap; + struct sigprocmask_args *uap; int *retval; { int error = 0; @@ -227,10 +235,13 @@ sigprocmask(p, uap, retval) return (error); } +struct sigpending_args { + int dummy; +}; /* ARGSUSED */ sigpending(p, uap, retval) struct proc *p; - void *uap; + struct sigpending_args *uap; int *retval; { @@ -238,18 +249,19 @@ sigpending(p, uap, retval) return (0); } -#ifdef COMPAT_43 +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) /* * Generalized interface signal handler, 4.3-compatible. */ +struct osigvec_args { + int signo; + struct sigvec *nsv; + struct sigvec *osv; +}; /* ARGSUSED */ osigvec(p, uap, retval) struct proc *p; - register struct args { - int signo; - struct sigvec *nsv; - struct sigvec *osv; - } *uap; + register struct osigvec_args *uap; int *retval; { struct sigvec vec; @@ -271,8 +283,10 @@ osigvec(p, uap, retval) sv->sv_flags |= SV_ONSTACK; if ((ps->ps_sigintr & bit) != 0) sv->sv_flags |= SV_INTERRUPT; +#ifndef COMPAT_SUNOS if (p->p_flag & SNOCLDSTOP) sv->sv_flags |= SA_NOCLDSTOP; +#endif if (error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec))) return (error); @@ -281,17 +295,28 @@ osigvec(p, uap, retval) if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec))) return (error); +#ifdef COMPAT_SUNOS + /* + * SunOS uses this bit (4, aka SA_DISABLE) as SV_RESETHAND, + * `reset to SIG_DFL on delivery'. We have no such option + * now or ever! + */ + if (sv->sv_flags & SA_DISABLE) + return (EINVAL); + sv->sv_flags |= SA_USERTRAMP; +#endif sv->sv_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */ setsigvec(p, sig, (struct sigaction *)sv); } return (0); } +struct osigblock_args { + int mask; +}; osigblock(p, uap, retval) register struct proc *p; - struct args { - int mask; - } *uap; + struct osigblock_args *uap; int *retval; { @@ -302,11 +327,12 @@ osigblock(p, uap, retval) return (0); } +struct osigsetmask_args { + int mask; +}; osigsetmask(p, uap, retval) struct proc *p; - struct args { - int mask; - } *uap; + struct osigsetmask_args *uap; int *retval; { @@ -316,19 +342,20 @@ osigsetmask(p, uap, retval) (void) spl0(); return (0); } -#endif +#endif /* COMPAT_43 || COMPAT_SUNOS */ /* * Suspend process until signal, providing mask to be set * in the meantime. Note nonstandard calling convention: * libc stub passes mask, not pointer, to save a copyin. */ +struct sigsuspend_args { + sigset_t mask; +}; /* ARGSUSED */ sigsuspend(p, uap, retval) register struct proc *p; - struct args { - sigset_t mask; - } *uap; + struct sigsuspend_args *uap; int *retval; { register struct sigacts *ps = p->p_sigacts; @@ -337,45 +364,95 @@ sigsuspend(p, uap, retval) * When returning from sigpause, we want * the old mask to be restored after the * signal handler has finished. Thus, we - * save it here and mark the proc structure - * to indicate this (should be in sigacts). + * save it here and mark the sigacts structure + * to indicate this. */ ps->ps_oldmask = p->p_sigmask; - ps->ps_flags |= SA_OLDMASK; + ps->ps_flags |= SAS_OLDMASK; p->p_sigmask = uap->mask &~ sigcantmask; (void) tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0); /* always return EINTR rather than ERESTART... */ return (EINTR); } +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) +struct osigstack_args { + struct sigstack *nss; + struct sigstack *oss; +}; /* ARGSUSED */ -sigstack(p, uap, retval) +osigstack(p, uap, retval) struct proc *p; - register struct args { - struct sigstack *nss; - struct sigstack *oss; - } *uap; + register struct osigstack_args *uap; int *retval; { struct sigstack ss; + struct sigacts *psp; int error = 0; - if (uap->oss && (error = copyout((caddr_t)&p->p_sigacts->ps_sigstack, - (caddr_t)uap->oss, sizeof (struct sigstack)))) + psp = p->p_sigacts; + ss.ss_sp = psp->ps_sigstk.ss_base; + ss.ss_onstack = psp->ps_sigstk.ss_flags & SA_ONSTACK; + if (uap->oss && (error = copyout((caddr_t)&ss, (caddr_t)uap->oss, + sizeof (struct sigstack)))) return (error); if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss, - sizeof (ss))) == 0) - p->p_sigacts->ps_sigstack = ss; + sizeof (ss))) == 0) { + psp->ps_sigstk.ss_base = ss.ss_sp; + psp->ps_sigstk.ss_size = 0; + psp->ps_sigstk.ss_flags |= ss.ss_onstack & SA_ONSTACK; + psp->ps_flags |= SAS_ALTSTACK; + } return (error); } +#endif /* COMPAT_43 || COMPAT_SUNOS */ + +struct sigaltstack_args { + struct sigaltstack *nss; + struct sigaltstack *oss; +}; +/* ARGSUSED */ +sigaltstack(p, uap, retval) + struct proc *p; + register struct sigaltstack_args *uap; + int *retval; +{ + struct sigacts *psp; + struct sigaltstack ss; + int error; + + psp = p->p_sigacts; + if ((psp->ps_flags & SAS_ALTSTACK) == 0) + psp->ps_sigstk.ss_flags |= SA_DISABLE; + if (uap->oss && (error = copyout((caddr_t)&psp->ps_sigstk, + (caddr_t)uap->oss, sizeof (struct sigaltstack)))) + return (error); + if (uap->nss == 0) + return (0); + if (error = copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss))) + return (error); + if (ss.ss_flags & SA_DISABLE) { + if (psp->ps_sigstk.ss_flags & SA_ONSTACK) + return (EINVAL); + psp->ps_flags &= ~SAS_ALTSTACK; + psp->ps_sigstk.ss_flags = ss.ss_flags; + return (0); + } + if (ss.ss_size < MINSIGSTKSZ) + return (ENOMEM); + psp->ps_flags |= SAS_ALTSTACK; + psp->ps_sigstk= ss; + return (0); +} +struct kill_args { + int pid; + int signo; +}; /* ARGSUSED */ kill(cp, uap, retval) register struct proc *cp; - register struct args { - int pid; - int signo; - } *uap; + register struct kill_args *uap; int *retval; { register struct proc *p; @@ -405,14 +482,15 @@ kill(cp, uap, retval) /* NOTREACHED */ } -#ifdef COMPAT_43 +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) +struct okillpg_args { + int pgid; + int signo; +}; /* ARGSUSED */ okillpg(p, uap, retval) struct proc *p; - register struct args { - int pgid; - int signo; - } *uap; + register struct okillpg_args *uap; int *retval; { @@ -420,7 +498,7 @@ okillpg(p, uap, retval) return (EINVAL); return (killpg1(p, uap->signo, uap->pgid, 0)); } -#endif +#endif /* COMPAT_43 || COMPAT_SUNOS */ /* * Common code for kill process group/broadcast kill. @@ -439,7 +517,7 @@ killpg1(cp, signo, pgid, all) /* * broadcast */ - for (p = allproc; p != NULL; p = p->p_nxt) { + for (p = (struct proc *)allproc; p != NULL; p = p->p_nxt) { if (p->p_pid <= 1 || p->p_flag&SSYS || p == cp || !CANSIGNAL(cp, pc, p, signo)) continue; @@ -460,7 +538,7 @@ killpg1(cp, signo, pgid, all) } for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) { if (p->p_pid <= 1 || p->p_flag&SSYS || - !CANSIGNAL(cp, pc, p, signo)) + p->p_stat == SZOMB || !CANSIGNAL(cp, pc, p, signo)) continue; nfound++; if (signo) @@ -820,8 +898,17 @@ issig(p) /* * Don't take default actions on system processes. */ - if (p->p_pid <= 1) + if (p->p_pid <= 1) { +#ifdef DIAGNOSTIC + /* + * Are you sure you want to ignore SIGSEGV + * in init? XXX + */ + printf("Process (pid %d) got signal %d\n", + p->p_pid, sig); +#endif break; /* == ignore */ + } /* * If there is a pending stop signal to process * with default action, stop here, @@ -909,7 +996,7 @@ psig(sig) action = ps->ps_sigact[sig]; #ifdef KTRACE if (KTRPOINT(p, KTR_PSIG)) - ktrpsig(p->p_tracep, sig, action, ps->ps_flags & SA_OLDMASK ? + ktrpsig(p->p_tracep, sig, action, ps->ps_flags & SAS_OLDMASK ? ps->ps_oldmask : p->p_sigmask, 0); #endif if (action == SIG_DFL) { @@ -937,9 +1024,9 @@ psig(sig) * restored after the signal processing is completed. */ (void) splhigh(); - if (ps->ps_flags & SA_OLDMASK) { + if (ps->ps_flags & SAS_OLDMASK) { returnmask = ps->ps_oldmask; - ps->ps_flags &= ~SA_OLDMASK; + ps->ps_flags &= ~SAS_OLDMASK; } else returnmask = p->p_sigmask; p->p_sigmask |= ps->ps_catchmask[sig] | mask; @@ -975,7 +1062,7 @@ sigexit(p, sig) /* * Create a core dump. - * The file name is "core.progname.pid". + * The file name is "core.progname". * Core dumps are not created if the process is setuid. */ coredump(p) @@ -988,7 +1075,7 @@ coredump(p) struct vattr vattr; int error, error1; struct nameidata nd; - char name[MAXCOMLEN+12]; /* core.progname.pid */ + char name[MAXCOMLEN+6]; /* core.progname */ if (pcred->p_svuid != pcred->p_ruid || pcred->p_svgid != pcred->p_rgid) @@ -996,10 +1083,9 @@ coredump(p) if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >= p->p_rlimit[RLIMIT_CORE].rlim_cur) return (EFAULT); - sprintf(name, "core.%s.%d", p->p_comm, p->p_pid); - nd.ni_dirp = name; - nd.ni_segflg = UIO_SYSSPACE; - if (error = vn_open(&nd, p, O_CREAT|FWRITE, 0644)) + sprintf(name, "core.%s", p->p_comm); + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p); + if (error = vn_open(&nd, O_CREAT|FWRITE, 0644)) return (error); vp = nd.ni_vp; if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred, p) || @@ -1009,23 +1095,12 @@ coredump(p) } VATTR_NULL(&vattr); vattr.va_size = 0; + LEASE_CHECK(vp, p, cred, LEASE_WRITE); VOP_SETATTR(vp, &vattr, cred, p); p->p_acflag |= ACORE; bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc)); fill_eproc(p, &p->p_addr->u_kproc.kp_eproc); -#ifdef HPUXCOMPAT - /* - * BLETCH! If we loaded from an HPUX format binary file - * we have to dump an HPUX style user struct so that the - * HPUX debuggers can grok it. - */ - if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXBIN) - error = hpuxdumpu(vp, cred); - else -#endif - error = vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES), - (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, - p); + error = cpu_coredump(p, vp, cred); if (error == 0) error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr, (int)ctob(vm->vm_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE, @@ -1039,7 +1114,7 @@ coredump(p) out: VOP_UNLOCK(vp); error1 = vn_close(vp, FWRITE, cred, p); - if (!error) + if (error == 0) error = error1; return (error); } @@ -1048,10 +1123,13 @@ out: * Nonexistent system call-- signal process (may want to handle it). * Flag error in case process won't see signal immediately (blocked or ignored). */ +struct nosys_args { + int dummy; +}; /* ARGSUSED */ nosys(p, args, retval) struct proc *p; - void *args; + struct nosys_args *args; int *retval; {