make sure that the pseudo_set isn't empty.
[unix-history] / sys / kern / kern_sig.c
index c5fecda..54bb672 100644 (file)
@@ -30,7 +30,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)kern_sig.c  7.35 (Berkeley) 6/28/91
+ *     from: @(#)kern_sig.c    7.35 (Berkeley) 6/28/91
+ *     $Id: kern_sig.c,v 1.11 1994/05/05 18:44:13 csgr Exp $
  */
 
 #define        SIGPROP         /* include signal properties table */
  */
 
 #define        SIGPROP         /* include signal properties table */
 #include "resourcevar.h"
 #include "namei.h"
 #include "vnode.h"
 #include "resourcevar.h"
 #include "namei.h"
 #include "vnode.h"
+#include "mount.h"
+#include "filedesc.h"
 #include "proc.h"
 #include "proc.h"
+#include "ucred.h"
 #include "systm.h"
 #include "timeb.h"
 #include "times.h"
 #include "systm.h"
 #include "timeb.h"
 #include "times.h"
@@ -49,6 +53,7 @@
 #include "kernel.h"
 #include "wait.h"
 #include "ktrace.h"
 #include "kernel.h"
 #include "wait.h"
 #include "ktrace.h"
+#include "syslog.h"
 
 #include "machine/cpu.h"
 
 
 #include "machine/cpu.h"
 
 #include "kinfo_proc.h"
 #include "user.h"              /* for coredump */
 
 #include "kinfo_proc.h"
 #include "user.h"              /* for coredump */
 
+static void setsigvec(struct proc *, int, struct sigaction *);
+static void stop(struct proc *);
+static void sigexit(struct proc *, int);
+static int killpg1(struct proc *, int, int, int);
+
 /*
  * Can process p, with pcred pc, send the signal signo to process q?
  */
 /*
  * Can process p, with pcred pc, send the signal signo to process q?
  */
            (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
            ((signo) == SIGCONT && (q)->p_session == (p)->p_session))
 
            (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 */
 /* ARGSUSED */
+int
 sigaction(p, uap, retval)
        struct proc *p;
 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;
        int *retval;
 {
        struct sigaction vec;
@@ -111,6 +124,7 @@ sigaction(p, uap, retval)
        return (0);
 }
 
        return (0);
 }
 
+void
 setsigvec(p, sig, sa)
        register struct proc *p;
        int sig;
 setsigvec(p, sig, sa)
        register struct proc *p;
        int sig;
@@ -218,12 +232,16 @@ execsigs(p)
  * and return old mask as return value;
  * the library stub does the rest.
  */
  * and return old mask as return value;
  * the library stub does the rest.
  */
+
+struct sigprocmask_args {
+       int     how;
+       sigset_t mask;
+};
+
+int
 sigprocmask(p, uap, retval)
        register struct proc *p;
 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;
        int *retval;
 {
        int error = 0;
@@ -253,6 +271,7 @@ sigprocmask(p, uap, retval)
 }
 
 /* ARGSUSED */
 }
 
 /* ARGSUSED */
+int
 sigpending(p, uap, retval)
        struct proc *p;
        void *uap;
 sigpending(p, uap, retval)
        struct proc *p;
        void *uap;
@@ -267,14 +286,18 @@ sigpending(p, uap, retval)
 /*
  * Generalized interface signal handler, 4.3-compatible.
  */
 /*
  * Generalized interface signal handler, 4.3-compatible.
  */
+
+struct osigvec_args {
+       int     signo;
+       struct  sigvec *nsv;
+       struct  sigvec *osv;
+};
+
 /* ARGSUSED */
 /* ARGSUSED */
+int
 osigvec(p, uap, retval)
        struct proc *p;
 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;
        int *retval;
 {
        struct sigvec vec;
@@ -312,11 +335,14 @@ osigvec(p, uap, retval)
        return (0);
 }
 
        return (0);
 }
 
+struct osigblock_args {
+       int     mask;
+};
+
+int
 osigblock(p, uap, retval)
        register struct proc *p;
 osigblock(p, uap, retval)
        register struct proc *p;
-       struct args {
-               int     mask;
-       } *uap;
+       struct osigblock_args *uap;
        int *retval;
 {
 
        int *retval;
 {
 
@@ -327,11 +353,14 @@ osigblock(p, uap, retval)
        return (0);
 }
 
        return (0);
 }
 
+struct osigsetmask_args {
+       int     mask;
+};
+
+int
 osigsetmask(p, uap, retval)
        struct proc *p;
 osigsetmask(p, uap, retval)
        struct proc *p;
