Annotation of coherent/d/286_KERNEL/USRSRC/coh/exec.c, revision 1.1

1.1     ! root        1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/exec.c,v 1.1 92/01/09 13:26:47 bin Exp Locker: bin $ */
        !             2: /* (lgl-
        !             3:  *     The information contained herein is a trade secret of Mark Williams
        !             4:  *     Company, and  is confidential information.  It is provided  under a
        !             5:  *     license agreement,  and may be  copied or disclosed  only under the
        !             6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !             7:  *     material without the express written authorization of Mark Williams
        !             8:  *     Company or persuant to the license agreement is unlawful.
        !             9:  *
        !            10:  *     COHERENT Version 2.3.37
        !            11:  *     Copyright (c) 1982, 1983, 1984.
        !            12:  *     An unpublished work by Mark Williams Company, Chicago.
        !            13:  *     All rights reserved.
        !            14:  -lgl) */
        !            15: /*
        !            16:  * Coherent.
        !            17:  * Exec and driver load code.
        !            18:  *
        !            19:  * $Log:       exec.c,v $
        !            20:  * Revision 1.1  92/01/09  13:26:47  bin
        !            21:  * Initial revision
        !            22:  * 
        !            23:  * Revision 1.1        88/03/24  16:13:39      src
        !            24:  * Initial revision
        !            25:  * 
        !            26:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/exec.c
        !            27:  * Exsread() initializes the (new) (IO).io_flag field to 0.
        !            28:  */
        !            29: #include <sys/coherent.h>
        !            30: #include <acct.h>
        !            31: #include <sys/buf.h>
        !            32: #include <canon.h>
        !            33: #include <sys/con.h>
        !            34: #include <errno.h>
        !            35: #include <sys/filsys.h>
        !            36: #include <sys/ino.h>
        !            37: #include <sys/inode.h>
        !            38: #include <l.out.h>
        !            39: #include <sys/proc.h>
        !            40: #include <sys/seg.h>
        !            41: #include <signal.h>
        !            42: #include <sys/uproc.h>
        !            43: 
        !            44: /*
        !            45:  * Sizes.
        !            46:  */
        !            47: #define        sh      ((fsize_t)sizeof(struct ldheader))
        !            48: #define si     lssize[L_SHRI]
        !            49: #define pi     lssize[L_PRVI]
        !            50: #define bi     lssize[L_BSSI]
        !            51: #define sd     lssize[L_SHRD]
        !            52: #define pd     lssize[L_PRVD]
        !            53: #define bd     lssize[L_BSSD]
        !            54: 
        !            55: /*
        !            56:  * Segments.
        !            57:  */
        !            58: #define upsp   pp->p_segp[SIUSERP]
        !            59: #define sssp   pp->p_segp[SISTACK]
        !            60: #define        sisp    pp->p_segp[SISTEXT]
        !            61: #define pisp   pp->p_segp[SIPTEXT]
        !            62: #define sdsp   pp->p_segp[SISDATA]
        !            63: #define pdsp   pp->p_segp[SIPDATA]
        !            64: 
        !            65: /*
        !            66:  * Set up the first process, a small programme which will exec
        !            67:  * the init programme.
        !            68:  */
        !            69: eveinit(sp)
        !            70: SEG *sp;
        !            71: {
        !            72:        register PROC *pp;
        !            73: 
        !            74:        SELF = pp = eprocp;
        !            75:        pp->p_segp[SIUSERP] = sp;
        !            76:        if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
        !            77:                panic("eveinit()");
        !            78:        pp->p_segp[SIPDATA] = sp;
        !            79:        kscopy(icodep, sp, 0, icodes);
        !            80:        if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
        !            81:                panic("eveinit()");
        !            82:        pp->p_segp[SISTACK] = sp;
        !            83:        u.u_argp = 0;
        !            84:        if (sproto() == 0)
        !            85:                panic("eveinit()");
        !            86:        segload();
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * Given a major number, a file containing a device driver and a configuration
        !            91:  * pointer, load the driver on the major number.
        !            92:  */
        !            93: pload(m, np, cp)
        !            94: char *np;
        !            95: CON *cp;
        !            96: {
        !            97:        register INODE *ip;
        !            98:        register SEG *sp;
        !            99:        register DRV *dp;
        !           100:        register fsize_t ss;
        !           101:        dold_t dold;
        !           102:        int lflag;
        !           103:        int r;
        !           104:        vaddr_t pc;
        !           105:        fsize_t lssize[NUSEG];
        !           106: 
        !           107:        if (m >= drvn) {
        !           108:                u.u_error = ENXIO;
        !           109:                return;
        !           110:        }
        !           111:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
        !           112:                return;
        !           113:        ss = pi+si+pd+sd;
        !           114:        sp = ssalloc(&r, ip, SFSHRX, ss+bi+bd, sh, ss);
        !           115:        idetach(ip);
        !           116:        if (r < 0)
        !           117:                return;
        !           118:        dp = &drvl[m];
        !           119:        lock(dp->d_gate);
        !           120:        if (dp->d_conp != NULL) {
        !           121:                unlock(dp->d_gate);
        !           122:                sfree(sp);
        !           123:                u.u_error = EDBUSY;
        !           124:                return;
        !           125:        }
        !           126:        dp->d_time = 0;
        !           127:        dp->d_conp = cp;
        !           128:        dp->d_segp = sp;
        !           129:        dp->d_map = sp->s_mbase;
        !           130:        dsave(dold);
        !           131:        dmapv(dp->d_map);
        !           132:        (*cp->c_load)();
        !           133:        drest(dold);
        !           134:        unlock(dp->d_gate);
        !           135: }
        !           136: 
        !           137: /*
        !           138:  * Given a major number, undo the previous function.
        !           139:  */
        !           140: puload(m)
        !           141: int m;
        !           142: {
        !           143:        register CON *cp;
        !           144:        register DRV *dp;
        !           145:        dold_t dold;
        !           146: 
        !           147:        dp = &drvl[m];
        !           148:        lock(dp->d_gate);
        !           149:        if (m>=drvn || dp->d_segp==NULL || (cp=dp->d_conp)==NULL) {
        !           150:                u.u_error = ENXIO;
        !           151:                goto ret;
        !           152:        }
        !           153:        dsave(dold);
        !           154:        dmapv(dp->d_map);
        !           155:        (*cp->c_uload)();
        !           156:        drest(dold);
        !           157:        if (u.u_error)
        !           158:                goto ret;
        !           159:        sfree(dp->d_segp);
        !           160:        dp->d_conp = NULL;
        !           161:        dp->d_segp = NULL;
        !           162:        dp->d_map = 0;
        !           163: ret:
        !           164:        unlock(dp->d_gate);
        !           165:        return (0);
        !           166: }
        !           167: 
        !           168: /*
        !           169:  * Given the name of an executable l.out, a null terminated argument
        !           170:  * list and a null terminated environment list, execute the l.out with the
        !           171:  * given arguments and environments.
        !           172:  */
        !           173: pexece(np, argp, envp)
        !           174: char   *np;
        !           175: char   *argp[];
        !           176: char   *envp[];
        !           177: {
        !           178:        register INODE  *ip;                    /* Load file INODE */
        !           179:        register PROC   *pp;                    /* A cheap copy of SELF */
        !           180:        register SEG    *ssp;                   /* New stack segment */
        !           181:        register fsize_t        ss;                     /* Segment size temp. */
        !           182:        register int    kprocflag;              /* Set if kernal process */
        !           183:        register int    i;                      /* For looping over segments */
        !           184:        int             r;                      /* Flag for "exload" */
        !           185:        int             lflag;                  /* l_flags from l.out */
        !           186:        vaddr_t         pc;                     /* l_entry from l.out */
        !           187:        vaddr_t         sp;                     /* Initial stack pointer */
        !           188:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !           189: 
        !           190:        pp = SELF;
        !           191:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
        !           192:                return;
        !           193:        if ((lflag&LF_KER) != 0) {
        !           194:                pp->p_flags |= PFKERN;
        !           195:                kprocflag = 1;
        !           196:                ssp = NULL;
        !           197:                if (super() == 0) {
        !           198:                        idetach(ip);
        !           199:                        return;
        !           200:                }
        !           201:        } else {
        !           202:                kprocflag = 0;
        !           203:                if ((ssp=exstack(&sp, argp, envp)) == NULL) {
        !           204:                        idetach(ip);
        !           205:                        return;
        !           206:                }
        !           207:        }
        !           208:        /*
        !           209:         * At this point the file has been
        !           210:         * validated as an object module, and the
        !           211:         * argument list has been build. Release all of
        !           212:         * the original segments. At this point we have
        !           213:         * committed to the new image. A "sys exec" that
        !           214:         * gets an I/O error is doomed.
        !           215:         */
        !           216:        for (i=1; i<NUSEG; ++i) {
        !           217:                if (pp->p_segp[i] != NULL) {
        !           218:                        sfree(pp->p_segp[i]);
        !           219:                        pp->p_segp[i] = NULL;
        !           220:                }
        !           221:        }
        !           222:        sssp = ssp;
        !           223:        /*
        !           224:         * Read in load module.
        !           225:         */
        !           226:        switch (lflag&(LF_SHR|LF_SEP)) {
        !           227:        case 0:
        !           228:                ss = si+pi+sd+pd;
        !           229:                pdsp = ssalloc(&r, ip, kprocflag?SFHIGH:0, ss+bi+bd, sh, ss);
        !           230:                if (r < 0)
        !           231:                        goto out;
        !           232:                break;
        !           233: 
        !           234:        case LF_SHR:
        !           235:                sdsp = ssalloc(&r, ip, SFSHRX, si+sd, sh, si);
        !           236:                if (r < 0)
        !           237:                        goto out;
        !           238:                if (r == 0) {
        !           239:                        if (exsread(sdsp, ip, sd, sh+si+pi, si) == 0)
        !           240:                                goto out;
        !           241:                }
        !           242:                pdsp = ssalloc(&r, ip, 0, pi+pd+bi+bd, sh+si, pi);
        !           243:                if (r < 0)
        !           244:                        goto out;
        !           245:                if (r == 0) {
        !           246:                        if (exsread(pdsp, ip, pd, sh+si+pi+sd, pi) == 0)
        !           247:                                goto out;
        !           248:                }
        !           249:                break;
        !           250: 
        !           251:        case LF_SEP:
        !           252:                pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
        !           253:                if (r < 0)
        !           254:                        goto out;
        !           255:                pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+bi, sd+pd);
        !           256:                if (r < 0)
        !           257:                        goto out;
        !           258:                break;
        !           259: 
        !           260:        case LF_SHR|LF_SEP:
        !           261:                sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
        !           262:                if (r < 0)
        !           263:                        goto out;
        !           264:                pisp = ssalloc(&r, ip, SFTEXT, pi+bi, sh+si, pi);
        !           265:                if (r < 0)
        !           266:                        goto out;
        !           267:                sdsp = ssalloc(&r, ip, SFSHRX, sd, sh+si+pi, sd);
        !           268:                if (r < 0)
        !           269:                        goto out;
        !           270:                pdsp = ssalloc(&r, ip, 0, pd+bd, sh+si+pi+pd, pd);
        !           271:                if (r < 0)
        !           272:                        goto out;
        !           273:        }
        !           274:        if (sproto() == 0)
        !           275:                goto out;
        !           276:        /*
        !           277:         * The new image is read in
        !           278:         * and mapped. Perform the final grunge
        !           279:         * (set-uid stuff, accounting, loading up
        !           280:         * registers, etc).
        !           281:         */
        !           282:        u.u_flag &= ~AFORK;
        !           283:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
        !           284:        if (iaccess(ip, IPR) == 0)
        !           285:                pp->p_flags |= PFNDMP;
        !           286:        if ((ip->i_mode&ISUID) != 0)
        !           287:                pp->p_uid = u.u_uid = ip->i_uid;
        !           288:        if ((ip->i_mode&ISGID) != 0)
        !           289:                u.u_gid = ip->i_gid;
        !           290:        for (i=0; i<NSIG; ++i) {
        !           291:                if (u.u_sfunc[i] != SIG_IGN)
        !           292:                        u.u_sfunc[i] = SIG_DFL;
        !           293:        }
        !           294:        if ((pp->p_flags&PFTRAC) != 0)
        !           295:                sendsig(SIGTRAP, pp);
        !           296:        idetach(ip);
        !           297:        msetusr(pc, sp);
        !           298:        segload();
        !           299:        return (0);
        !           300: 
        !           301:        /*
        !           302:         * We did not make it.
        !           303:         * Release the INODE for the load
        !           304:         * file, and return through the "sys exit"
        !           305:         * code. A better exit status should be
        !           306:         * chosen!
        !           307:         */
        !           308: out:
        !           309:        idetach(ip);
        !           310:        pexit(0);
        !           311: }
        !           312: 
        !           313: /*
        !           314:  * Open an l.out, make sure it is an l.out and executable and return the
        !           315:  * appropriate information.
        !           316:  */
        !           317: INODE *
        !           318: exlopen(np, ssizep, flagp, pcp)
        !           319: char *np;
        !           320: fsize_t *ssizep;
        !           321: int *flagp;
        !           322: vaddr_t *pcp;
        !           323: {
        !           324:        register INODE *ip;
        !           325:        register struct ldheader *ldp;
        !           326:        register int n;
        !           327:        register BUF *bp;
        !           328:        int m;
        !           329: 
        !           330:        /*
        !           331:         * Make sure the file is really an executable l.out and read the
        !           332:         * header in.
        !           333:         */
        !           334:        if (ftoi(np, 'r') != 0)
        !           335:                return (NULL);
        !           336:        ip = u.u_cdiri;
        !           337:        if (iaccess(ip, IPE) == 0) {
        !           338:                idetach(ip);
        !           339:                return (NULL);
        !           340:        }
        !           341:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
        !           342:                u.u_error = EACCES;
        !           343:                idetach(ip);
        !           344:                return (NULL);
        !           345:        }
        !           346:        if ((bp=vread(ip, (daddr_t)0)) == NULL) {
        !           347:                u.u_error = EBADFMT;
        !           348:                idetach(ip);
        !           349:                return (NULL);
        !           350:        }
        !           351: 
        !           352:        /*
        !           353:         * Copy everything we need from the l.out header and check magic
        !           354:         * number and machine type.
        !           355:         */
        !           356:        ldp = bp->b_vaddr;
        !           357:        m = ldp->l_magic;
        !           358:        canint(m);
        !           359:        if (m != L_MAGIC) {
        !           360:                u.u_error = ENOEXEC;
        !           361:                brelease(bp);
        !           362:                idetach(ip);
        !           363:                return (NULL);
        !           364:        }
        !           365:        m = ldp->l_machine;
        !           366:        canint(m);
        !           367:        if (m != mactype) {
        !           368:                u.u_error = EBADFMT;
        !           369:                brelease(bp);
        !           370:                idetach(ip);
        !           371:                return (NULL);
        !           372:        }
        !           373:        kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
        !           374:        for (n=0; n<NXSEG; n++)
        !           375:                cansize(ssizep[n]);
        !           376:        *flagp = ldp->l_flag;
        !           377:        canint(*flagp);
        !           378:        *pcp = ldp->l_entry;
        !           379:        canvaddr(*pcp);
        !           380:        brelease(bp);
        !           381:        return (ip);
        !           382: }
        !           383: 
        !           384: /*
        !           385:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
        !           386:  * at seek address `sa' into offset `so' in the segment.
        !           387:  */
        !           388: SEG *
        !           389: exsread(sp, ip, ss, sa, so)
        !           390: register SEG *sp;
        !           391: INODE *ip;
        !           392: fsize_t sa;
        !           393: fsize_t ss;
        !           394: fsize_t so;
        !           395: {
        !           396:        u.u_io.io_seg = IOPHY;
        !           397:        u.u_io.io_ioc = ss;
        !           398:        u.u_io.io_seek = sa;
        !           399:        u.u_io.io_phys = ctob((paddr_t)sp->s_mbase) + so;
        !           400:        u.u_io.io_flag = 0;
        !           401:        iread(ip, &u.u_io);
        !           402:        return (u.u_error==0);
        !           403: }
        !           404: 
        !           405: /*
        !           406:  * Given a pointer to a list of arguments and a pointer to a list of
        !           407:  * environments, return a stack with the arguments and environments on it.
        !           408:  */
        !           409: SEG *
        !           410: exstack(iusp, argp, envp)
        !           411: char **iusp;           /* Back patch sp value */
        !           412: char *argp[];          /* Arguments for new process */
        !           413: char *envp[];          /* Environments for new process */
        !           414: {
        !           415:        SEG *sp;                /* Stack segment pointer */
        !           416:        struct adata {          /* Storage for arg and env data */
        !           417:                char    **up;           /* User vector pointer */
        !           418:                int     np;             /* Number of pointers in vector */
        !           419:                int     nc;             /* Number of characters in strings */
        !           420:        } arg, env;
        !           421:        struct sdata {          /* To keep segment pointers */
        !           422:                vaddr_t base;           /* Top of segment virtual */
        !           423:                vaddr_t ap;             /* Argc, argv, envp pointer */
        !           424:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
        !           425:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
        !           426:        } aux, stk;
        !           427:        aold_t aold;                    /* Auxiliary map storage */
        !           428:        register char **usrvp;          /* Vector pointer into user seg */
        !           429:        register char *usrcp;           /* Character pointer into user seg */
        !           430:        register int c;                 /* Character fetched from user */
        !           431:        register int chrsz;             /* Size of strings */
        !           432:        register struct adata *adp;     /* Arg and env scanner */
        !           433:        register int vecsz;             /* Size of vectors */
        !           434:        register int stksz;             /* Size of stack argument region */
        !           435: 
        !           436:        /* Validate and evaluate size of args and envs */
        !           437:        arg.up = argp;
        !           438:        env.up = envp;
        !           439:        chrsz = 0;
        !           440:        vecsz = 0;
        !           441:        for (adp = &arg; ; adp = &env) {
        !           442:                adp->np = 0;
        !           443:                adp->nc = 0;
        !           444:                if (excount(adp->up, &adp->np, &adp->nc) == 0)
        !           445:                        return (NULL);
        !           446:                chrsz += adp->nc * sizeof(char);
        !           447:                vecsz += adp->np * sizeof(char *);
        !           448:                if (adp == &env)
        !           449:                        break;
        !           450:        }
        !           451: 
        !           452:        /* Calculate stack size and allocate it */
        !           453:        chrsz = roundu(chrsz, sizeof(int));
        !           454:        stksz = sizeof(int)             /* argc */
        !           455:                + sizeof(char **)       /* argv */
        !           456:                + sizeof(char **)       /* envp */
        !           457:                + vecsz                 /* argv[i] and envp[i] */
        !           458:                + chrsz                 /* *argv[i] and *envp[i] */
        !           459:                + sizeof(int)           /* Mystery zero word */
        !           460:                + sizeof(char *)        /* Splimit for z8000 */
        !           461:                + sizeof(int);          /* errno */
        !           462:        stksz += ISTSIZE;
        !           463:        if (stksz > MADSIZE) {
        !           464:                u.u_error = E2BIG;
        !           465:                return (NULL);
        !           466:        }
        !           467:        if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
        !           468:                return (NULL);
        !           469:        stksz -= ISTSIZE;
        !           470: 
        !           471:        /*
        !           472:         * Initialize segment data.
        !           473:         */
        !           474:        asave(aold);
        !           475: 
        !           476:        aux.base = abase(sp->s_mbase) + ctob(sp->s_size);
        !           477:        aux.ap = aux.base - stksz;
        !           478:        aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
        !           479:        aux.cp = aux.vp + vecsz;
        !           480: 
        !           481:        stk.base = ISTVIRT;
        !           482:        stk.ap = stk.base - stksz;
        !           483:        stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
        !           484:        stk.cp = stk.vp + vecsz;
        !           485: 
        !           486:        /*
        !           487:         * Write argc.
        !           488:         */
        !           489:        aputi((int *)aux.ap, arg.np-1);
        !           490:        aux.ap += sizeof(int);
        !           491: 
        !           492:        /*
        !           493:         * Arguments and environments.
        !           494:         */
        !           495:        for (adp = &arg; ; adp = &env) {
        !           496: 
        !           497:                /* Write argv or envp */
        !           498:                aputp((char ***)aux.ap, (char **)stk.vp);
        !           499:                aux.ap += sizeof(char **);
        !           500:                if ((usrvp = adp->up) != NULL) {
        !           501: 
        !           502:                        /* Write argv[i] or envp[i] */
        !           503:                        while ((usrcp = getupd(usrvp++)) != NULL) {
        !           504:                                aputp((char **)aux.vp, (char *)stk.cp);
        !           505:                                aux.vp += sizeof(char *);
        !           506:                                stk.vp += sizeof(char *);
        !           507: 
        !           508:                                /* Write argv[i][j] or envp[i][j] */
        !           509:                                do {
        !           510:                                        c = getubd(usrcp++);
        !           511:                                        aputc((char *)aux.cp, c);
        !           512:                                        aux.cp += sizeof(char);
        !           513:                                        stk.cp += sizeof(char);
        !           514:                                } while (c != '\0');
        !           515:                        }
        !           516:                }
        !           517: 
        !           518:                /* Write argv[argc] or envp[envc] */
        !           519:                aputp((char **)aux.vp, NULL);
        !           520:                aux.vp += sizeof(char *);
        !           521:                stk.vp += sizeof(char *);
        !           522:                if (adp == &env)
        !           523:                        break;
        !           524:        }
        !           525: 
        !           526:        /*
        !           527:         * Clear out the slop.
        !           528:         */
        !           529:        aux.base -= sizeof(int);
        !           530:        aputi((int *) aux.base, 0);             /* errno */
        !           531:        aux.base -= sizeof(char *);
        !           532:        aputp((char **) aux.base, (char *)stk.base-ctob(sp->s_size)+SOVSIZE);
        !           533:        aux.base -= sizeof(int);
        !           534:        aputi((int *) aux.base, 0);             /* mystery word */
        !           535: 
        !           536:        arest(aold);
        !           537: 
        !           538:        /*
        !           539:         * Patch some values and return.
        !           540:         */
        !           541:        *iusp = stk.ap;         /* Patch initial usp */
        !           542:        u.u_argc = arg.np-1;
        !           543:        u.u_argp = stk.vp;      /* Points after NULL of envs */
        !           544:        return (sp);
        !           545: }
        !           546: 
        !           547: /*
        !           548:  * Given a pointer to a list of arguments, a pointer to an argument count
        !           549:  * and a pointer to a byte count, update incrementally the argument count
        !           550:  * and the byte count.
        !           551:  */
        !           552: excount(usrvp, nap, nbp)
        !           553: register char **usrvp;
        !           554: int *nap;
        !           555: int *nbp;
        !           556: {
        !           557:        register char *usrcp;
        !           558:        register int c;
        !           559:        register unsigned nb;
        !           560:        register unsigned na;
        !           561: 
        !           562:        na = 1;
        !           563:        nb = 0;
        !           564:        if (usrvp != NULL) {
        !           565:                for (;;) {
        !           566:                        usrcp = getupd(usrvp++);
        !           567:                        if (u.u_error)
        !           568:                                return (0);
        !           569:                        if (usrcp == NULL)
        !           570:                                break;
        !           571:                        na++;
        !           572:                        for (;;) {
        !           573:                                c = getubd(usrcp++);
        !           574:                                if (u.u_error)
        !           575:                                        return (0);
        !           576:                                nb++;
        !           577:                                if (c == '\0')
        !           578:                                        break;
        !           579:                        }
        !           580:                }
        !           581:        }
        !           582:        *nap += na;
        !           583:        *nbp += nb;
        !           584:        return (1);
        !           585: }

unix.superglobalmegacorp.com

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