Annotation of researchv10no/sys/os/sys1.c, revision 1.1.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.