-       struct args {
-               int     mask;
-       } *uap;
+       struct osigsetmask_args *uap;
        int *retval;
 {
 
        int *retval;
 {
 
@@ -348,12 +377,16 @@ osigsetmask(p, uap, retval)
  * in the meantime.  Note nonstandard calling convention:
  * libc stub passes mask, not pointer, to save a copyin.
  */
  * in the meantime.  Note nonstandard calling convention:
  * libc stub passes mask, not pointer, to save a copyin.
  */
+
+struct sigsuspend_args {
+       sigset_t mask;
+};
+
 /* ARGSUSED */
 /* ARGSUSED */
+int
 sigsuspend(p, uap, retval)
        register struct proc *p;
 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;
        int *retval;
 {
        register struct sigacts *ps = p->p_sigacts;
@@ -373,13 +406,16 @@ sigsuspend(p, uap, retval)
        return (EINTR);
 }
 
        return (EINTR);
 }
 
+struct sigstack_args {
+       struct  sigstack *nss;
+       struct  sigstack *oss;
+};
+
 /* ARGSUSED */
 /* ARGSUSED */
+int
 sigstack(p, uap, retval)
        struct proc *p;
 sigstack(p, uap, retval)
        struct proc *p;
-       register struct args {
-               struct  sigstack *nss;
-               struct  sigstack *oss;
-       } *uap;
+       register struct sigstack_args *uap;
        int *retval;
 {
        struct sigstack ss;
        int *retval;
 {
        struct sigstack ss;
@@ -394,13 +430,16 @@ sigstack(p, uap, retval)
        return (error);
 }
 
        return (error);
 }
 
+struct kill_args {
+       int     pid;
+       int     signo;
+};
+
 /* ARGSUSED */
 /* ARGSUSED */
+int
 kill(cp, uap, retval)
        register struct proc *cp;
 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;
        int *retval;
 {
        register struct proc *p;
@@ -431,13 +470,17 @@ kill(cp, uap, retval)
 }
 
 #ifdef COMPAT_43
 }
 
 #ifdef COMPAT_43
+
+struct okillpg_args {
+       int     pgid;
+       int     signo;
+};
+
 /* ARGSUSED */
 /* ARGSUSED */
+int
 okillpg(p, uap, retval)
        struct proc *p;
 okillpg(p, uap, retval)
        struct proc *p;
