bug fixes from elz and utcsrgv!thomson
[unix-history] / usr / src / sys / kern / kern_proc.c
index 4497220..53cab4f 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_proc.c     4.5     %G%     */
+/*     kern_proc.c     4.25    82/04/02        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -49,26 +49,24 @@ exece()
        char cfname[DIRSIZ];
        char cfarg[SHSIZE];
 
        char cfname[DIRSIZ];
        char cfarg[SHSIZE];
 
-       if ((ip = namei(uchar, 0)) == NULL)
+       if ((ip = namei(uchar, 0, 1)) == NULL)
                return;
                return;
-
        bno = 0;
        bp = 0;
        indir = 0;
        uid = u.u_uid;
        gid = u.u_gid;
        bno = 0;
        bp = 0;
        indir = 0;
        uid = u.u_uid;
        gid = u.u_gid;
-
        if (ip->i_mode & ISUID)
                uid = ip->i_uid;
        if (ip->i_mode & ISGID)
                gid = ip->i_gid;
 
   again:
        if (ip->i_mode & ISUID)
                uid = ip->i_uid;
        if (ip->i_mode & ISGID)
                gid = ip->i_gid;
 
   again:
-       if(access(ip, IEXEC))
+       if (access(ip, IEXEC))
                goto bad;
                goto bad;
-       if((u.u_procp->p_flag&STRC) && access(ip, IREAD))
+       if ((u.u_procp->p_flag&STRC) && access(ip, IREAD))
                goto bad;
                goto bad;
-       if((ip->i_mode & IFMT) != IFREG ||
+       if ((ip->i_mode & IFMT) != IFREG ||
           (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) {
                u.u_error = EACCES;
                goto bad;
           (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) {
                u.u_error = EACCES;
                goto bad;
@@ -94,10 +92,10 @@ exece()
        u.u_segflg = 1;
        readi(ip);
        u.u_segflg = 0;
        u.u_segflg = 1;
        readi(ip);
        u.u_segflg = 0;
-       if(u.u_error)
+       if (u.u_error)
                goto bad;
                goto bad;
-       if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A)
-               && u.u_exdata.ux_shell[0] != '#') {
+       if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A) &&
+           u.u_exdata.ux_shell[0] != '#') {
                u.u_error = ENOEXEC;
                goto bad;
        }
                u.u_error = ENOEXEC;
                goto bad;
        }
@@ -156,7 +154,7 @@ exece()
                bcopy((caddr_t)u.u_dbuf, (caddr_t)cfname, DIRSIZ);
                indir = 1;
                iput(ip);
                bcopy((caddr_t)u.u_dbuf, (caddr_t)cfname, DIRSIZ);
                indir = 1;
                iput(ip);
-               ip = namei(schar, 0);
+               ip = namei(schar, 0, 1);
                if (ip == NULL)
                        return;
                goto again;
                if (ip == NULL)
                        return;
                goto again;
@@ -169,18 +167,15 @@ exece()
        ne = 0;
        nc = 0;
        uap = (struct execa *)u.u_ap;
        ne = 0;
        nc = 0;
        uap = (struct execa *)u.u_ap;
-       if ((bno = malloc(argmap, ctod(clrnd((int) btoc(NCARGS))))) == 0) {
+       if ((bno = rmalloc(argmap, ctod(clrnd((int) btoc(NCARGS))))) == 0) {
                swkill(u.u_procp, "exece");
                goto bad;
        }
        if (bno % CLSIZE)
                swkill(u.u_procp, "exece");
                goto bad;
        }
        if (bno % CLSIZE)
-               panic("execa malloc");
+               panic("execa rmalloc");
        if (uap->argp) for (;;) {
                ap = NULL;
        if (uap->argp) for (;;) {
                ap = NULL;
-               if (na == 1 && indir) {
-                       if (sharg == NULL)
-                               ap = (int)uap->fname;
-               } else if (na == 2 && indir && sharg != NULL)
+               if (indir && (na == 1 || na == 2 && sharg))
                        ap = (int)uap->fname;
                else if (uap->argp) {
                        ap = fuword((caddr_t)uap->argp);
                        ap = (int)uap->fname;
                else if (uap->argp) {
                        ap = fuword((caddr_t)uap->argp);
@@ -196,7 +191,7 @@ exece()
                if (ap==NULL)
                        break;
                na++;
                if (ap==NULL)
                        break;
                na++;
-               if(ap == -1)
+               if (ap == -1)
                        u.u_error = EFAULT;
                do {
                        if (nc >= NCARGS-1)
                        u.u_error = EFAULT;
                do {
                        if (nc >= NCARGS-1)
@@ -244,7 +239,6 @@ badarg:
        /*
         * copy back arglist
         */
        /*
         * copy back arglist
         */
