Annotation of coherent/d/PS2_KERNEL/coh.386/exec.c, revision 1.1

1.1     ! root        1: /* (lgl-
        !             2:  *     The information contained herein is a trade secret of Mark Williams
        !             3:  *     Company, and  is confidential information.  It is provided  under a
        !             4:  *     license agreement,  and may be  copied or disclosed  only under the
        !             5:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !             6:  *     material without the express written authorization of Mark Williams
        !             7:  *     Company or persuant to the license agreement is unlawful.
        !             8:  *
        !             9:  *     COHERENT Version 2.3.37
        !            10:  *     Copyright (c) 1982, 1983, 1984.
        !            11:  *     An unpublished work by Mark Williams Company, Chicago.
        !            12:  *     All rights reserved.
        !            13:  *
        !            14:  *     Intel 386 port and extensions (16/32 bit compatibility)
        !            15:  *     Copyright (c) Ciaran O'Donnell, Bievres (FRANCE), 1991
        !            16:  *
        !            17:  * $Log:       exec.c,v $
        !            18:  * Revision 1.10  92/07/16  16:33:31  hal
        !            19:  * Kernel #58
        !            20:  * 
        !            21:  * Revision 1.9  92/06/11  21:39:19  root
        !            22:  * Add close on exec.
        !            23:  * 
        !            24:  * Revision 1.8  92/06/10  12:51:09  hal
        !            25:  * Do click roundup on call to salloc for eveinit.
        !            26:  * Assorted cosmetic changes.
        !            27:  * 
        !            28:  * Revision 1.6  92/02/11  10:09:57  hal
        !            29:  * Execute shared l.out's now
        !            30:  * 
        !            31:  * Revision 1.5  92/02/10  18:11:27  hal
        !            32:  * Ignore SHR bit in l.out's for now.
        !            33:  * 
        !            34:  * Revision 1.4  92/01/23  18:15:28  hal
        !            35:  * Add "double sfree" fix from Ciaran.
        !            36:  * 
        !            37:  * Revision 1.3  92/01/15  11:11:26  hal
        !            38:  * Remove exlock temporary fix.
        !            39:  * 
        !            40:  * Revision 1.2  92/01/06  11:58:57  hal
        !            41:  * Compile with cc.mwc.
        !            42:  * 
        !            43:  *
        !            44:  -lgl) */
        !            45: #include <sys/coherent.h>
        !            46: #include <acct.h>
        !            47: #include <sys/buf.h>
        !            48: #include <canon.h>
        !            49: #include <sys/con.h>
        !            50: #include <errno.h>
        !            51: #include <fcntl.h>
        !            52: #include <sys/filsys.h>
        !            53: #include <sys/ino.h>
        !            54: #include <sys/inode.h>
        !            55: #include <a.out.h>
        !            56: #include <l.out.h>
        !            57: #include <sys/proc.h>
        !            58: #include <sys/sched.h>
        !            59: #include <sys/seg.h>
        !            60: #include <signal.h>
        !            61: #include <sys/reg.h>
        !            62: #include <sys/stat.h>
        !            63: #include <sys/fd.h>
        !            64: 
        !            65: /*
        !            66:  * Pass control to an image in a file.
        !            67:  * Make sure the format is acceptable. Release
        !            68:  * the old segments. Read in the new ones. Some special
        !            69:  * care is taken so that shared and (more important) shared
        !            70:  * and separated images can be run on the 8086.
        !            71:  */
        !            72: pexece(np, argp, envp)
        !            73: char   *np;
        !            74: char   *argp[];
        !            75: char   *envp[];
        !            76: {
        !            77:        struct xechdr   head;
        !            78:        register INODE  *ip;                    /* Load file INODE */
        !            79:        register PROC   *pp;                    /* A cheap copy of SELF */
        !            80:        register SEG    *segp;
        !            81:        SEG     *ssegp;
        !            82:        register int    i;                      /* For looping over segments*/
        !            83:        register BUF *bp;
        !            84:        int roundup;
        !            85:        int shrdsize;
        !            86: 
        !            87:        pp = SELF;
        !            88:        kclear(&head, sizeof(head)); 
        !            89:        if ((ip=exlopen(&head, np, &shrdsize)) == NULL)
        !            90:                goto done;
        !            91:        roundup = (shrdsize) & 0xf;
        !            92:        ssegp = exstack(&head,argp, envp, wdsize());
        !            93: 
        !            94:        if (!ssegp) {
        !            95:                idetach(ip);
        !            96:                goto done;
        !            97:        }
        !            98: 
        !            99:        /*
        !           100:         * At this point the file has been
        !           101:         * validated as an object module, and the
        !           102:         * argument list has been built. Release all of
        !           103:         * the original segments. At this point we have
        !           104:         * committed to the new image. A "sys exec" that
        !           105:         * gets an I/O error is doomed.
        !           106:         * NOTE: User-area segment is NOT released.
        !           107:         *       Segment pointer in proc is erased BEFORE invoking sfree().
        !           108:         */
        !           109: 
        !           110:        for ( i = 1; i < NUSEG; ++i ) {
        !           111:                if ((segp = pp->p_segp[i]) != NULL) {
        !           112:                        pp->p_segp[i] = NULL;
        !           113:                        sfree(segp);
        !           114:                }
        !           115:        }
        !           116:        pp->p_segp[SISTACK] = ssegp;
        !           117: 
        !           118:        /*
        !           119:         * Read in the loadable segments.
        !           120:         */
        !           121:        switch (head.magic) {
        !           122:        case XMAGIC(    I286MAGIC,I_MAGIC       ):
        !           123:                u.u_regl[CS] = SEG_286_UII | R_USR;
        !           124:                u.u_regl[DS] = SEG_286_UD  | R_USR;
        !           125:                segp = pp->p_segp[SISTEXT] = ssalloc(ip,SFTEXT,
        !           126:                  head.segs[SISTEXT].size);
        !           127:                if (!exsread(segp, ip, &head.segs[SISTEXT], 0)) {
        !           128:                        goto out;
        !           129:                }
        !           130:                segp = ssalloc(ip,0,roundup+
        !           131:                  head.segs[SIPDATA].size+head.segs[SIBSS].size);
        !           132:                pp->p_segp[SIPDATA] = segp;
        !           133:                if (!exsread(segp,ip,&head.segs[SIPDATA],shrdsize)) {
        !           134:                        goto out;
        !           135:                }
        !           136:                head.segs[SIPDATA].size += roundup;
        !           137:                break;
        !           138:        case XMAGIC(    I386MAGIC,Z_MAGIC       ):
        !           139:                u.u_regl[CS] = SEG_386_UI | R_USR;
        !           140:                u.u_regl[DS] = SEG_386_UD | R_USR;
        !           141:                segp = pp->p_segp[SISTEXT] = ssalloc(ip,SFTEXT|SFSHRX,
        !           142:                                head.segs[SISTEXT].size);
        !           143:                if (segp->s_ip==0) {
        !           144:                        if (!exsread(segp, ip, &head.segs[SISTEXT], 0)) {
        !           145:                                goto out;
        !           146:                        }
        !           147:                        segp->s_ip = ip;
        !           148:                        ip->i_refc++;
        !           149:                }
        !           150:                segp = ssalloc(ip,0,
        !           151:                  head.segs[SIPDATA].size+head.segs[SIBSS].size);
        !           152:                pp->p_segp[SIPDATA] = segp;
        !           153:                if (segp->s_ip==0 &&
        !           154:                    !exsread(segp, ip, &head.segs[SIPDATA], 0)) {
        !           155:                        goto out;
        !           156:                }
        !           157:                break;
        !           158:        default:
        !           159:                panic("pexece");
        !           160:        }
        !           161: 
        !           162:        u.u_regl[SS] = u.u_regl[ES] = u.u_regl[DS];
        !           163:        if (sproto(&head) == 0) {
        !           164:                goto out;
        !           165:        }
        !           166: 
        !           167:        /*
        !           168:         * The new image is read in
        !           169:         * and mapped. Perform the final grunge
        !           170:         * (set-uid stuff, accounting, loading up
        !           171:         * registers, etc).
        !           172:         */
        !           173:        u.u_flag &= ~AFORK;
        !           174:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
        !           175:        if (iaccess(ip, IPR) == 0) {    /* Can't read ? no dump or trace */
        !           176:                pp->p_flags |= PFNDMP;
        !           177:                pp->p_flags &= ~PFTRAC;
        !           178:        }
        !           179: 
        !           180:        /*
        !           181:         * Norm says Frank says we need to drop this for db to work.
        !           182:         */
        !           183:        if (iaccess(ip, IPW) == 0)      /* Can't write ? no trace */
        !           184:                pp->p_flags &= ~PFTRAC;
        !           185: 
        !           186:        if ((ip->i_mode&ISUID) != 0) {  /* Set user id ? no trace */
        !           187:                pp->p_uid = u.u_uid = ip->i_uid;
        !           188:                pp->p_flags &= ~PFTRAC;
        !           189:        }
        !           190:        if ((ip->i_mode&ISGID) != 0) {  /* Set group id ? no trace */
        !           191:                u.u_gid = ip->i_gid;
        !           192:                pp->p_flags &= ~PFTRAC;
        !           193:        }
        !           194:        for (i=0; i < NUFILE; i++) {
        !           195:                if (u.u_filep[i]!=NULL && (u.u_filep[i]->f_flag2&FD_CLOEXEC))  {
        !           196:                        fdclose(i);     /* close fd on exec bit set */
        !           197:                }
        !           198:        }
        !           199:        /*
        !           200:         * Default every signal that is not ignored.
        !           201:         */
        !           202:        for (i=0; i<NSIG; ++i) {
        !           203:                if (u.u_sfunc[i] != SIG_IGN) {
        !           204:                        u.u_sfunc[i] = SIG_DFL;
        !           205:                        pp->p_dfsig |= ((sig_t) 1) << (i - 1);
        !           206:                }
        !           207:        }
        !           208:        if ((pp->p_flags&PFTRAC) != 0)  /* Being traced */
        !           209:                sendsig(SIGTRAP, pp);
        !           210:        idetach(ip);
        !           211:        msetusr(head.entry, head.initsp);
        !           212: 
        !           213:        segload();
        !           214:        goto done;
        !           215: 
        !           216:        /*
        !           217:         * We did not make it.
        !           218:         * Release the INODE for the load
        !           219:         * file, and return through the "sys exit"
        !           220:         * code with a "SIGSYS", or with the signal actually received
        !           221:         * if we are aborting due to interrupted exec.
        !           222:         */
        !           223: out:
        !           224:        idetach(ip);
        !           225:        if (u.u_error == EINTR)
        !           226:                pexit(nondsig());
        !           227:        pexit(SIGSYS);
        !           228: 
        !           229: done:
        !           230:        return 0;       
        !           231: }
        !           232: 
        !           233: /*
        !           234:  * Open an l.out, make sure it is an l.out and executable and return the
        !           235:  * appropriate information.
        !           236:  */
        !           237: INODE *
        !           238: exlopen(xhp, np, shrds) 
        !           239: register struct xechdr *xhp;
        !           240: char *np;
        !           241: int *shrds;
        !           242: {
        !           243:        register INODE *ip;
        !           244:        int     i, nscn, diff, hdrsize;
        !           245:        register BUF *bp;
        !           246:        unsigned short magic;
        !           247:        struct ldheader head;
        !           248:        struct filehdr fhead;
        !           249:        struct aouthdr ahead;   
        !           250:        struct scnhdr scnhdr;
        !           251: 
        !           252:        /*
        !           253:         * Make sure the file is really an executable l.out and read the
        !           254:         * header in.
        !           255:         */
        !           256:        if (ftoi(np, 'r') != 0)
        !           257:                return (NULL);
        !           258:        ip = u.u_cdiri;
        !           259:        if (iaccess(ip, IPE) == 0) {
        !           260:                idetach(ip);
        !           261:                return (NULL);
        !           262:        }
        !           263:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
        !           264:                u.u_error = EACCES;
        !           265:                idetach(ip);
        !           266:                return (NULL);
        !           267:        }
        !           268:        if ((bp=vread(ip, (daddr_t)0)) == NULL)
        !           269:                goto bad;
        !           270:        /*
        !           271:         * Copy everything we need from the l.out header and check magic
        !           272:         * number and machine type.
        !           273:         */
        !           274:        *shrds = 0;  /* set return arg shrds nonzero only for shared l.out */
        !           275:        kkcopy(bp->b_vaddr, &magic, sizeof(magic));
        !           276:        canint(magic);
        !           277:        switch (magic) {
        !           278:        case L_MAGIC:           /* Coherent 286 format */
        !           279:                kkcopy(bp->b_vaddr, &head, sizeof(struct ldheader));
        !           280:                canint(head.l_machine);
        !           281:                if (head.l_machine!=M_8086)
        !           282:                        goto bad;
        !           283:                for (i=0; i<NXSEG; i++) {
        !           284:                        cansize(head.l_ssize[i]);
        !           285:                }       
        !           286:                canint(head.l_flag);
        !           287:                canvaddr(head.l_entry);
        !           288: 
        !           289:                /*
        !           290:                 * If a shared and separated image
        !           291:                 * has stuff in segments that makes it impossible
        !           292:                 * to share, give an error immediately so that we don't
        !           293:                 * lose the parent.
        !           294:                 */
        !           295:                head.l_flag &= LF_SHR|LF_SEP|LF_KER;
        !           296: 
        !           297:                if ((head.l_flag&LF_SEP==0) || (head.l_flag &LF_KER)
        !           298:                  || head.l_ssize[L_PRVI] || head.l_ssize[L_BSSI]) {
        !           299:                        goto bad;
        !           300:                }
        !           301:                xhp->magic = XMAGIC(    I286MAGIC,I_MAGIC       );
        !           302:                xhp->entry = head.l_entry;
        !           303: 
        !           304:                xhp->segs[SISTEXT].fbase = sizeof(struct ldheader);
        !           305:                xhp->segs[SISTEXT].mbase = NBPS;
        !           306:                xhp->segs[SISTEXT].size = head.l_ssize[L_SHRI];
        !           307: 
        !           308:                xhp->segs[SIPDATA].fbase = sizeof(struct ldheader) +
        !           309:                        xhp->segs[SISTEXT].size;
        !           310:                xhp->segs[SIPDATA].mbase = 0;
        !           311:                xhp->segs[SIPDATA].size = head.l_ssize[L_SHRD] +
        !           312:                        head.l_ssize[L_PRVD];
        !           313:                if (head.l_flag & LF_SHR)
        !           314:                        *shrds = head.l_ssize[L_SHRD];
        !           315: 
        !           316:                xhp->segs[SIBSS].fbase = 0;
        !           317:                xhp->segs[SIBSS].mbase = xhp->segs[SIPDATA].size;
        !           318:                xhp->segs[SIBSS].size = head.l_ssize[L_BSSD];
        !           319: 
        !           320:                xhp->segs[SISTACK].mbase = ISP_286;     /* size 0, fbase 0 */
        !           321:                brelease(bp);
        !           322:                return ip;
        !           323: 
        !           324:        case I386MAGIC:         /* ... COFF */
        !           325:                kkcopy(bp->b_vaddr, &fhead, sizeof(struct filehdr));
        !           326:                hdrsize = sizeof(ahead)+sizeof(fhead);
        !           327:                if(fhead.f_opthdr!=sizeof (ahead) || !(fhead.f_flags&F_EXEC)||
        !           328:                fhead.f_nscns*sizeof(scnhdr) > BSIZE)
        !           329:                        goto bad;
        !           330: 
        !           331:                kkcopy(bp->b_vaddr+sizeof(fhead), &ahead, sizeof(ahead));
        !           332:                if ((/*ahead.magic!=O_MAGIC && ahead.magic!=N_MAGIC && */
        !           333:                     ahead.magic!=Z_MAGIC))
        !           334:                        goto bad;
        !           335: 
        !           336:                xhp->magic = XMAGIC(    I386MAGIC,ahead.magic   );
        !           337:                xhp->entry = ahead.entry;
        !           338: 
        !           339:                for (i=0; i<fhead.f_nscns; i++) {
        !           340:                        kkcopy(bp->b_vaddr + hdrsize + sizeof(scnhdr)*i,
        !           341:                                &scnhdr, sizeof(scnhdr));
        !           342:                        switch ((int)(scnhdr.s_flags)) {
        !           343:                        case STYP_INFO:
        !           344:                                continue;
        !           345:                        case STYP_BSS:
        !           346:                                nscn = SIBSS;
        !           347:                                break;
        !           348:                        case STYP_TEXT:
        !           349:                                nscn = SISTEXT; goto common;
        !           350:                        case STYP_DATA:
        !           351:                                nscn = SIPDATA;
        !           352:                        common:
        !           353:                                diff = scnhdr.s_scnptr & (NBPC-1);
        !           354:                                scnhdr.s_vaddr -= diff;
        !           355:                                scnhdr.s_scnptr -= diff;
        !           356:                                scnhdr.s_size += diff;
        !           357:                                break;
        !           358:                        default:
        !           359:                                goto bad;
        !           360:                        }
        !           361: 
        !           362:                        if (xhp->segs[nscn].size!=0
        !           363:                        ||  (unsigned)scnhdr.s_vaddr >= ISP_386)
        !           364:                                goto bad;
        !           365: 
        !           366:                        xhp->segs[nscn].mbase = scnhdr.s_vaddr;
        !           367:                        xhp->segs[nscn].fbase = scnhdr.s_scnptr;
        !           368:                        xhp->segs[nscn].size = scnhdr.s_size;
        !           369:                }
        !           370: 
        !           371:                if (!xhp->segs[SISTEXT].size || !xhp->segs[SIPDATA].size)
        !           372:                        goto bad;
        !           373: 
        !           374:                xhp->entry = ahead.entry;
        !           375:                if (xhp->entry >= xhp->segs[SISTEXT].size)
        !           376:                        goto bad;
        !           377: 
        !           378:                xhp->segs[SISTACK].mbase = ISP_386;     /* size 0, fbase 0 */
        !           379:                xhp->magic = XMAGIC(    I386MAGIC,ahead.magic   );
        !           380:                brelease(bp);   
        !           381:                return ip;
        !           382:        default:
        !           383:        bad:            
        !           384:                brelease(bp);
        !           385:                u.u_error = ENOEXEC;
        !           386:                idetach(ip);
        !           387:                return NULL;
        !           388:        }
        !           389: }
        !           390: 
        !           391: /*
        !           392:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
        !           393:  * at seek address `sa' into offset `so' in the segment.
        !           394:  *
        !           395:  * Argument "first" is nonzero only when loading data for l.out -
        !           396:  * need this because *shared* l.out's need PRVD to be aligned on the next
        !           397:  * 16 byte boundary after the end of SHRD.  So we need to leave a hole
        !           398:  * between SHRD and PRVD in this case.
        !           399:  */
        !           400: static SEG *
        !           401: exsread(sp, ip, xsp, first)
        !           402: register SEG *sp;
        !           403: INODE *ip;
        !           404: struct xecseg *xsp;
        !           405: int first;
        !           406: {
        !           407:        register int ss, sa, so, did;
        !           408:        int overshoot;
        !           409: 
        !           410:        sa = xsp->fbase;
        !           411:        so = 0;
        !           412: 
        !           413:        for (ss = first ? first : xsp->size;; ss -= did) {
        !           414:                if (!ss) {      /* we finished a hunk */
        !           415:                        /* is there more to read */
        !           416:                        if (!first || (!(ss = xsp->size - first)))
        !           417:                                break;
        !           418:                        so = (so + 15) & ~15; /* round up */
        !           419:                        first = 0;      /* don't go again */
        !           420:                }
        !           421:                u.u_io.io_seg = IOPHY;
        !           422:                u.u_io.io_seek = sa;
        !           423:                u.u_io.io.pbase = MAPIO(sp->s_vmem, so);
        !           424:                u.u_io.io_flag = 0;
        !           425:                /*
        !           426:                 * "did" is how many bytes to read in with this request.
        !           427:                 */
        !           428:                if (ss >= 4096)
        !           429:                        did = u.u_io.io_ioc = 4096;
        !           430:                else
        !           431:                        did = u.u_io.io_ioc = ss;
        !           432:                /*
        !           433:                 * Don't allow incoming data to straddle a 4k segment.
        !           434:                 */
        !           435:                overshoot = did + (so & 4095) - 4096;
        !           436:                if (overshoot > 0)
        !           437:                        did -= overshoot;
        !           438:                sp->s_lrefc++;
        !           439:                iread(ip, &u.u_io);
        !           440:                sp->s_lrefc--;
        !           441:                if (nondsig()) {
        !           442:                        u.u_error = EINTR;
        !           443:                        break;
        !           444:                }
        !           445:                sa += did;
        !           446:                so += did;
        !           447:        }
        !           448:        if (u.u_error == 0)
        !           449:                return (sp);
        !           450:        return (NULL);
        !           451: }
        !           452: 
        !           453: struct adata {         /* Storage for arg and env data */
        !           454:        int     np;             /* Number of pointers in vector */
        !           455:        int     nc;             /* Number of characters in strings */
        !           456: };
        !           457: 
        !           458: /*
        !           459:  * Given a pointer to a list of arguments and a pointer to a list of
        !           460:  * environments, return a stack with the arguments and environments on it.
        !           461:  */
        !           462: SEG *
        !           463: exstack(xhp, argp, envp, wdin)
        !           464: register struct xechdr *xhp;
        !           465: vaddr_t        argp, envp;
        !           466: {
        !           467:        register SEG *sp;               /* Stack segment pointer */
        !           468:        struct sdata {          /* To keep segment pointers */
        !           469:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
        !           470:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
        !           471:        } stk;
        !           472:        struct adata arg, env;
        !           473:        int     chrsz, vecsz, stksz, wdmask, wdout, stkoff, stktop;
        !           474:        int     stkenvp;
        !           475:        register int i;
        !           476: 
        !           477:        /* Validate and evaluate size of args and envs */
        !           478:        if (!excount(argp, &arg, wdin) || !excount(envp, &env, wdin))
        !           479:                return NULL;
        !           480: 
        !           481:        /* Calculate stack size and allocate it */
        !           482:        chrsz = roundu(arg.nc + env.nc, sizeof(int));
        !           483:        vecsz = (arg.np+1 + env.np+1) * sizeof(long);
        !           484:        stksz = roundu(vecsz+chrsz+ISTSIZE, NBPC);
        !           485:        if (stksz > MADSIZE || !(sp = salloc(stksz, SFDOWN))) {
        !           486:                u.u_error = E2BIG;
        !           487:                return NULL;
        !           488:        }
        !           489: 
        !           490:        /* Set up target stack */
        !           491:        stktop = xhp->segs[SISTACK].mbase;
        !           492:        stk.cp = stktop - chrsz;
        !           493:        stk.vp = stktop - chrsz - vecsz;
        !           494:        stkoff = MAPIO(sp->s_vmem, stksz - stktop);
        !           495:        u.u_argc = arg.np;
        !           496:        u.u_argp = stk.vp;
        !           497:        wdmask = -1;
        !           498:        if (wdin==sizeof(short))
        !           499:                wdmask = (unsigned short)wdmask;
        !           500: 
        !           501:        switch (stktop) {
        !           502: 
        !           503:        case ISP_386:
        !           504:                wdout = sizeof(long);
        !           505:                xhp->initsp = stk.vp - sizeof(long);
        !           506:                dmaout(sizeof(long), xhp->initsp+stkoff, &arg.np);
        !           507:                break;
        !           508: 
        !           509:        case ISP_286:
        !           510:                wdout = sizeof(short);
        !           511:                xhp->initsp = stk.vp - 3*sizeof(short);
        !           512:                stkenvp = stk.vp + (arg.np+1) * sizeof(short);
        !           513:                dmaout(sizeof(short), xhp->initsp+stkoff, &arg.np);
        !           514:                dmaout(sizeof(short), xhp->initsp+sizeof(short)+stkoff,
        !           515:                        &stk.vp);
        !           516:                dmaout(sizeof(short), xhp->initsp+2*sizeof(short)+stkoff,
        !           517:                        &stkenvp);
        !           518:                break;
        !           519: 
        !           520:        default:
        !           521:                panic("exstack");
        !           522: 
        !           523:        }
        !           524: 
        !           525:        /* Arguments */
        !           526:        for (i = 0; i<arg.np; i++, argp += wdin, stk.vp += wdout) {
        !           527:                dmaout(wdout, stk.vp+stkoff, &stk.cp);
        !           528:                stk.cp += exarg(stk.cp+stkoff, getupd(argp) & wdmask);
        !           529:        }
        !           530: 
        !           531:        /* skip null word after arguments */
        !           532:        stk.vp += wdout;
        !           533: 
        !           534:        /* Environments */
        !           535:        for (i = 0; i<env.np; i++, envp += wdin, stk.vp += wdout) {
        !           536:                dmaout(wdout, stk.vp+stkoff, &stk.cp);
        !           537:                stk.cp += exarg(stk.cp+stkoff, getupd(envp) & wdmask);
        !           538:        }
        !           539: 
        !           540:        return sp;
        !           541: }
        !           542: 
        !           543: exarg(out, in)
        !           544: vaddr_t        in, out;
        !           545: {
        !           546:        char    c;
        !           547:        vaddr_t init_in;
        !           548: 
        !           549:        init_in = in;
        !           550:        do {
        !           551:                c = getubd(in++);
        !           552:                dmaout(sizeof(char), out++, &c);
        !           553:        } while (c);
        !           554:        return in - init_in;
        !           555: }
        !           556: 
        !           557: 
        !           558: /*
        !           559:  * Given a pointer to a list of arguments, a pointer to an argument count
        !           560:  * and a pointer to a byte count, count the #characters/#strigns
        !           561:  * in the arguments
        !           562:  */
        !           563: excount(usrvp, adp, wdin)
        !           564: register vaddr_t usrvp;
        !           565: struct adata *adp;
        !           566: {
        !           567:        register vaddr_t        usrcp;
        !           568:        register int c;
        !           569:        register unsigned nb;
        !           570:        register unsigned na;
        !           571:        int     wdmask;
        !           572: 
        !           573:        wdmask = -1;
        !           574:        if (wdin==sizeof(short))
        !           575:                wdmask = (unsigned short)wdmask;
        !           576:        na = nb = 0;
        !           577:        if (usrvp != NULL) {
        !           578:                for (;;) {
        !           579:                        usrcp = getupd(usrvp) & wdmask;
        !           580:                        usrvp += wdin;
        !           581:                        if (u.u_error)
        !           582:                                return (0);
        !           583:                        if (usrcp == NULL)
        !           584:                                break;
        !           585:                        na++;
        !           586:                        for (;;) {
        !           587:                                c = getubd(usrcp++);
        !           588:                                if (u.u_error)
        !           589:                                        return (0);
        !           590:                                nb++;
        !           591:                                if (c == '\0')
        !           592:                                        break;
        !           593:                        }
        !           594:                }
        !           595:        }
        !           596:        adp->np = na;
        !           597:        adp->nc = nb;
        !           598:        return (1);
        !           599: }
        !           600: 
        !           601: /*
        !           602:  * Round up a size to a paragraph
        !           603:  * (mod 16) boundry.
        !           604:  * This is really mod 512 to make swapping work
        !           605:  */
        !           606: off_t
        !           607: exround(s)
        !           608: off_t  s;
        !           609: {
        !           610:        return ((s+15)&~0x0F);
        !           611: }
        !           612: 
        !           613: pload( np )
        !           614: char * np;
        !           615: {
        !           616:        return -1;
        !           617: 
        !           618: }
        !           619: /*
        !           620:  * Set up the first process, a small programme which will exec
        !           621:  * the init programme.
        !           622:  */
        !           623: eveinit()
        !           624: {
        !           625:        SEG *sp;
        !           626:        register PROC *pp;
        !           627:        SELF = pp = eprocp;
        !           628: /*     static struct xechdr xecinit[NUSEG+1] = { {0},{0},{0},{ISP_386}}; */ 
        !           629: 
        !           630:        /*
        !           631:         * Allocate, record, initialize code segment, make it executable.
        !           632:         */
        !           633:        if ((sp = salloc(roundu(icodes, NBPC), 0)) == NULL)
        !           634:                panic("eveinit(code)");
        !           635:        pp->p_segp[SIPDATA] = sp;
        !           636: 
        !           637:        /*
        !           638:         * Start process.
        !           639:         */
        !           640:        u.u_argp = 0;
        !           641:        if (sproto(0) == 0)
        !           642:                panic("eveinit()");
        !           643:        segload();
        !           644:        kucopy(icodep, 0, icodes);
        !           645: }
        !           646: 
        !           647: /*
        !           648:  * Given a major number, undo the previous function.
        !           649:  */
        !           650: puload(m)
        !           651: int m;
        !           652: {
        !           653:        register CON *cp;
        !           654:        register DRV *dp;
        !           655: 
        !           656:        dp = &drvl[m];
        !           657:        lock(dp->d_gate);
        !           658:        if (m>=drvn || (cp=dp->d_conp)==NULL) {
        !           659:                u.u_error = ENXIO;
        !           660:                goto ret;
        !           661:        }
        !           662:        (*cp->c_uload)();
        !           663:        if ( ! u.u_error)
        !           664:                dp->d_conp = NULL;
        !           665: ret:
        !           666:        unlock(dp->d_gate);
        !           667:        return (0);
        !           668: }
        !           669: 

unix.superglobalmegacorp.com

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