(no message)
[unix-history] / usr / src / sys / kern / kern_proc.c
index 04d1a52..16ab001 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_proc.c     3.2     %H%     */
+/*     kern_proc.c     3.7     %H%     */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/inode.h"
 #include "../h/seg.h"
 #include "../h/acct.h"
 #include "../h/inode.h"
 #include "../h/seg.h"
 #include "../h/acct.h"
+#include <wait.h>
 #include "../h/pte.h"
 #include "../h/vm.h"
 #include "../h/text.h"
 #include "../h/pte.h"
 #include "../h/vm.h"
 #include "../h/text.h"
+#include "../h/psl.h"
 
 /*
  * exec system call, with and without environments.
 
 /*
  * exec system call, with and without environments.
@@ -127,17 +129,17 @@ badarg:
        ucp = USRSTACK - nc - NBPW;
        ap = ucp - na*NBPW - 3*NBPW;
        u.u_ar0[SP] = ap;
        ucp = USRSTACK - nc - NBPW;
        ap = ucp - na*NBPW - 3*NBPW;
        u.u_ar0[SP] = ap;
-       VOID suword((caddr_t)ap, na-ne);
+       (void) suword((caddr_t)ap, na-ne);
        nc = 0;
        for (;;) {
                ap += NBPW;
                if (na==ne) {
        nc = 0;
        for (;;) {
                ap += NBPW;
                if (na==ne) {
-                       VOID suword((caddr_t)ap, 0);
+                       (void) suword((caddr_t)ap, 0);
                        ap += NBPW;
                }
                if (--na < 0)
                        break;
                        ap += NBPW;
                }
                if (--na < 0)
                        break;
-               VOID suword((caddr_t)ap, ucp);
+               (void) suword((caddr_t)ap, ucp);
                do {
                        if ((nc&BMASK) == 0) {
                                if (bp)
                do {
                        if ((nc&BMASK) == 0) {
                                if (bp)
@@ -147,12 +149,12 @@ badarg:
                                bp->b_flags &= ~B_DELWRI;       /* cancel io */
                                cp = bp->b_un.b_addr;
                        }
                                bp->b_flags &= ~B_DELWRI;       /* cancel io */
                                cp = bp->b_un.b_addr;
                        }
-                       VOID subyte((caddr_t)ucp++, (c = *cp++));
+                       (void) subyte((caddr_t)ucp++, (c = *cp++));
                        nc++;
                } while(c&0377);
        }
                        nc++;
                } while(c&0377);
        }
-       VOID suword((caddr_t)ap, 0);
-       VOID suword((caddr_t)ucp, 0);
+       (void) suword((caddr_t)ap, 0);
+       (void) suword((caddr_t)ucp, 0);
        setregs();
 bad:
        if (bp)
        setregs();
 bad:
        if (bp)
@@ -324,7 +326,7 @@ register struct inode *ip;
                        if(ip->i_mode&ISGID)
                                u.u_gid = ip->i_gid;
                } else
                        if(ip->i_mode&ISGID)
                                u.u_gid = ip->i_gid;
                } else
-                       psignal(u.u_procp, SIGTRC);
+                       psignal(u.u_procp, SIGTRAP);
        }
        u.u_tsize = ts;
        u.u_dsize = ds;
        }
        u.u_tsize = ts;
        u.u_dsize = ds;