-       register struct args {
-               int     pgid;
-               int     signo;
-       } *uap;
+       register struct okillpg_args *uap;
        int *retval;
 {
 
        int *retval;
 {
 
@@ -451,6 +494,7 @@ okillpg(p, uap, retval)
  * Common code for kill process group/broadcast kill.
  * cp is calling process.
  */
  * Common code for kill process group/broadcast kill.
  * cp is calling process.
  */
+static int
 killpg1(cp, signo, pgid, all)
        register struct proc *cp;
        int signo, pgid, all;
 killpg1(cp, signo, pgid, all)
        register struct proc *cp;
        int signo, pgid, all;
@@ -580,6 +624,10 @@ psignal(p, sig)
        register sig_t action;
        int mask;
 
        register sig_t action;
        int mask;
 
+       /* Ignore signals to system (internal) daemons */
+       if (p->p_flag & SSYS)
+               return;
+
        if ((unsigned)sig >= NSIG || sig == 0)
                panic("psignal sig");
        mask = sigmask(sig);
        if ((unsigned)sig >= NSIG || sig == 0)
                panic("psignal sig");
        mask = sigmask(sig);
@@ -770,6 +818,7 @@ out:
  *     while (sig = CURSIG(curproc))
  *             psig(sig);
  */
  *     while (sig = CURSIG(curproc))
  *             psig(sig);
  */
+int
 issig(p)
        register struct proc *p;
 {
 issig(p)
        register struct proc *p;
 {
@@ -907,6 +956,7 @@ issig(p)
  * Signals are handled elsewhere.
  * The process must not be on the run queue.
  */
  * Signals are handled elsewhere.
  * The process must not be on the run queue.
  */
+static void
 stop(p)
        register struct proc *p;
 {
 stop(p)
        register struct proc *p;
 {
@@ -987,6 +1037,7 @@ psig(sig)
  * If dumping core, save the signal number for the debugger.
  * Calls exit and does not return.
  */
  * If dumping core, save the signal number for the debugger.
  * Calls exit and does not return.
  */
+static void
 sigexit(p, sig)
        register struct proc *p;
        int sig;
 sigexit(p, sig)
        register struct proc *p;
        int sig;
@@ -995,18 +1046,32 @@ sigexit(p, sig)
        p->p_acflag |= AXSIG;
        if (sigprop[sig] & SA_CORE) {
                p->p_sigacts->ps_sig = sig;
        p->p_acflag |= AXSIG;
        if (sigprop[sig] & SA_CORE) {
                p->p_sigacts->ps_sig = sig;
+               /*
+                * Log signals which would cause core dumps
+                * (Log as LOG_INFO to appease those who don't want 
+                * these messages.)
+                * XXX : Todo, as well as euid, write out ruid too
+                */
+               log(LOG_INFO, "pid %d: %s: uid %d: exited on signal %d\n",
+                       p->p_pid, p->p_comm, p->p_ucred->cr_uid, sig);
                if (coredump(p) == 0)
                        sig |= WCOREFLAG;
        }
                if (coredump(p) == 0)
                        sig |= WCOREFLAG;
        }
-       exit(p, W_EXITCODE(0, sig));
+       kexit(p, W_EXITCODE(0, sig));
        /* NOTREACHED */
 }
 
 /*
  * Create a core dump.
        /* NOTREACHED */
 }
 
 /*
  * Create a core dump.
- * The file name is "core.progname".
- * Core dumps are not created if the process is setuid.
+ * The file name is "progname.core".
+ * Core dumps are not created if:
+ *     the process is setuid,
+ *     we are on a filesystem mounted with MNT_NOCORE,
+ *     a file already exists and is not a core file,
+ *             or was not produced from the same program,
+ *     the link count to the corefile is > 1.
  */
  */
+int
 coredump(p)
        register struct proc *p;
 {
 coredump(p)
        register struct proc *p;
 {
@@ -1015,9 +1080,9 @@ coredump(p)
        register struct ucred *cred = pcred->pc_ucred;
        register struct vmspace *vm = p->p_vmspace;
        struct vattr vattr;
        register struct ucred *cred = pcred->pc_ucred;
        register struct vmspace *vm = p->p_vmspace;
        struct vattr vattr;
-       int error, error1;
+       int error, error1, exists;
        struct nameidata nd;
        struct nameidata nd;
-       char name[MAXCOMLEN+6]; /* core.progname */
+       char name[MAXCOMLEN+6]; /* progname.core */
 
        if (pcred->p_svuid != pcred->p_ruid ||
            pcred->p_svgid != pcred->p_rgid)
 
        if (pcred->p_svuid != pcred->p_ruid ||
            pcred->p_svgid != pcred->p_rgid)
@@ -1025,10 +1090,19 @@ coredump(p)
        if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
            p->p_rlimit[RLIMIT_CORE].rlim_cur)
                return (EFAULT);
        if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
            p->p_rlimit[RLIMIT_CORE].rlim_cur)
                return (EFAULT);
-       sprintf(name, "core.%s", p->p_comm);
+       if (p->p_fd->fd_cdir->v_mount->mnt_flag & MNT_NOCORE)
+               return (EFAULT);
+
+       sprintf(name, "%s.core", p->p_comm);
        nd.ni_dirp = name;
        nd.ni_segflg = UIO_SYSSPACE;
        nd.ni_dirp = name;
        nd.ni_segflg = UIO_SYSSPACE;
-       if (error = vn_open(&nd, p, O_CREAT|FWRITE, 0644))
+       if ((error = vn_open(&nd, p, FWRITE, 0600)) == 0)
+               exists = 1;
+       else
+               exists = 0;
+       if (error == ENOENT)
+               error = vn_open(&nd, p, O_CREAT | FWRITE, 0600);
+       if (error)
                return (error);
        vp = nd.ni_vp;
        if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred, p) ||
                return (error);
        vp = nd.ni_vp;
        if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred, p) ||
@@ -1036,6 +1110,19 @@ coredump(p)
                error = EFAULT;
                goto out;
        }
                error = EFAULT;
                goto out;
        }
+       if (exists) {   /* if file already exists, look if it's a coredump */
+           struct user userbuf;        /* XXX */
+           error = vn_rdwr(UIO_READ, vp, (caddr_t)&userbuf, sizeof(userbuf),
+               (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred,
+               (int *)NULL, p);
+           if (error || (vattr.va_size != ctob(UPAGES + 
+                       userbuf.u_kproc.kp_eproc.e_vm.vm_dsize +
+                       userbuf.u_kproc.kp_eproc.e_vm.vm_ssize)) ||
+                       strcmp(p->p_comm, userbuf.u_kproc.kp_proc.p_comm)) {
+               error = EFAULT;
+               goto out;
+               }
+       }
        VATTR_NULL(&vattr);
        vattr.va_size = 0;
        VOP_SETATTR(vp, &vattr, cred, p);
        VATTR_NULL(&vattr);
        vattr.va_size = 0;
        VOP_SETATTR(vp, &vattr, cred, p);
@@ -1079,6 +1166,7 @@ out:
  * Flag error in case process won't see signal immediately (blocked or ignored).
  */
 /* ARGSUSED */
  * Flag error in case process won't see signal immediately (blocked or ignored).
  */
 /* ARGSUSED */
+int
 nosys(p, args, retval)
        struct proc *p;
        void *args;
 nosys(p, args, retval)
        struct proc *p;
        void *args;