Annotation of researchv10no/sys/os/sys1.c, revision 1.1

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/systm.h"
        !             3: #include "sys/map.h"
        !             4: #include "sys/mtpr.h"
        !             5: #include "sys/user.h"
        !             6: #include "sys/proc.h"
        !             7: #include "sys/buf.h"
        !             8: #include "sys/reg.h"
        !             9: #include "sys/inode.h"
        !            10: #include "sys/acct.h"
        !            11: #include "/usr/include/wait.h"
        !            12: #include "sys/pte.h"
        !            13: #include "sys/vm.h"
        !            14: #include "sys/text.h"
        !            15: #include "sys/psl.h"
        !            16: #include "sys/vlimit.h"
        !            17: #include "sys/file.h"
        !            18: 
        !            19: /*
        !            20:  * exec system call
        !            21:  */
        !            22: struct execa {
        !            23:        char    *fname;
        !            24:        char    **argp;
        !            25:        char    **envp;
        !            26: };
        !            27: 
        !            28: struct shdata {
        !            29:        char            sd_save[DIRSIZ];
        !            30:        int             sd_gid;
        !            31:        int             sd_uid;
        !            32:        int             sd_indir;
        !            33:        char            sd_flag[SHSIZE];
        !            34: };
        !            35: 
        !            36: struct swargs {
        !            37:        char            *sw_cp;
        !            38:        int             sw_argc;
        !            39:        int             sw_envc;
        !            40:        int             sw_chars;
        !            41:        int             sw_bn;
        !            42:        struct buf      *sw_bp;
        !            43: };
        !            44: 
        !            45: void
        !            46: str_stash(s, sp)
        !            47: register char          *s;
        !            48: register struct swargs *sp;
        !            49: {
        !            50:        register char   *cp;
        !            51:        register int    nc;
        !            52:        register int    bmask;
        !            53: 
        !            54:        cp = sp->sw_cp;
        !            55:        nc = sp->sw_chars;
        !            56:        bmask = BMASK(argdev);
        !            57: 
        !            58:        do {
        !            59:                if ((nc & bmask) == 0) {
        !            60:                        if (nc >= NCARGS) {
        !            61:                                u.u_error = E2BIG;
        !            62:                                return;
        !            63:                        }
        !            64:                        if (sp->sw_bp != NULL)
        !            65:                                bdwrite(sp->sw_bp);
        !            66:                        sp->sw_bp = getblk(argdev, (daddr_t)(dbtofsb(argdev,
        !            67:                                        sp->sw_bn) + (nc>>BSHIFT(argdev))));
        !            68:                        cp = sp->sw_bp->b_un.b_addr;
        !            69:                }
        !            70:                nc++;
        !            71:        } while ((*cp++ = *s++) != '\0');
        !            72: 
        !            73:        sp->sw_chars = nc;
        !            74:        sp->sw_cp = cp;
        !            75:        sp->sw_argc++;
        !            76: }
        !            77: 
        !            78: int
        !            79: vec_stash(v, sp)
        !            80: register char          **v;
        !            81: register struct swargs *sp;
        !            82: {
        !            83:        register char   *s;
        !            84:        register int    nc;
        !            85:        register int    nleft;
        !            86:        register int    i;
        !            87:        int             bsize;
        !            88:        int             count;
        !            89:        int             ap;
        !            90: 
        !            91:        if (v == NULL)
        !            92:                return 0;
        !            93: 
        !            94:        nc = sp->sw_chars;
        !            95:        bsize = BSIZE(argdev);
        !            96:        nleft = ((nc + bsize-1) & ~(bsize-1)) - nc;
        !            97:        count = 0;
        !            98: 
        !            99:        for (;;) {
        !           100:                if ((ap = fuword((caddr_t)v++)) < 0) {
        !           101:                        u.u_error = EFAULT;
        !           102:                        return 0;
        !           103:                }
        !           104:                if ((s = (char *)ap) == NULL)
        !           105:                        break;
        !           106:                if ((i = fustrlen(s)) < 0) {
        !           107:                        u.u_error = EFAULT;
        !           108:                        return 0;
        !           109:                }
        !           110:                while (i > nleft) {
        !           111:                        if (sp->sw_bp) {
        !           112:                                bcopy(s, sp->sw_cp, nleft);
        !           113:                                s += nleft;
        !           114:                                nc += nleft;
        !           115:                                i -= nleft;
        !           116:                                if (nc >= NCARGS) {
        !           117:                                        u.u_error = E2BIG;
        !           118:                                        return 0;
        !           119:                                }
        !           120:                                bdwrite(sp->sw_bp);
        !           121:                        }
        !           122:                        sp->sw_bp = getblk(argdev, (daddr_t)(dbtofsb(argdev,
        !           123:                                        sp->sw_bn) + (nc>>BSHIFT(argdev))));
        !           124:                        sp->sw_cp = sp->sw_bp->b_un.b_addr;
        !           125:                        nleft = bsize;
        !           126:                }
        !           127:                bcopy(s, sp->sw_cp, i);
        !           128:                sp->sw_cp += i;
        !           129:                nc += i;
        !           130:                nleft -= i;
        !           131:                count++;
        !           132:        }
        !           133:        sp->sw_chars = nc;
        !           134:        sp->sw_argc += count;
        !           135:        return count;
        !           136: }
        !           137: 
        !           138: exece()
        !           139: {
        !           140:        register int            i;
        !           141:        register int            ap;
        !           142:        register int            bsize;
        !           143:        register char           *cp;
        !           144:        register char           *ucp;
        !           145:        register struct execa   *uap;
        !           146:        struct buf              *bp;
        !           147:        struct inode            *ip;
        !           148:        struct shdata           sh;
        !           149:        struct swargs           sw;
        !           150:        extern struct map argmap[];
        !           151:        extern struct inode     *gethead();
        !           152: 
        !           153:        uap = (struct execa *)u.u_ap;
        !           154:        sh.sd_uid = u.u_uid;
        !           155:        sh.sd_gid = u.u_gid;
        !           156:        sh.sd_indir = 0;
        !           157:        sh.sd_flag[0] = '\0';
        !           158:        if ((ip = gethead(uap->fname, &sh)) == NULL)
        !           159:                return;
        !           160: 
        !           161:        sw.sw_argc = 0;
        !           162:        sw.sw_chars = 0;
        !           163:        sw.sw_bp = NULL;
        !           164:        bsize = BSIZE(argdev);
        !           165:        if ((sw.sw_bn = rmalloc(argmap, ctod(clrnd((int)btoc(NCARGS))))) == 0) {
        !           166:                swkill(u.u_procp, "exece");
        !           167:                iput(ip);
        !           168:                return;
        !           169:        }
        !           170:        if (sw.sw_bn % CLSIZE)
        !           171:                panic("exece rmalloc");
        !           172:        if (sh.sd_indir) {
        !           173:                if ((ap = fuword((caddr_t)uap->argp)) < 0){
        !           174:                        u.u_error = EFAULT;
        !           175:                        goto out;
        !           176:                }
        !           177:                if (ap) {
        !           178:                        uap->argp++;
        !           179:                        if (fustrlen((char *)ap) < 0) {
        !           180:                                u.u_error = EFAULT;
        !           181:                                goto out;
        !           182:                        }
        !           183:                        /*
        !           184:                         * improper assumption
        !           185:                         * ap is a user address;
        !           186:                         * str_stash assumes kernel-accessible
        !           187:                         */
        !           188:                        str_stash((char *)ap, &sw);
        !           189:                }
        !           190:                if (sh.sd_flag[0] != '\0')
        !           191:                        str_stash(sh.sd_flag, &sw);
        !           192:                str_stash(uap->fname, &sw);
        !           193:        }
        !           194:        vec_stash(uap->argp, &sw);
        !           195:        sw.sw_envc = vec_stash(uap->envp, &sw);
        !           196:        bp = sw.sw_bp;
        !           197:        if (bp) {
        !           198:                bdwrite(bp);
        !           199:                bp = NULL;
        !           200:        }
        !           201: 
        !           202:        if (u.u_error)
        !           203:                goto out;
        !           204: 
        !           205:        sw.sw_chars = (sw.sw_chars + NBPW-1) & ~(NBPW-1);
        !           206:        /* 4: argc, null after args, null after env, null after everything,  */
        !           207:        getxfile(ip, sw.sw_chars + (sw.sw_argc+4)*NBPW, sh.sd_uid, sh.sd_gid);
        !           208: 
        !           209:        if (u.u_error)
        !           210:                goto out;
        !           211: 
        !           212:        iput(ip);
        !           213:        ucp = (char *)(USRSTACK - sw.sw_chars - NBPW);
        !           214:        ap = (int)ucp - (sw.sw_argc + 3) * NBPW;
        !           215:        u.u_ar0[SP] = ap;
        !           216:        *(int *)ap = sw.sw_argc - sw.sw_envc;
        !           217: 
        !           218:        for (i = 0, cp = ucp; sw.sw_chars > 0; i++, cp += bsize, sw.sw_chars -= bsize) {
        !           219:                if (bp)
        !           220:                        brelse(bp);
        !           221:                bp = bread(argdev, (daddr_t)(dbtofsb(argdev, sw.sw_bn)+i));
        !           222:                bcopy(bp->b_un.b_addr, cp, min(bsize, sw.sw_chars));    
        !           223:                bp->b_flags |= B_AGE;
        !           224:                bp->b_flags &= ~B_DELWRI;
        !           225:        }
        !           226: 
        !           227:        if (bp)
        !           228:                brelse(bp);
        !           229: 
        !           230:        for (cp = ucp; ; cp += fustrlen(cp)) {
        !           231:                ap += NBPW;
        !           232:                if (sw.sw_argc == sw.sw_envc)
        !           233:                        ap += NBPW;
        !           234:                if (--sw.sw_argc < 0)
        !           235:                        break;
        !           236:                *(char **)ap = cp;
        !           237:        }
        !           238:        setregs(sh.sd_save);
        !           239:        rmfree(argmap, ctod(clrnd((int) btoc(NCARGS))), sw.sw_bn);
        !           240:        return;
        !           241: 
        !           242: out:
        !           243:        iput(ip);
        !           244:        for (i = (((sw.sw_chars+bsize-1)&~(bsize-1))>>BSHIFT(argdev))-1;
        !           245:             i >= 0; i--) {
        !           246:                bp = getblk(argdev, (daddr_t)(dbtofsb(argdev, sw.sw_bn)+i));
        !           247:                bp->b_flags |= B_AGE;
        !           248:                bp->b_flags &= ~B_DELWRI;
        !           249:                brelse(bp);
        !           250:        }
        !           251:        rmfree(argmap, ctod(clrnd((int) btoc(NCARGS))), sw.sw_bn);
        !           252: }
        !           253: 
        !           254: /*
        !           255:  *     Get a shell after #! magic number.
        !           256:  */
        !           257: struct inode   *
        !           258: getshell(ip, sp)
        !           259: struct inode   *ip;
        !           260: struct shdata  *sp;
        !           261: {
        !           262:        register char           *cp, *fname;
        !           263:        extern struct inode     *gethead();
        !           264: 
        !           265:        if(u.u_exdata.ux_shell[0] != '#' || u.u_exdata.ux_shell[1] != '!' || sp->sd_indir)
        !           266:                goto error;
        !           267:        cp = &u.u_exdata.ux_shell[2];
        !           268:        for (;;) {
        !           269:                if (cp == &u.u_exdata.ux_shell[SHSIZE])
        !           270:                        goto error;
        !           271:                if (*cp == '\n') {
        !           272:                        *cp = '\0';
        !           273:                        break;
        !           274:                }
        !           275:                if (*cp == '\t')
        !           276:                        *cp = ' ';
        !           277:                cp++;
        !           278:        }
        !           279:        for (cp = &u.u_exdata.ux_shell[2]; *cp == ' '; cp++);
        !           280:        if (*cp == '\0')
        !           281:                goto error;
        !           282:        fname = cp;
        !           283:        while (*cp != '\0') {
        !           284:                if (*cp == ' ') {
        !           285:                        *cp++ = '\0';
        !           286:                        while (*cp == ' ')
        !           287:                                cp++;
        !           288:                        /*
        !           289:                         *      Shell argument (one only).
        !           290:                         */
        !           291:                        if (*cp != '\0') {
        !           292:                                register int    i;
        !           293: 
        !           294:                                i = 0;
        !           295:                                do
        !           296:                                        sp->sd_flag[i++] = *cp++;
        !           297:                                while (*cp != ' ' && *cp != '\0');
        !           298:                                sp->sd_flag[i] = '\0';
        !           299:                        }
        !           300:                        break;
        !           301:                }
        !           302:                else
        !           303:                        cp++;
        !           304:        }
        !           305:        iput(ip);
        !           306:        sp->sd_indir = 1;
        !           307:        return gethead(fname, sp);
        !           308: 
        !           309: error:
        !           310:        iput(ip);
        !           311:        u.u_error = ENOEXEC;
        !           312:        return NULL;
        !           313: }
        !           314: 
        !           315: /*
        !           316:  *     Get the header of an executable and do all the right tests.
        !           317:  */
        !           318: struct inode   *
        !           319: gethead(fname, sp)
        !           320: char *fname;
        !           321: struct shdata  *sp;
        !           322: {
        !           323:        register struct inode   *ip;
        !           324:        struct argnamei nmarg;
        !           325: 
        !           326:        nmarg = nilargnamei;
        !           327:        if(sp->sd_indir == 0) {
        !           328:                nmarg.un.buf = (caddr_t)sp->sd_save;
        !           329:                nmarg.len = sizeof(sp->sd_save);
        !           330:                if((ip = namei(fname, SEGUDATA, &nmarg, 1)) == NULL)
        !           331:                        return NULL;
        !           332:        }
        !           333:        else if((ip = namei(fname, SEGSYS, &nmarg, 1)) == NULL)
        !           334:                return NULL;
        !           335: 
        !           336:        /*
        !           337:         *      Setuid and setgid denied for network root.
        !           338:         */
        !           339:        if (!(ip->i_mode & ICONC)) {
        !           340:                if ((ip->i_mode & ISUID) != 0 && ip->i_uid != -1)
        !           341:                        sp->sd_uid = ip->i_uid;
        !           342: 
        !           343:                if ((ip->i_mode & ISGID) != 0 && ip->i_gid != -1)
        !           344:                        sp->sd_gid = ip->i_gid;
        !           345:        }
        !           346: 
        !           347:        /*
        !           348:         *      Check permission.  May not trace something we can't read.
        !           349:         */
        !           350:        if(access(ip, IEXEC) || (PTRACED(u.u_procp) && access(ip, IREAD)))
        !           351:                goto out;
        !           352: 
        !           353:        /*
        !           354:         *      Must be a regular file and must really be executable.
        !           355:         */
        !           356:        if ((ip->i_mode & IFMT) != IFREG ||
        !           357:            (ip->i_mode & (IEXEC | (IEXEC >> 3) | (IEXEC >> 6))) == 0) {
        !           358:                u.u_error = EACCES;
        !           359:                goto out;
        !           360:        }
        !           361: 
        !           362:        /*
        !           363:         * ux_mag = 407/410/413
        !           364:         *      407 is plain executable
        !           365:         *      410 is RO text
        !           366:         *      413 is demand paged RO text
        !           367:         *
        !           368:         * Also an ASCII line beginning with #! is
        !           369:         * the file name of a ``shell'' and arguments may be prepended
        !           370:         * to the argument list if given here.
        !           371:         *
        !           372:         * Shell names are limited in length.
        !           373:         *
        !           374:         * Only one argument may be passed to the shell from the ASCII line.
        !           375:         */
        !           376:        u.u_base = (caddr_t)&u.u_exdata;
        !           377:        u.u_count = sizeof(u.u_exdata);
        !           378:        u.u_offset = ltoL(0);
        !           379:        u.u_segflg = SEGSYS;
        !           380:        readi(ip);
        !           381:        u.u_segflg = SEGUDATA;
        !           382: 
        !           383:        if (u.u_error)
        !           384:                goto out;
        !           385: 
        !           386:        if (u.u_count > sizeof (u.u_exdata) - sizeof (u.u_exdata.Ux_A))
        !           387:                ip = getshell(ip, sp);
        !           388:        else {
        !           389:                switch (u.u_exdata.ux_mag) {
        !           390:                case 0407:
        !           391:                        u.u_exdata.ux_dsize += u.u_exdata.ux_tsize;
        !           392:                        u.u_exdata.ux_tsize = 0;
        !           393:                        break;
        !           394: 
        !           395:                case 0410:
        !           396:                case 0413:
        !           397:                        if (u.u_exdata.ux_tsize == 0)
        !           398:                                u.u_error = ENOEXEC;
        !           399:                        break;
        !           400: 
        !           401:                default:
        !           402:                        ip = getshell(ip, sp);
        !           403:                }
        !           404:        }
        !           405: 
        !           406: out:
        !           407:        if (u.u_error && ip != NULL) {
        !           408:                iput(ip);
        !           409:                ip = NULL;
        !           410:        }
        !           411: 
        !           412:        return ip;
        !           413: }
        !           414: 
        !           415: /*
        !           416:  * Read in and set up memory for executed file.
        !           417:  */
        !           418: getxfile(ip, nargc, uid, gid)
        !           419: register struct inode *ip;
        !           420: {
        !           421:        register clicks_t ts, ds, ss;
        !           422:        int pagi;
        !           423: 
        !           424:        /* for now, no paging off alternate file systems */
        !           425:        if (u.u_exdata.ux_mag == 0413 && !BITFS(ip->i_dev) && !ip->i_fstyp)
        !           426:                pagi = SPAGI;
        !           427:        else
        !           428:                pagi = 0;
        !           429:        /* never demand-page if process is traced (panic pagein mfind) */
        !           430:        if (PTRACED(u.u_procp))
        !           431:                pagi = 0;
        !           432: 
        !           433:        if(u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) {
        !           434:                register struct file *fp;
        !           435: 
        !           436:                for (fp = file; fp < fileNFILE; fp++)
        !           437:                        if (fp->f_count && fp->f_inode==ip
        !           438:                         && (fp->f_flag&FWRITE)) {
        !           439:                                u.u_error = ETXTBSY;
        !           440:                                goto bad;
        !           441:                        }
        !           442:        }
        !           443: 
        !           444:        /*
        !           445:         * find text and data sizes
        !           446:         * try them out for possible
        !           447:         * exceed of max sizes
        !           448:         */
        !           449: 
        !           450:        ts = clrnd(btoc(u.u_exdata.ux_tsize));
        !           451:        ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
        !           452:        ss = clrnd(SSIZE + btoc(nargc));
        !           453:        if (chksize(ts, ds, ss))
        !           454:                goto bad;
        !           455:        u.u_cdmap = zdmap;
        !           456:        u.u_csmap = zdmap;
        !           457:        if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL)
        !           458:                goto bad;
        !           459: 
        !           460:        /*
        !           461:         * At this point, committed to the new image!
        !           462:         * Release virtual memory resources of old process, and
        !           463:         * initialize the virtual memory of the new process.
        !           464:         */
        !           465:        u.u_prof.pr_scale = 0;
        !           466:        vrelvm();
        !           467:        u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM);
        !           468:        u.u_procp->p_flag |= pagi;
        !           469:        u.u_dmap = u.u_cdmap;
        !           470:        u.u_smap = u.u_csmap;
        !           471:        vgetvm(ts, ds, ss);
        !           472: 
        !           473:        if (pagi == 0) {
        !           474:                /*
        !           475:                 * Read in data segment.
        !           476:                 */
        !           477:                u.u_base = (char *)ctob(ts);
        !           478:                if(u.u_exdata.ux_mag != 0413)
        !           479:                        u.u_offset = ltoL(sizeof(u.u_exdata)+u.u_exdata.ux_tsize);
        !           480:                else    /* stupid 1k 0413 files */
        !           481:                        u.u_offset = ltoL(BSIZE(0) + u.u_exdata.ux_tsize);
        !           482:                u.u_count = u.u_exdata.ux_dsize;
        !           483:                readi(ip);
        !           484:        }
        !           485:        xalloc(ip, pagi);
        !           486:        if (pagi && u.u_procp->p_textp)
        !           487:                vinifod((struct fpte *)dptopte(u.u_procp, 0),
        !           488:                    u.u_procp->p_textp->x_iptr,
        !           489:                    1 + ts/CLSIZE, (int)btoc(u.u_exdata.ux_dsize));
        !           490: 
        !           491:        /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
        !           492:        mtpr(TBIA, 0);
        !           493: 
        !           494:        /*
        !           495:         * set SUID/SGID protections, if no tracing
        !           496:         */
        !           497:        if (!PTRACED(u.u_procp)) {
        !           498:                u.u_uid = uid;
        !           499:                u.u_procp->p_uid = uid;
        !           500:                u.u_gid = gid;
        !           501:        }
        !           502:        if (u.u_procp->p_flag&SSEXEC)
        !           503:                psignal(u.u_procp, SIGSTOP);
        !           504:        u.u_tsize = ts;
        !           505:        u.u_dsize = ds;
        !           506:        u.u_ssize = ss;
        !           507: bad:
        !           508:        return;
        !           509: }
        !           510: 
        !           511: /*
        !           512:  * Reset context on exec
        !           513:  */
        !           514: setregs(comm)
        !           515: char *comm;
        !           516: {
        !           517:        register i;
        !           518:        register int (*f)();
        !           519: 
        !           520:        for (i = 0; i < NSIG; i++) {
        !           521:                if ((f = u.u_signal[i]) == SIG_DFL
        !           522:                ||  f == SIG_IGN || f == SIG_HOLD)
        !           523:                        continue;
        !           524:                spl6();         /* needed? */
        !           525:                u.u_signal[i] = SIG_DFL;
        !           526:                P_SETDFL(u.u_procp, SIGMASK(i));
        !           527:                spl0();
        !           528:        }
        !           529: /*
        !           530:        for(rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
        !           531:                *rp++ = 0;
        !           532: */
        !           533:        u.u_ar0[PC] = u.u_exdata.ux_entloc + 2; /* skip over entry mask */
        !           534:        for(i=0; i<NOFILE; i++) {
        !           535:                if (u.u_pofile[i]&EXCLOSE) {
        !           536:                        closef(u.u_ofile[i]);
        !           537:                        u.u_ofile[i] = NULL;
        !           538:                        u.u_pofile[i] &= ~EXCLOSE;
        !           539:                }
        !           540:        }
        !           541:        /*
        !           542:         * Remember file name for accounting.
        !           543:         */
        !           544:        u.u_acflag &= ~AFORK;
        !           545:        bcopy((caddr_t)comm, (caddr_t)u.u_comm, sizeof(u.u_comm));
        !           546: }
        !           547: 
        !           548: /*
        !           549:  * exit system call:
        !           550:  * pass back caller's arg
        !           551:  */
        !           552: rexit()
        !           553: {
        !           554:        register struct a {
        !           555:                int     rval;
        !           556:        } *uap;
        !           557: 
        !           558:        uap = (struct a *)u.u_ap;
        !           559:        exit((uap->rval & 0377) << 8);
        !           560: }
        !           561: 
        !           562: /*
        !           563:  * Release resources.
        !           564:  * Save u. area for parent to look at.
        !           565:  * Enter zombie state.
        !           566:  * Wake up parent and init processes,
        !           567:  * and dispose of children.
        !           568:  */
        !           569: exit(rv)
        !           570: {
        !           571:        register int i;
        !           572:        register struct proc *p, *q;
        !           573:        register struct file *f;
        !           574: 
        !           575:        vmsizmon();
        !           576:        p = u.u_procp;
        !           577:        p->p_flag &= ~(STRC|SULOCK);
        !           578:        p->p_flag |= SWEXIT;
        !           579:        p->p_clktim = 0;
        !           580:        (void) spl6();
        !           581:        p->p_siga0 = p->p_siga1 = 0;
        !           582:        p->p_ignsig = ~0;               /* magic: ignore all */
        !           583:        (void) spl0();
        !           584:        p->p_cpticks = 0;
        !           585:        p->p_pctcpu = 0;
        !           586:        for(i=0; i<NSIG; i++)
        !           587:                u.u_signal[i] = SIG_IGN;
        !           588:        vrelvm();
        !           589:        for(i=0; i<NOFILE; i++) {
        !           590:                if ((f = u.u_ofile[i]) == NULL)
        !           591:                        continue;
        !           592:                u.u_ofile[i] = NULL;
        !           593:                closef(f);
        !           594:        }
        !           595:        plock(u.u_cdir);
        !           596:        iput(u.u_cdir);
        !           597:        if (u.u_rdir) {
        !           598:                plock(u.u_rdir);
        !           599:                iput(u.u_rdir);
        !           600:        }
        !           601:        u.u_limit[LIM_FSIZE] = INFINITY;
        !           602:        acct();
        !           603:        vrelpt(u.u_procp);
        !           604:        vrelu(u.u_procp, 0);
        !           605:        p->p_stat = SZOMB;
        !           606:        noproc = 1;
        !           607:        if (p->p_pid < SYSPIDS)
        !           608:                printf("process %d died\n", p->p_pid);
        !           609: done:
        !           610:        ((struct xproc *)p)->xp_xstat = rv;             /* overlay */
        !           611:        ((struct xproc *)p)->xp_vm = u.u_vm;            /* overlay */
        !           612:        vmsadd(&((struct xproc *)p)->xp_vm, &u.u_cvm);
        !           613:        for(q = proc; q < procNPROC; q++)
        !           614:                if (q->p_stat != 0 && q->p_pptr == p) {
        !           615:                        q->p_pptr = &proc[INITPID];
        !           616:                        q->p_ppid = 1;
        !           617:                        wakeup((caddr_t)&proc[INITPID]);
        !           618:                        /*
        !           619:                         * Traced processes are killed
        !           620:                         * since their existence means someone is screwing up.
        !           621:                         * this is probably wrong now
        !           622:                         * Stopped processes are sent a hangup and a continue.
        !           623:                         * This is designed to be ``safe'' for setuid
        !           624:                         * processes since they must be willing to tolerate
        !           625:                         * hangups anyways.
        !           626:                         */
        !           627:                        if (q->p_flag&STRC) {
        !           628:                                q->p_flag &= ~STRC;
        !           629:                                psignal(q, SIGKILL);
        !           630:                        } else if (q->p_stat == SSTOP) {
        !           631:                                psignal(q, SIGHUP);
        !           632:                                psignal(q, SIGCONT);
        !           633:                        }
        !           634:                        (void) spgrp(q, -1);
        !           635:                }
        !           636:        wakeup((caddr_t)p->p_pptr);
        !           637:        if (p->p_trace)
        !           638:                wakeup((caddr_t)p->p_trace);
        !           639:        psignal(p->p_pptr, SIGCHLD);
        !           640:        swtch();
        !           641: }
        !           642: 
        !           643: wait()
        !           644: {
        !           645:        struct vtimes vm;
        !           646:        struct vtimes *vp;
        !           647: 
        !           648:        if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) {
        !           649:                wait1(0, (struct vtimes *)0);
        !           650:                return;
        !           651:        }
        !           652:        vp = (struct vtimes *)u.u_ar0[R1];
        !           653:        wait1(u.u_ar0[R0], &vm);
        !           654:        if (u.u_error)
        !           655:                return;
        !           656:        (void) copyout((caddr_t)&vm, (caddr_t)vp, sizeof (struct vtimes));
        !           657: }
        !           658: 
        !           659: /*
        !           660:  * Wait system call.
        !           661:  * Search for a terminated (zombie) child,
        !           662:  * finally lay it to rest, and collect its status.
        !           663:  * Look also for stopped (traced) children,
        !           664:  * and pass back status from them.
        !           665:  */
        !           666: wait1(options, vp)
        !           667:        register options;
        !           668:        struct vtimes *vp;
        !           669: {
        !           670:        register f;
        !           671:        register struct proc *p;
        !           672:        register struct proc *myp;      /* optimization */
        !           673: 
        !           674:        f = 0;
        !           675:        myp = u.u_procp;
        !           676: loop:
        !           677:        for(p = proc; p < procNPROC; p++) {
        !           678:                if (p->p_stat == 0 || p->p_pptr != myp)
        !           679:                        continue;
        !           680:                f++;
        !           681:                if(p->p_stat == SZOMB) {
        !           682:                        u.u_r.r_val1 = p->p_pid;
        !           683:                        u.u_r.r_val2 = ((struct xproc *)p)->xp_xstat;
        !           684:                        if (vp)
        !           685:                                *vp = ((struct xproc *)p)->xp_vm;
        !           686:                        vmsadd(&u.u_cvm, &((struct xproc *)p)->xp_vm);
        !           687:                        p->p_stat = 0;
        !           688:                        /* if it mattered, we could bzero(p, sizeof(*p)) here */
        !           689:                        if (p == procNPROC - 1) {
        !           690:                                do
        !           691:                                        --p;
        !           692:                                while (p->p_stat == 0);
        !           693:                                procNPROC = p + 1;
        !           694:                        }
        !           695:                        return;
        !           696:                }
        !           697:                if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 &&
        !           698:                    (p->p_flag&STRC)==0) {
        !           699:                        p->p_flag |= SWTED;
        !           700:                        u.u_r.r_val1 = p->p_pid;
        !           701:                        u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED;
        !           702:                        return;
        !           703:                }
        !           704:        }
        !           705:        if (f==0) {
        !           706:                u.u_error = ECHILD;
        !           707:                return;
        !           708:        }
        !           709:        if (options&WNOHANG) {
        !           710:                u.u_r.r_val1 = 0;
        !           711:                return;
        !           712:        }
        !           713:        sleep((caddr_t)myp, PWAIT);
        !           714:        goto loop;
        !           715: }
        !           716: 
        !           717: /*
        !           718:  * fork system call.
        !           719:  */
        !           720: fork()
        !           721: {
        !           722:        register struct proc *p1, *p2;
        !           723:        register int a, pid;
        !           724:        static int mpid = 0;
        !           725: 
        !           726:        u.u_cdmap = zdmap;
        !           727:        u.u_csmap = zdmap;
        !           728:        if (swpexpand(u.u_dsize, u.u_ssize, &u.u_cdmap, &u.u_csmap) == 0)
        !           729:                goto out;
        !           730: retry:
        !           731:        pid = ++mpid;
        !           732:        if (pid > MAXPID)
        !           733:                pid = mpid = 1;
        !           734:        a = 0;
        !           735:        p2 = NULL;
        !           736:        for(p1 = proc; p1 < procNPROC; p1++) {
        !           737:                if (p1->p_stat == 0) {
        !           738:                        if (p2 == NULL)
        !           739:                                p2 = p1;
        !           740:                        continue;
        !           741:                }
        !           742:                if (p1->p_pid == pid || p1->p_pgrp == pid)
        !           743:                        goto retry;
        !           744:                if (p1->p_uid == u.u_uid)
        !           745:                        a++;
        !           746:        }
        !           747:        if (p2 == NULL) {       /* try pushing up high water mark */
        !           748:                for (; p1 < &proc[proccnt]; p1++)
        !           749:                        if (p1->p_stat == 0) {
        !           750:                                p2 = p1;
        !           751:                                p1++;
        !           752:                                break;
        !           753:                        }
        !           754:                procNPROC = p1;
        !           755:        }
        !           756:        /*
        !           757:         * Disallow if
        !           758:         *  No processes at all;
        !           759:         *  not su and too many procs owned; or
        !           760:         *  not su and would take last slot.
        !           761:         */
        !           762:        if (p2==NULL)
        !           763:                tablefull("proc");
        !           764:        if (p2==NULL || (u.u_uid!=0 && (p2==&proc[proccnt-1] || a>MAXUPRC))) {
        !           765:                u.u_error = EAGAIN;
        !           766:                (void) vsexpand(0, &u.u_cdmap, 1);
        !           767:                (void) vsexpand(0, &u.u_csmap, 1);
        !           768:                goto out;
        !           769:        }
        !           770:        p1 = u.u_procp;
        !           771:        if(newproc(p2, pid)) {
        !           772:                u.u_r.r_val1 = p1->p_pid;
        !           773:                u.u_r.r_val2 = 1;  /* child */
        !           774:                u.u_start = time;
        !           775:                u.u_acflag = AFORK;
        !           776:                u.u_nbadio = 0;
        !           777:                return;
        !           778:        }
        !           779:        u.u_r.r_val1 = pid;
        !           780: out:
        !           781:        u.u_r.r_val2 = 0;
        !           782: }
        !           783: 
        !           784: /*
        !           785:  * break system call.
        !           786:  *  -- bad planning: "break" is a dirty word in C.
        !           787:  */
        !           788: sbreak()
        !           789: {
        !           790:        struct a {
        !           791:                char    *nsiz;
        !           792:        };
        !           793:        register int n, d;
        !           794: 
        !           795:        /*
        !           796:         * set n to new data size
        !           797:         * set d to new-old
        !           798:         */
        !           799: 
        !           800:        n = btoc(((struct a *)u.u_ap)->nsiz);
        !           801: #if NOTDEF
        !           802:        if (!u.u_sep)
        !           803: #endif
        !           804:                n -= ctos(u.u_tsize) * stoc(1);
        !           805:        if (n < 0)
        !           806:                n = 0;
        !           807:        d = clrnd(n - u.u_dsize);
        !           808:        if (ctob(u.u_dsize+d) > u.u_limit[LIM_DATA]) {
        !           809:                u.u_error = ENOMEM;
        !           810:                return;
        !           811:        }
        !           812:        if (chksize(u.u_tsize, u.u_dsize+d, u.u_ssize))
        !           813:                return;
        !           814:        if (swpexpand(u.u_dsize+d, u.u_ssize, &u.u_dmap, &u.u_smap)==0)
        !           815:                return;
        !           816:        expand(d, P0BR);
        !           817: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.