-
        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;
@@ -280,7 +274,7 @@ bad:
        if (bp)
                brelse(bp);
        if (bno)
        if (bp)
                brelse(bp);
        if (bno)
-               mfree(argmap, ctod(clrnd((int) btoc(NCARGS))), bno);
+               rmfree(argmap, ctod(clrnd((int) btoc(NCARGS))), bno);
        iput(ip);
 }
 
        iput(ip);
 }
 
@@ -297,28 +291,32 @@ register struct inode *ip;
                pagi = SPAGI;
        else
                pagi = 0;
                pagi = SPAGI;
        else
                pagi = 0;
-
-       if(u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) {
+       if (u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 &&
+           ip->i_count!=1) {
                register struct file *fp;
 
                register struct file *fp;
 
-               for (fp = file; fp < &file[NFILE]; fp++)
+               for (fp = file; fp < fileNFILE; fp++) {
+                       if (fp->f_flag & FSOCKET)
+                               continue;
                        if (fp->f_inode == ip && (fp->f_flag&FWRITE)) {
                                u.u_error = ETXTBSY;
                                goto bad;
                        }
                        if (fp->f_inode == ip && (fp->f_flag&FWRITE)) {
                                u.u_error = ETXTBSY;
                                goto bad;
                        }
+               }
        }
 
        /*
        }
 
        /*
-        * find text and data sizes
-        * try them out for possible
-        * exceed of max sizes
+        * Compute text and data sizes and make sure not too large.
         */
         */
-
        ts = clrnd(btoc(u.u_exdata.ux_tsize));
        ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
        ss = clrnd(SSIZE + btoc(nargc));
        if (chksize(ts, ds, ss))
                goto bad;
        ts = clrnd(btoc(u.u_exdata.ux_tsize));
        ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
        ss = clrnd(SSIZE + btoc(nargc));
        if (chksize(ts, ds, ss))
                goto bad;
+
+       /*
+        * Make sure enough space to start process.
+        */
        u.u_cdmap = zdmap;
        u.u_csmap = zdmap;
        if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL)
        u.u_cdmap = zdmap;
        u.u_csmap = zdmap;
        if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL)
@@ -343,7 +341,7 @@ register struct inode *ip;
                        sleep((caddr_t)u.u_procp, PZERO - 1);
                u.u_procp->p_flag &= ~(SVFDONE|SKEEP);
        }
                        sleep((caddr_t)u.u_procp, PZERO - 1);
                u.u_procp->p_flag &= ~(SVFDONE|SKEEP);
        }
-       u.u_procp->p_flag &= ~(SPAGI|SANOM|SUANOM|SNUSIG);
+       u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SNUSIG);
        u.u_procp->p_flag |= pagi;
        u.u_dmap = u.u_cdmap;
        u.u_smap = u.u_csmap;
        u.u_procp->p_flag |= pagi;
        u.u_dmap = u.u_cdmap;
        u.u_smap = u.u_csmap;
@@ -371,14 +369,10 @@ register struct inode *ip;
         * set SUID/SGID protections, if no tracing
         */
        if ((u.u_procp->p_flag&STRC)==0) {
         * set SUID/SGID protections, if no tracing
         */
        if ((u.u_procp->p_flag&STRC)==0) {
-#ifndef        MELB
-               if(u.u_uid != 0)
-#endif
-               {
-                       u.u_uid = uid;
-                       u.u_procp->p_uid = uid;
-               }
+               u.u_uid = uid;
+               u.u_procp->p_uid = uid;
                u.u_gid = gid;
                u.u_gid = gid;
+               u.u_grps[gid/(sizeof(int)*8)] |= 1 << (gid%(sizeof(int)*8));
        } else
                psignal(u.u_procp, SIGTRAP);
        u.u_tsize = ts;
        } else
                psignal(u.u_procp, SIGTRAP);
        u.u_tsize = ts;