@@ -339,12 +341,37 @@ bad:
  */
 setregs()
 {
  */
 setregs()
 {
-       register int *rp;
+       register int (**rp)();
        register i;
        register i;
+       long sigmask;
 
 
-       for(rp = &u.u_signal[0]; rp < &u.u_signal[NSIG]; rp++)
-               if((*rp & 1) == 0)
-                       *rp = 0;
+       for(rp = &u.u_signal[0], sigmask = 1L; rp < &u.u_signal[NSIG];
+           sigmask <<= 1, rp++) {
+               switch (*rp) {
+
+               case SIG_IGN:
+               case SIG_DFL:
+               case SIG_HOLD:
+                       continue;
+
+               default:
+                       /*
+                        * Normal or deferring catch; revert to default.
+                        */
+                       (void) spl6();
+                       *rp = SIG_DFL;
+                       if ((int)*rp & 1)
+                               u.u_procp->p_siga0 |= sigmask;
+                       else
+                               u.u_procp->p_siga1 &= ~sigmask;
+                       if ((int)*rp & 2)
+                               u.u_procp->p_siga1 |= sigmask;
+                       else
+                               u.u_procp->p_siga1 &= ~sigmask;
+                       (void) spl0();
+                       continue;
+               }
+       }
 /*
        for(rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
                *rp++ = 0;
 /*
        for(rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
                *rp++ = 0;
@@ -354,8 +381,8 @@ setregs()
                if (u.u_pofile[i]&EXCLOSE) {
                        closef(u.u_ofile[i]);
                        u.u_ofile[i] = NULL;
                if (u.u_pofile[i]&EXCLOSE) {
                        closef(u.u_ofile[i]);
                        u.u_ofile[i] = NULL;
+                       u.u_pofile[i] &= ~EXCLOSE;
                }
                }
-               u.u_pofile[i] &= ~EXCLOSE;
        }
        /*
         * Remember file name for accounting.
        }
        /*
         * Remember file name for accounting.
@@ -399,10 +426,20 @@ exit(rv)
        p->p_flag &= ~(STRC|SULOCK);
        p->p_flag |= SWEXIT;
        p->p_clktim = 0;
        p->p_flag &= ~(STRC|SULOCK);
        p->p_flag |= SWEXIT;
        p->p_clktim = 0;
+       (void) spl6();
+       if ((int)SIG_IGN & 1)
+               p->p_siga0 = ~0;
+       else
+               p->p_siga0 = 0;
+       if ((int)SIG_IGN & 2)
+               p->p_siga1 = ~0;
+       else
+               p->p_siga1 = 0;
+       (void) spl0();
        rate.v_pgin -= p->p_aveflt;
        p->p_aveflt = 0;
        for(i=0; i<NSIG; i++)
        rate.v_pgin -= p->p_aveflt;
        p->p_aveflt = 0;
        for(i=0; i<NSIG; i++)
-               u.u_signal[i] = 1;
+               u.u_signal[i] = SIG_IGN;
        /*
         * Release virtual memory.  If we resulted from
         * a vfork(), instead give the resources back to
        /*
         * Release virtual memory.  If we resulted from
         * a vfork(), instead give the resources back to
@@ -451,22 +488,51 @@ done:
        ((struct xproc *)p)->xp_vm = u.u_vm;            /* overlay */
        vmsadd(&((struct xproc *)p)->xp_vm, &u.u_cvm);
        for(q = &proc[0]; q < &proc[NPROC]; q++)
        ((struct xproc *)p)->xp_vm = u.u_vm;            /* overlay */
        vmsadd(&((struct xproc *)p)->xp_vm, &u.u_cvm);
        for(q = &proc[0]; q < &proc[NPROC]; q++)
-               if(q->p_ppid == p->p_pid) {
-                       wakeup((caddr_t)&proc[1]);
+               if(q->p_pptr == p) {
+                       q->p_pptr = &proc[1];
                        q->p_ppid = 1;
                        q->p_ppid = 1;
-                       if (q->p_stat==SSTOP)
-                               setrun(q);
+                       wakeup((caddr_t)&proc[1]);
+                       /*
+                        * Traced processes are killed
+                        * since their existence means someone is screwing up.
+                        * Traced processes are sent a hangup and a continue.
+                        * This is designed to be ``safe'' for setuid
+                        * processes since they must be willing to tolerate
+                        * hangups anyways.
+                        */
+                       if (q->p_flag&STRC) {
+                               q->p_flag &= ~STRC;
+                               psignal(q, SIGKILL);
+                       } else if (q->p_stat == SSTOP) {
+                               psignal(q, SIGHUP);
+                               psignal(q, SIGCONT);
+                               /*
+                                * Protect this process from future
+                                * tty signals, and clear TSTP if pending.
+                                */
+                               q->p_pgrp = 0;
+                               q->p_sig &= ~(1<<(SIGTSTP-1));
+                       }
                }
                }
-       q = pfind(p->p_ppid);
-       if (q)
-               wakeup((caddr_t)q);
+       wakeup((caddr_t)p->p_pptr);
+       psignal(p->p_pptr, SIGCHLD);
        swtch();
 }
 
 wait()
 {
        swtch();
 }
 
 wait()
 {
+       struct vtimes vm;
+       struct vtimes *vp;
 
 
-       wait1((struct vtimes *)0);
+       if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) {
+               wait1(0, (struct vtimes *)0);
+               return;
+       }
+       vp = (struct vtimes *)u.u_ar0[R1];
+       wait1(u.u_ar0[R0], &vm);
+       if (u.u_error)
+               return;
+       (void) copyout((caddr_t)&vm, (caddr_t)vp, sizeof (struct vtimes));
 }
 
 /*
 }
 
 /*
@@ -476,17 +542,17 @@ wait()
  * Look also for stopped (traced) children,
  * and pass back status from them.
  */
  * Look also for stopped (traced) children,
  * and pass back status from them.
  */