@@ -395,12 +389,9 @@ setregs()
 {
        register int (**rp)();
        register i;
 {
        register int (**rp)();
        register i;
-#ifdef UCBIPC
-       register struct port *pt;
-#endif UCBIPC
        long sigmask;
 
        long sigmask;
 
-       for(rp = &u.u_signal[0], sigmask = 1L; rp < &u.u_signal[NSIG];
+       for (rp = &u.u_signal[1], sigmask = 1L; rp < &u.u_signal[NSIG];
            sigmask <<= 1, rp++) {
                switch (*rp) {
 
            sigmask <<= 1, rp++) {
                switch (*rp) {
 
@@ -418,7 +409,7 @@ setregs()
                        if ((int)*rp & 1)
                                u.u_procp->p_siga0 |= sigmask;
                        else
                        if ((int)*rp & 1)
                                u.u_procp->p_siga0 |= sigmask;
                        else
-                               u.u_procp->p_siga1 &= ~sigmask;
+                               u.u_procp->p_siga0 &= ~sigmask;
                        if ((int)*rp & 2)
                                u.u_procp->p_siga1 |= sigmask;
                        else
                        if ((int)*rp & 2)
                                u.u_procp->p_siga1 |= sigmask;
                        else
@@ -428,30 +419,18 @@ setregs()
                }
        }
 /*
                }
        }
 /*
-       for(rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
+       for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
                *rp++ = 0;
 */
        u.u_ar0[PC] = u.u_exdata.ux_entloc + 2; /* skip over entry mask */
                *rp++ = 0;
 */
        u.u_ar0[PC] = u.u_exdata.ux_entloc + 2; /* skip over entry mask */
-       for(i=0; i<NOFILE; i++) {
+       for (i=0; i<NOFILE; i++) {
                if (u.u_pofile[i]&EXCLOSE) {
                if (u.u_pofile[i]&EXCLOSE) {
-#ifndef UCBIPC
-                       closef(u.u_ofile[i]);
+                       closef(u.u_ofile[i], 1);
                        u.u_ofile[i] = NULL;
                        u.u_ofile[i] = NULL;
-#else UCBIPC
-                       if (u.u_pofile[i]&ISPORT) {
-                               pt = u.u_oport[i];
-                               if (--pt->pt_count == 0)
-                                       ptclose(pt);
-                               u.u_pofile[i] &= ~ISPORT;
-                               u.u_oport[i] = NULL;
-                       } else {
-                               closef(u.u_ofile[i]);
-                               u.u_ofile[i] = NULL;
-                       }
-#endif UCBIPC
                        u.u_pofile[i] &= ~EXCLOSE;
                }
        }
                        u.u_pofile[i] &= ~EXCLOSE;
                }
        }
+
        /*
         * Remember file name for accounting.
         */
        /*
         * Remember file name for accounting.
         */
@@ -460,8 +439,7 @@ setregs()
 }
 
 /*
 }
 
 /*
- * exit system call:
- * pass back caller's arg
+ * Exit system call: pass back caller's arg
  */
 rexit()
 {
  */
 rexit()
 {
@@ -485,9 +463,6 @@ exit(rv)
        register int i;
        register struct proc *p, *q;
        register struct file *f;
        register int i;
        register struct proc *p, *q;
        register struct file *f;
-#ifdef UCBIPC
-       register struct port *pt;
-#endif UCBIPC
        register int x;
 
 #ifdef PGINPROF
        register int x;
 
 #ifdef PGINPROF
@@ -509,7 +484,7 @@ exit(rv)
        (void) spl0();
        p->p_cpticks = 0;
        p->p_pctcpu = 0;
        (void) spl0();
        p->p_cpticks = 0;
        p->p_pctcpu = 0;
-       for(i=0; i<NSIG; i++)
+       for (i=0; i<NSIG; i++)
                u.u_signal[i] = SIG_IGN;
        /*
         * Release virtual memory.  If we resulted from
                u.u_signal[i] = SIG_IGN;
        /*
         * Release virtual memory.  If we resulted from
@@ -525,36 +500,23 @@ exit(rv)
                        sleep((caddr_t)p, PZERO - 1);
                p->p_flag &= ~SVFDONE;
        }
                        sleep((caddr_t)p, PZERO - 1);
                p->p_flag &= ~SVFDONE;
        }
-       for(i=0; i<NOFILE; i++) {
-#ifndef UCBIPC
+       for (i=0; i<NOFILE; i++) {
                f = u.u_ofile[i];
                u.u_ofile[i] = NULL;
                f = u.u_ofile[i];
                u.u_ofile[i] = NULL;
-               closef(f);
-#else UCBIPC
-               if (u.u_pofile[i]&ISPORT) {
-                       pt = u.u_oport[i];
-                       if (--pt->pt_count == 0)
-                               ptclose(pt);
-                       u.u_oport[i] = NULL;
-               } else {
-                       f = u.u_ofile[i];
-                       u.u_ofile[i] = NULL;
-                       closef(f);
-               }
-#endif UCBIPC
+               closef(f, 1);
        }
        }
-       plock(u.u_cdir);
+       ilock(u.u_cdir);
        iput(u.u_cdir);
        if (u.u_rdir) {
        iput(u.u_cdir);
        if (u.u_rdir) {
-               plock(u.u_rdir);
+               ilock(u.u_rdir);
                iput(u.u_rdir);
        }
        u.u_limit[LIM_FSIZE] = INFINITY;
        acct();
        vrelpt(u.u_procp);
        vrelu(u.u_procp, 0);
                iput(u.u_rdir);
        }
        u.u_limit[LIM_FSIZE] = INFINITY;
        acct();
        vrelpt(u.u_procp);
        vrelu(u.u_procp, 0);
+       (void) spl5();          /* hack for mem alloc race XXX */
        multprog--;
        multprog--;
-/*     spl7();                 /* clock will get mad because of overlaying */
        p->p_stat = SZOMB;
        noproc = 1;
        i = PIDHASH(p->p_pid);
        p->p_stat = SZOMB;
        noproc = 1;
        i = PIDHASH(p->p_pid);
@@ -575,8 +537,8 @@ done:
        ((struct xproc *)p)->xp_xstat = rv;             /* overlay */
        ((struct xproc *)p)->xp_vm = u.u_vm;            /* overlay */
        vmsadd(&((struct xproc *)p)->xp_vm, &u.u_cvm);
        ((struct xproc *)p)->xp_xstat = rv;             /* overlay */
        ((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_pptr == p) {
+       for (q = proc; q < procNPROC; q++)
+               if (q->p_pptr == p) {
                        q->p_pptr = &proc[1];
                        q->p_ppid = 1;
                        wakeup((caddr_t)&proc[1]);
                        q->p_pptr = &proc[1];
                        q->p_ppid = 1;
                        wakeup((caddr_t)&proc[1]);
@@ -597,13 +559,12 @@ done:
                        }
                        /*
                         * Protect this process from future
                        }
                        /*
                         * Protect this process from future
-                        * tty signals, clear TSTP/TTIN/TTOU if pending,
-                        * and set SDETACH bit on procs.
+                        * tty signals, clear TSTP/TTIN/TTOU if pending.
                         */
                        (void) spgrp(q, -1);
                }
                         */
                        (void) spgrp(q, -1);
                }
-       wakeup((caddr_t)p->p_pptr);
        psignal(p->p_pptr, SIGCHLD);
        psignal(p->p_pptr, SIGCHLD);
+       wakeup((caddr_t)p->p_pptr);
        swtch();
 }
 
        swtch();
 }
 
@@ -639,10 +600,10 @@ wait1(options, vp)
 
        f = 0;
 loop:
 
        f = 0;
 loop:
-       for(p = &proc[0]; p < &proc[NPROC]; p++)
-       if(p->p_pptr == u.u_procp) {
+       for (p = proc; p < procNPROC; p++)
+       if (p->p_pptr == u.u_procp) {
                f++;
                f++;
-               if(p->p_stat == SZOMB) {
+               if (p->p_stat == SZOMB) {
                        u.u_r.r_val1 = p->p_pid;
                        u.u_r.r_val2 = ((struct xproc *)p)->xp_xstat;
                        ((struct xproc *)p)->xp_xstat = 0;
                        u.u_r.r_val1 = p->p_pid;
                        u.u_r.r_val2 = ((struct xproc *)p)->xp_xstat;
                        ((struct xproc *)p)->xp_xstat = 0;
@@ -709,7 +670,7 @@ fork1(isvfork)
 
        a = 0;
        p2 = NULL;
 
        a = 0;
        p2 = NULL;
-       for(p1 = &proc[0]; p1 < &proc[NPROC]; p1++) {
+       for (p1 = proc; p1 < procNPROC; p1++) {
                if (p1->p_stat==NULL && p2==NULL)
                        p2 = p1;
                else {
                if (p1->p_stat==NULL && p2==NULL)
                        p2 = p1;
                else {
@@ -723,7 +684,9 @@ fork1(isvfork)
         *  not su and too many procs owned; or
         *  not su and would take last slot.
         */
         *  not su and too many procs owned; or
         *  not su and would take last slot.
         */
-       if (p2==NULL || (u.u_uid!=0 && (p2==&proc[NPROC-1] || a>MAXUPRC))) {
+       if (p2==NULL)
+               tablefull("proc");
+       if (p2==NULL || (u.u_uid!=0 && (p2==procNPROC-1 || a>MAXUPRC))) {
                u.u_error = EAGAIN;
                if (!isvfork) {
                        (void) vsexpand(0, &u.u_cdmap, 1);
                u.u_error = EAGAIN;
                if (!isvfork) {
                        (void) vsexpand(0, &u.u_cdmap, 1);
@@ -732,7 +695,7 @@ fork1(isvfork)
                goto out;
        }
        p1 = u.u_procp;
                goto out;
        }
        p1 = u.u_procp;
-       if(newproc(isvfork)) {
+       if (newproc(isvfork)) {
                u.u_r.r_val1 = p1->p_pid;
                u.u_r.r_val2 = 1;  /* child */
                u.u_start = time;
                u.u_r.r_val1 = p1->p_pid;
                u.u_r.r_val2 = 1;  /* child */
                u.u_start = time;