-wait1(vp)
+wait1(options, vp)
+       register options;
        struct vtimes *vp;
 {
        register f;
        register struct proc *p;
 
        f = 0;
        struct vtimes *vp;
 {
        register f;
        register struct proc *p;
 
        f = 0;
-
 loop:
        for(p = &proc[0]; p < &proc[NPROC]; p++)
 loop:
        for(p = &proc[0]; p < &proc[NPROC]; p++)
-       if(p->p_ppid == u.u_procp->p_pid) {
+       if(p->p_pptr == u.u_procp) {
                f++;
                if(p->p_stat == SZOMB) {
                        u.u_r.r_val1 = p->p_pid;
                f++;
                if(p->p_stat == SZOMB) {
                        u.u_r.r_val1 = p->p_pid;
@@ -499,27 +565,40 @@ loop:
                        p->p_stat = NULL;
                        p->p_pid = 0;
                        p->p_ppid = 0;
                        p->p_stat = NULL;
                        p->p_pid = 0;
                        p->p_ppid = 0;
+                       p->p_pptr = 0;
                        p->p_sig = 0;
                        p->p_sig = 0;
+                       p->p_siga0 = 0;
+                       p->p_siga1 = 0;
                        p->p_pgrp = 0;
                        p->p_flag = 0;
                        p->p_wchan = 0;
                        p->p_pgrp = 0;
                        p->p_flag = 0;
                        p->p_wchan = 0;
+                       p->p_cursig = 0;
                        return;
                }
                        return;
                }
-               if(p->p_stat == SSTOP) {
-                       if((p->p_flag&SWTED) == 0) {
-                               p->p_flag |= SWTED;
-                               u.u_r.r_val1 = p->p_pid;
-                               u.u_r.r_val2 = (fsig(p)<<8) | 0177;
-                               return;
-                       }
-                       continue;
+               if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 &&
+                   (p->p_flag&STRC || options&WUNTRACED)) {
+                       p->p_flag |= SWTED;
+                       u.u_r.r_val1 = p->p_pid;
+                       u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED;
+                       return;
                }
        }
                }
        }
-       if(f) {
-               sleep((caddr_t)u.u_procp, PWAIT);
-               goto loop;
+       if (f==0) {
+               u.u_error = ECHILD;
+               return;
+       }
+       if (options&WNOHANG) {
+               u.u_r.r_val1 = 0;
+               return;
        }
        }
-       u.u_error = ECHILD;
+/*
+       if (setjmp(u.u_qsav)) {
+               u.u_eosys = RESTARTSYS;
+               return;
+       }
+*/
+       sleep((caddr_t)u.u_procp, PWAIT);
+       goto loop;
 }
 
 /*
 }
 
 /*
@@ -561,8 +640,8 @@ fork1(isvfork)
        if (p2==NULL || (u.u_uid!=0 && (p2==&proc[NPROC-1] || a>MAXUPRC))) {
                u.u_error = EAGAIN;
                if (!isvfork) {
        if (p2==NULL || (u.u_uid!=0 && (p2==&proc[NPROC-1] || a>MAXUPRC))) {
                u.u_error = EAGAIN;
                if (!isvfork) {
-                       VOID vsexpand(0, &u.u_cdmap, 1);
-                       VOID vsexpand(0, &u.u_csmap, 1);
+                       (void) vsexpand(0, &u.u_cdmap, 1);
+                       (void) vsexpand(0, &u.u_csmap, 1);
                }
                goto out;
        }
                }
                goto out;
        }