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

1.1     ! root        1: /* $Header: /kernel/kersrc/i286/RCS/exec.c,v 1.1 92/07/17 15:21:27 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:  * This file contains a special version
        !            17:  * of "sys exec" for the i8086. This version has
        !            18:  * no driver load code in it (save space) and has
        !            19:  * special load code so that the text of a shared
        !            20:  * and separated image can be shared.
        !            21:  * Loadable kernel processes are partially supported:
        !            22:  * the process text and data must be ld'ed with the system
        !            23:  * and the l.out executed must have no loadable or allocateable
        !            24:  * segments.
        !            25:  *
        !            26:  * $Log:       exec.c,v $
        !            27:  * Revision 1.1  92/07/17  15:21:27  bin
        !            28:  * Initial revision
        !            29:  * 
        !            30:  * Revision 1.1        88/03/24  17:39:26      src
        !            31:  * Initial revision
        !            32:  * 
        !            33:  * 88/01/21    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !            34:  * Segments are now de-associated from processes before freeing the segment.
        !            35:  *
        !            36:  * 87/12/03    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !            37:  * ld_start() now reverts to kernel mode [depth=0] from user mode [depth=1].
        !            38:  *
        !            39:  * 87/11/25    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !            40:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !            41:  *
        !            42:  * 87/11/14    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !            43:  * Init code+data now split into icodep/icodes and idatap/idatas.
        !            44:  *
        !            45:  * 87/11/05    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !            46:  * New seg struct now used to allow extended addressing.
        !            47:  *
        !            48:  * 87/10/09    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !            49:  * pload() now handles new format [separate code] loadable device drivers.
        !            50:  *
        !            51:  * 87/10/08    Allan Cornish           /usr/src/sys/i8086/src/exec.c
        !            52:  * Exsread() initializes the (IO).io_flag field to 0.
        !            53:  */
        !            54: #include <sys/coherent.h>
        !            55: #include <acct.h>
        !            56: #include <sys/buf.h>
        !            57: #include <canon.h>
        !            58: #include <sys/con.h>
        !            59: #include <errno.h>
        !            60: #include <sys/filsys.h>
        !            61: #include <sys/ino.h>
        !            62: #include <sys/inode.h>
        !            63: #include <l.out.h>
        !            64: #include <sys/proc.h>
        !            65: #include <sys/sched.h>
        !            66: #include <sys/seg.h>
        !            67: #include <signal.h>
        !            68: #include <sys/i8086.h>
        !            69: 
        !            70: /*
        !            71:  * Sizes.
        !            72:  */
        !            73: #define        sh      ((fsize_t)sizeof(struct ldheader))
        !            74: #define si     lssize[L_SHRI]
        !            75: #define pi     lssize[L_PRVI]
        !            76: #define bi     lssize[L_BSSI]
        !            77: #define sd     lssize[L_SHRD]
        !            78: #define pd     lssize[L_PRVD]
        !            79: #define bd     lssize[L_BSSD]
        !            80: 
        !            81: /*
        !            82:  * Segments.
        !            83:  */
        !            84: #define upsp   pp->p_segp[SIUSERP]
        !            85: #define sssp   pp->p_segp[SISTACK]
        !            86: #define        sisp    pp->p_segp[SISTEXT]
        !            87: #define pisp   pp->p_segp[SIPTEXT]
        !            88: #define pdsp   pp->p_segp[SIPDATA]
        !            89: 
        !            90: /*
        !            91:  * Loadable driver initiation point.
        !            92:  */
        !            93: static
        !            94: ld_start()
        !            95: {
        !            96:        register SEG * sp;
        !            97:        register int ret;
        !            98: 
        !            99:        /*
        !           100:         * Kernel processes start by default at user level.
        !           101:         * Revert to kernel level.
        !           102:         */
        !           103:        if ( depth == 1 )
        !           104:                depth--;
        !           105: 
        !           106:        /*
        !           107:         * Initialize memory references.
        !           108:         */
        !           109:        u.u_btime = timer.t_time;
        !           110:        sproto();
        !           111:        segload();
        !           112: 
        !           113: 
        !           114:        /*
        !           115:         * Invoke the driver if it has a shared or private code segment.
        !           116:         */
        !           117:        ret = 100;
        !           118:        if ( (sp = SELF->p_segp[SISTEXT]) || (sp = SELF->p_segp[SIPTEXT]) ) {
        !           119:                ret = ld_xcall( sp->s_faddr );
        !           120:        }
        !           121: 
        !           122:        uexit( ret );
        !           123: }
        !           124: 
        !           125: /*
        !           126:  * Set up the first process, a small programme which will exec
        !           127:  * the init programme.
        !           128:  */
        !           129: eveinit(sp)
        !           130: SEG *sp;
        !           131: {
        !           132:        register PROC *pp;
        !           133:        SELF = pp = eprocp;
        !           134: 
        !           135:        /*
        !           136:         * Record user area.
        !           137:         */
        !           138:        pp->p_segp[SIUSERP] = sp;
        !           139: 
        !           140:        /*
        !           141:         * Allocate, record, initialize code segment, make it executable.
        !           142:         */
        !           143:        if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
        !           144:                panic("eveinit(code)");
        !           145:        pp->p_segp[SIPTEXT] = sp;
        !           146:        kfcopy( icodep, sp->s_faddr, icodes );
        !           147:        sp->s_flags |= SFTEXT;
        !           148:        vremap(sp);
        !           149: 
        !           150:        /*
        !           151:         * Allocate, record, and initialize data segment.
        !           152:         */
        !           153:        if ((sp=salloc((fsize_t)idatas, 0)) == NULL)
        !           154:                panic("eveinit(data)");
        !           155:        pp->p_segp[SIPDATA] = sp;
        !           156:        kfcopy( idatap, sp->s_faddr, idatas );
        !           157: 
        !           158:        /*
        !           159:         * Allocate and record stack segment.
        !           160:         */
        !           161:        if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
        !           162:                panic("eveinit()");
        !           163:        pp->p_segp[SISTACK] = sp;
        !           164: 
        !           165:        /*
        !           166:         * Start process.
        !           167:         */
        !           168:        u.u_argp = 0;
        !           169:        if (sproto() == 0)
        !           170:                panic("eveinit()");
        !           171:        segload();
        !           172: }
        !           173: 
        !           174: /*
        !           175:  * Load a driver which has already been linked into the system image.
        !           176:  */
        !           177: pload( np )
        !           178: char * np;
        !           179: {
        !           180:        register INODE * ip;
        !           181:        register PROC  * cpp;
        !           182:        struct seg     * sp;
        !           183:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !           184:        int             lflag;                  /* l_flags from l.out */
        !           185:        vaddr_t         pc;                     /* l_entry from l.out */
        !           186:        int             r;                      /* Flag for "exload" */
        !           187:        int             s;
        !           188:        extern char     end[];
        !           189: 
        !           190: 
        !           191:        if (super() == 0) {
        !           192:                return( -1 );
        !           193:        }
        !           194: 
        !           195:        /*
        !           196:         * Coalesce memory BEFORE loading driver, since it can't be moved.
        !           197:         */
        !           198:        krunch(10000);
        !           199: 
        !           200:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL) {
        !           201:                return( -1 );
        !           202:        }
        !           203: 
        !           204:        /*
        !           205:         * New format loadable drivers must have separate code/data.
        !           206:         * It must have executable code, but no initialized data.
        !           207:         * Uninitialized data must match the kernel data size.
        !           208:         */
        !           209:        if ( ((lflag & (LF_KER|LF_SHR|LF_SEP)) != (LF_SEP|LF_KER))
        !           210:          || (si==0) || (sd!=0) || (pd!=0) || (bd != (int)end) ) {
        !           211:                u.u_error = EBADFMT;
        !           212:                idetach(ip);
        !           213:                return( -1 );
        !           214:        }
        !           215: 
        !           216:        /*
        !           217:         * Allocate and initialize driver code segment.
        !           218:         * NOTE: Must be system segment to prevent relocation.
        !           219:         */
        !           220:        sp = ssalloc(&r, ip, SFTEXT|SFHIGH|SFNSWP|SFSYST, si+pi+bi, sh, si+pi);
        !           221: 
        !           222:        /*
        !           223:         * Release driver object file.
        !           224:         */
        !           225:        idetach(ip);
        !           226: 
        !           227:        if ( r < 0 ) {
        !           228:                u.u_error = ENOMEM;
        !           229:                return( -1 );
        !           230:        }
        !           231: 
        !           232:        /*
        !           233:         * Spawn kernel process to service driver.
        !           234:         */
        !           235:        if ((cpp = process(ld_start)) == NULL ) {
        !           236:                u.u_error = ENOMEM;
        !           237:                sfree(sp);
        !           238:                return( -1 );
        !           239:        }
        !           240: 
        !           241:        /*
        !           242:         * Record the basename of the loaded driver.
        !           243:         */
        !           244:        kscopy( u.u_direct.d_name, cpp->p_segp[SIUSERP],
        !           245:                offset(uproc,u_comm[0]), sizeof(u.u_comm) );
        !           246: 
        !           247:        /*
        !           248:         * Record the driver code segment in the process's private code.
        !           249:         */
        !           250:        cpp->p_segp[SIPTEXT] = sp;
        !           251:        cpp->p_cval = CVCHILD;
        !           252:        cpp->p_sval = SVCHILD;
        !           253:        cpp->p_rval = RVCHILD;
        !           254:        cpp->p_ppid = 1;
        !           255: 
        !           256:        /*
        !           257:         * Make the process executable.
        !           258:         */
        !           259:        s = sphi();
        !           260:        setrun( cpp );
        !           261:        spl( s );
        !           262: 
        !           263:        /*
        !           264:         * Return driver process id.
        !           265:         */
        !           266:        return( cpp->p_pid );
        !           267: }
        !           268: 
        !           269: /*
        !           270:  * Given a major number, undo the previous function.
        !           271:  */
        !           272: puload(m)
        !           273: int m;
        !           274: {
        !           275:        register CON *cp;
        !           276:        register DRV *dp;
        !           277: 
        !           278:        dp = &drvl[m];
        !           279:        lock(dp->d_gate);
        !           280:        if (m>=drvn || (cp=dp->d_conp)==NULL) {
        !           281:                u.u_error = ENXIO;
        !           282:                goto ret;
        !           283:        }
        !           284:        (*cp->c_uload)();
        !           285:        if ( ! u.u_error)
        !           286:                dp->d_conp = NULL;
        !           287: ret:
        !           288:        unlock(dp->d_gate);
        !           289:        return (0);
        !           290: }
        !           291: 
        !           292: /*
        !           293:  * Pass control to an image in a file.
        !           294:  * Make sure the format is acceptable. Release
        !           295:  * the old segments. Read in the new ones. Some special
        !           296:  * care is taken so that shared and (more important) shared
        !           297:  * and separated images can be run on the 8086.
        !           298:  */
        !           299: pexece(np, argp, envp)
        !           300: char   *np;
        !           301: char   *argp[];
        !           302: char   *envp[];
        !           303: {
        !           304:        register INODE  *ip;                    /* Load file INODE */
        !           305:        register PROC   *pp;                    /* A cheap copy of SELF */
        !           306:        register SEG    *ssp;                   /* New stack segment */
        !           307:        register SEG    *segp;
        !           308:        register fsize_t        ss;                     /* Segment size temp. */
        !           309:        register int    i;                      /* For looping over segments */
        !           310:        int             r;                      /* Flag for "exload" */
        !           311:        int             lflag;                  /* l_flags from l.out */
        !           312:        vaddr_t         pc;                     /* l_entry from l.out */
        !           313:        vaddr_t         sp;                     /* Initial stack pointer */
        !           314:        fsize_t         lssize[NUSEG];          /* Segment sizes */
        !           315:        fsize_t         codsize;                /* Total if CS segment  */
        !           316:        fsize_t         datsize;                /* Total of DS segment  */
        !           317:        extern fsize_t  exround();              /* Paragraph rounder */
        !           318: 
        !           319:        pp = SELF;
        !           320:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL) {
        !           321:                return;
        !           322:        }
        !           323: 
        !           324:        if ( (lflag & LF_SEP) == 0 ) {
        !           325:                u.u_error = EBADFMT;
        !           326:                idetach(ip);
        !           327:                return;
        !           328:        }
        !           329: 
        !           330:        /*
        !           331:         * Kernel processes are now supported through the sload() system call.
        !           332:         * 87/10/09     Allan Cornish.
        !           333:         */
        !           334:        if ((lflag&LF_KER) != 0) {
        !           335:                u.u_error = EBADFMT;
        !           336:                idetach(ip);
        !           337:                return;
        !           338:        }
        !           339: 
        !           340:        /*
        !           341:         * If a shared and separated image
        !           342:         * has stuff in segments that makes it impossible
        !           343:         * to share, give an error immediately so that we don't
        !           344:         * lose the parent.
        !           345:         */
        !           346:        lflag &= LF_SHR|LF_SEP;
        !           347: 
        !           348:        if (lflag==(LF_SHR|LF_SEP) && (pi!=0 || bi!=0)) {
        !           349:                u.u_error = EBADFMT;
        !           350:                idetach(ip);
        !           351:                return;
        !           352:        }
        !           353: 
        !           354:        if ((ssp=exstack(&sp, argp, envp)) == NULL) {
        !           355:                idetach(ip);
        !           356:                return;
        !           357:        }
        !           358: 
        !           359:        switch (lflag) {
        !           360:        case LF_SEP:
        !           361:                codsize = si+pi+bi;
        !           362:                datsize = ssp->s_size+sd+pd+bd;
        !           363:                break;
        !           364:        case LF_SHR|LF_SEP:
        !           365:                codsize = si;
        !           366:                datsize = ssp->s_size+exround(sd)+pd+bd;
        !           367:                break;
        !           368:        }
        !           369:        codsize = (codsize+(BSIZE-1)) & ~(BSIZE-1);
        !           370:        datsize = (datsize+(BSIZE-1)) & ~(BSIZE-1);
        !           371:        if ( (codsize >= MAXU) || (datsize >= MAXU) ) {
        !           372:                u.u_error = E2BIG;
        !           373:                idetach(ip);
        !           374:                return;
        !           375:        }
        !           376: 
        !           377:        /*
        !           378:         * At this point the file has been
        !           379:         * validated as an object module, and the
        !           380:         * argument list has been built. Release all of
        !           381:         * the original segments. At this point we have
        !           382:         * committed to the new image. A "sys exec" that
        !           383:         * gets an I/O error is doomed.
        !           384:         * NOTE: User-area segment is NOT released.
        !           385:         *       Segment pointer in proc is erased BEFORE invoking sfree().
        !           386:         */
        !           387:        for ( i = 1; i < NUSEG; ++i ) {
        !           388:                if ((segp = pp->p_segp[i]) != NULL) {
        !           389:                        pp->p_segp[i] = NULL;
        !           390:                        sfree(segp);
        !           391:                }
        !           392:        }
        !           393: 
        !           394:        /*
        !           395:         * Read in the loadable segments.
        !           396:         */
        !           397:        sssp = ssp;
        !           398:        switch (lflag) {
        !           399:        case 0:
        !           400:                ss = si+pi+sd+pd;
        !           401:                pdsp = ssalloc(&r, ip, 0, ss+bi+bd, sh, ss);
        !           402:                if (r < 0)
        !           403:                        goto out;
        !           404:                break;
        !           405: 
        !           406:        case LF_SHR:
        !           407:                ss = exround(si+sd);
        !           408:                pdsp = ssalloc(&r, ip, 0, ss+pi+pd+bi+bd, sh, si);
        !           409:                if (r < 0)
        !           410:                        goto out;
        !           411:                if (exsread(pdsp, ip, sd, sh+si+pi, si) == NULL)
        !           412:                        goto out;
        !           413:                if (exsread(pdsp, ip, pi, sh+si, ss) == NULL)
        !           414:                        goto out;
        !           415:                if (exsread(pdsp, ip, pd, sh+si+pi+sd, ss+pi) == NULL)
        !           416:                        goto out;
        !           417:                break;
        !           418: 
        !           419:        case LF_SEP:
        !           420:                pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
        !           421:                if (r < 0)
        !           422:                        goto out;
        !           423:                pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+pi, sd+pd);
        !           424:                if (r < 0)
        !           425:                        goto out;
        !           426:                break;
        !           427: 
        !           428:        case LF_SHR|LF_SEP:
        !           429:                /* pi=0, bi=0 */
        !           430:                sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
        !           431:                if (r < 0)
        !           432:                        goto out;
        !           433:                ss = exround(sd);
        !           434:                pdsp = ssalloc(&r, ip, 0, ss+pd+bd, sh+si, sd);
        !           435:                if (r<0 || exsread(pdsp, ip, pd, sh+si+sd, ss) == NULL)
        !           436:                        goto out;
        !           437:        }
        !           438:        if (sproto() == 0)
        !           439:                 goto out;
        !           440: #if 0
        !           441:        if ( (datsize != pdsp->s_size) ||
        !           442:             ( (lflag==LF_SEP) && (codsize != pisp->s_size) ) ||
        !           443:             ( (lflag==(LF_SEP|LF_SHR)) && (codsize != sisp->s_size) ) ) {
        !           444:                printf("\nExec ERROR:  codsize: 0x%X  datsize: 0x%X\n", 
        !           445:                                        codsize, datsize);
        !           446:                printf(
        !           447:                "pdsp->s_size: 0x%X  pisp->s_size: 0x%X  sisp->s_size: 0x%X\n",
        !           448:                        pdsp->s_size, pisp->s_size, sisp->s_size);
        !           449:        }
        !           450: #endif
        !           451:        /*
        !           452:         * The new image is read in
        !           453:         * and mapped. Perform the final grunge
        !           454:         * (set-uid stuff, accounting, loading up
        !           455:         * registers, etc).
        !           456:         */
        !           457:        u.u_flag &= ~AFORK;
        !           458:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
        !           459:        if (iaccess(ip, IPR) == 0) {    /* Can't read ? no dump or trace */
        !           460:                pp->p_flags |= PFNDMP;
        !           461:                pp->p_flags &= ~PFTRAC;
        !           462:        }
        !           463:        if (iaccess(ip, IPW) == 0)      /* Can't write ? no trace */
        !           464:                pp->p_flags &= ~PFTRAC;
        !           465:        if ((ip->i_mode&ISUID) != 0) {  /* Set user id ? no trace */
        !           466:                pp->p_uid = u.u_uid = ip->i_uid;
        !           467:                pp->p_flags &= ~PFTRAC;
        !           468:        }
        !           469:        if ((ip->i_mode&ISGID) != 0) {  /* Set group id ? no trace */
        !           470:                u.u_gid = ip->i_gid;
        !           471:                pp->p_flags &= ~PFTRAC;
        !           472:        }
        !           473:        for (i=0; i<NSIG; ++i)
        !           474:                if (u.u_sfunc[i] != SIG_IGN)
        !           475:                        u.u_sfunc[i] = SIG_DFL;
        !           476:        if ((pp->p_flags&PFTRAC) != 0)  /* Being traced */
        !           477:                sendsig(SIGTRAP, pp);
        !           478:        idetach(ip);
        !           479:        msetusr(pc, sp);
        !           480:        segload();
        !           481:        return (0);
        !           482: 
        !           483:        /*
        !           484:         * We did not make it.
        !           485:         * Release the INODE for the load
        !           486:         * file, and return through the "sys exit"
        !           487:         * code with a "SIGSYS", or with the signal actually received
        !           488:         * if we are aborting due to interrupted exec.
        !           489:         */
        !           490: out:
        !           491:        idetach(ip);
        !           492:        if (u.u_error == EINTR)
        !           493:                pexit(nondsig());
        !           494:        pexit(SIGSYS);
        !           495: }
        !           496: 
        !           497: /*
        !           498:  * Open an l.out, make sure it is an l.out and executable and return the
        !           499:  * appropriate information.
        !           500:  */
        !           501: INODE *
        !           502: exlopen(np, ssizep, flagp, pcp)
        !           503: char *np;
        !           504: fsize_t *ssizep;
        !           505: int *flagp;
        !           506: vaddr_t *pcp;
        !           507: {
        !           508:        register INODE *ip;
        !           509:        register struct ldheader *ldp;
        !           510:        register int n;
        !           511:        register BUF *bp;
        !           512:        int m;
        !           513: 
        !           514:        /*
        !           515:         * Make sure the file is really an executable l.out and read the
        !           516:         * header in.
        !           517:         */
        !           518:        if (ftoi(np, 'r') != 0)
        !           519:                return (NULL);
        !           520:        ip = u.u_cdiri;
        !           521:        if (iaccess(ip, IPE) == 0) {
        !           522:                idetach(ip);
        !           523:                return (NULL);
        !           524:        }
        !           525:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
        !           526:                u.u_error = EACCES;
        !           527:                idetach(ip);
        !           528:                return (NULL);
        !           529:        }
        !           530:        if ((bp=vread(ip, (daddr_t)0)) == NULL) {
        !           531:                u.u_error = EBADFMT;
        !           532:                idetach(ip);
        !           533:                return (NULL);
        !           534:        }
        !           535: 
        !           536:        /*
        !           537:         * Copy everything we need from the l.out header and check magic
        !           538:         * number and machine type.
        !           539:         */
        !           540:        ldp = FP_OFF(bp->b_faddr);
        !           541:        m = ldp->l_magic;
        !           542:        canint(m);
        !           543:        if (m != L_MAGIC) {
        !           544:                u.u_error = ENOEXEC;
        !           545:                brelease(bp);
        !           546:                idetach(ip);
        !           547:                return (NULL);
        !           548:        }
        !           549:        m = ldp->l_machine;
        !           550:        canint(m);
        !           551:        if (m != mactype) {
        !           552:                u.u_error = EBADFMT;
        !           553:                brelease(bp);
        !           554:                idetach(ip);
        !           555:                return (NULL);
        !           556:        }
        !           557:        kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
        !           558:        for (n=0; n<NXSEG; n++)
        !           559:                cansize(ssizep[n]);
        !           560:        *flagp = ldp->l_flag;
        !           561:        canint(*flagp);
        !           562:        *pcp = ldp->l_entry;
        !           563:        canvaddr(*pcp);
        !           564:        brelease(bp);
        !           565:        return (ip);
        !           566: }
        !           567: 
        !           568: /*
        !           569:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
        !           570:  * at seek address `sa' into offset `so' in the segment.
        !           571:  */
        !           572: SEG *
        !           573: exsread(sp, ip, ss, sa, so)
        !           574: register SEG *sp;
        !           575: INODE *ip;
        !           576: fsize_t ss;
        !           577: fsize_t sa;
        !           578: fsize_t so;
        !           579: {
        !           580:        while (ss > 0) {
        !           581:                u.u_io.io_seg = IOPHY;
        !           582:                u.u_io.io_seek = sa;
        !           583:                u.u_io.io_phys = sp->s_paddr + so;
        !           584:                u.u_io.io_flag = 0;
        !           585:                if (ss >= 4096) {
        !           586:                        u.u_io.io_ioc = 4096;
        !           587:                        ss -= 4096;
        !           588:                } else {
        !           589:                        u.u_io.io_ioc = ss;
        !           590:                        ss = 0;
        !           591:                }
        !           592:                sp->s_lrefc++;
        !           593:                iread(ip, &u.u_io);
        !           594:                sp->s_lrefc--;
        !           595:                if (nondsig()) {
        !           596:                        u.u_error = EINTR;
        !           597:                        break;
        !           598:                }
        !           599:                sa += 4096;
        !           600:                so += 4096;
        !           601:        }
        !           602:        if (u.u_error == 0)
        !           603:                return (sp);
        !           604:        return (NULL);
        !           605: }
        !           606: 
        !           607: /*
        !           608:  * Given a pointer to a list of arguments and a pointer to a list of
        !           609:  * environments, return a stack with the arguments and environments on it.
        !           610:  */
        !           611: SEG *
        !           612: exstack(iusp, argp, envp)
        !           613: char **iusp;           /* Back patch sp value */
        !           614: char *argp[];          /* Arguments for new process */
        !           615: char *envp[];          /* Environments for new process */
        !           616: {
        !           617:        SEG *sp;                /* Stack segment pointer */
        !           618:        struct adata {          /* Storage for arg and env data */
        !           619:                char    **up;           /* User vector pointer */
        !           620:                int     np;             /* Number of pointers in vector */
        !           621:                int     nc;             /* Number of characters in strings */
        !           622:        } arg, env;
        !           623:        struct sdata {          /* To keep segment pointers */
        !           624:                vaddr_t base;           /* Top of segment virtual */
        !           625:                vaddr_t ap;             /* Argc, argv, envp pointer */
        !           626:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
        !           627:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
        !           628:        } aux, stk;
        !           629:        aold_t aold;                    /* Auxiliary map storage */
        !           630:        register char **usrvp;          /* Vector pointer into user seg */
        !           631:        register char *usrcp;           /* Character pointer into user seg */
        !           632:        register int c;                 /* Character fetched from user */
        !           633:        register int chrsz;             /* Size of strings */
        !           634:        register struct adata *adp;     /* Arg and env scanner */
        !           635:        register int vecsz;             /* Size of vectors */
        !           636:        register int stksz;             /* Size of stack argument region */
        !           637: 
        !           638:        /* Validate and evaluate size of args and envs */
        !           639:        arg.up = argp;
        !           640:        env.up = envp;
        !           641:        chrsz = 0;
        !           642:        vecsz = 0;
        !           643:        for (adp = &arg; ; adp = &env) {
        !           644:                adp->np = 0;
        !           645:                adp->nc = 0;
        !           646:                if (excount(adp->up, &adp->np, &adp->nc) == 0)
        !           647:                        return (NULL);
        !           648:                chrsz += adp->nc * sizeof(char);
        !           649:                vecsz += adp->np * sizeof(char *);
        !           650:                if (adp == &env)
        !           651:                        break;
        !           652:        }
        !           653: 
        !           654:        /* Calculate stack size and allocate it */
        !           655:        chrsz = roundu(chrsz, sizeof(int));
        !           656:        stksz = sizeof(int)             /* argc */
        !           657:                + sizeof(char **)       /* argv */
        !           658:                + sizeof(char **)       /* envp */
        !           659:                + vecsz                 /* argv[i] and envp[i] */
        !           660:                + chrsz                 /* *argv[i] and *envp[i] */
        !           661:                + sizeof(int)           /* Mystery zero word */
        !           662:                + sizeof(char *)        /* Splimit for z8000 */
        !           663:                + sizeof(int);          /* errno */
        !           664:        stksz += ISTSIZE;
        !           665:        if (stksz > MADSIZE) {
        !           666:                u.u_error = E2BIG;
        !           667:                return (NULL);
        !           668:        }
        !           669:        if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
        !           670:                return (NULL);
        !           671:        stksz -= ISTSIZE;
        !           672: 
        !           673:        /*
        !           674:         * Initialize segment data.
        !           675:         */
        !           676:        asave(aold);
        !           677: 
        !           678:        abase(FP_SEL(sp->s_faddr));
        !           679:        aux.base = sp->s_size;
        !           680:        aux.ap = aux.base - stksz;
        !           681:        aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
        !           682:        aux.cp = aux.vp + vecsz;
        !           683: 
        !           684:        stk.base = ISTVIRT;
        !           685:        stk.ap = stk.base - stksz;
        !           686:        stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
        !           687:        stk.cp = stk.vp + vecsz;
        !           688: 
        !           689:        /*
        !           690:         * Write argc.
        !           691:         */
        !           692:        aputi((int *)aux.ap, arg.np-1);
        !           693:        aux.ap += sizeof(int);
        !           694: 
        !           695:        /*
        !           696:         * Arguments and environments.
        !           697:         */
        !           698:        for (adp = &arg; ; adp = &env) {
        !           699: 
        !           700:                /* Write argv or envp */
        !           701:                aputp((char ***)aux.ap, (char **)stk.vp);
        !           702:                aux.ap += sizeof(char **);
        !           703:                if ((usrvp = adp->up) != NULL) {
        !           704: 
        !           705:                        /* Write argv[i] or envp[i] */
        !           706:                        while ((usrcp = getupd(usrvp++)) != NULL) {
        !           707:                                aputp((char **)aux.vp, (char *)stk.cp);
        !           708:                                aux.vp += sizeof(char *);
        !           709:                                stk.vp += sizeof(char *);
        !           710: 
        !           711:                                /* Write argv[i][j] or envp[i][j] */
        !           712:                                do {
        !           713:                                        c = getubd(usrcp++);
        !           714:                                        aputc((char *)aux.cp, c);
        !           715:                                        aux.cp += sizeof(char);
        !           716:                                        stk.cp += sizeof(char);
        !           717:                                } while (c != '\0');
        !           718:                        }
        !           719:                }
        !           720: 
        !           721:                /* Write argv[argc] or envp[envc] */
        !           722:                aputp((char **)aux.vp, NULL);
        !           723:                aux.vp += sizeof(char *);
        !           724:                stk.vp += sizeof(char *);
        !           725:                if (adp == &env)
        !           726:                        break;
        !           727:        }
        !           728: 
        !           729:        /*
        !           730:         * Clear out the slop.
        !           731:         */
        !           732:        aux.base -= sizeof(int);
        !           733:        aputi((int *) aux.base, 0);             /* errno */
        !           734:        aux.base -= sizeof(char *);
        !           735:        aputp((char **) aux.base, (char *)stk.base - sp->s_size + SOVSIZE);
        !           736:        aux.base -= sizeof(int);
        !           737:        aputi((int *) aux.base, 0);             /* mystery word */
        !           738: 
        !           739:        arest(aold);
        !           740: 
        !           741:        /*
        !           742:         * Patch some values and return.
        !           743:         */
        !           744:        *iusp = stk.ap;         /* Patch initial usp */
        !           745:        u.u_argc = arg.np-1;
        !           746:        u.u_argp = stk.vp;      /* Points after NULL of envs */
        !           747:        return (sp);
        !           748: }
        !           749: 
        !           750: /*
        !           751:  * Given a pointer to a list of arguments, a pointer to an argument count
        !           752:  * and a pointer to a byte count, update incrementally the argument count
        !           753:  * and the byte count.
        !           754:  */
        !           755: excount(usrvp, nap, nbp)
        !           756: register char **usrvp;
        !           757: int *nap;
        !           758: int *nbp;
        !           759: {
        !           760:        register char *usrcp;
        !           761:        register int c;
        !           762:        register unsigned nb;
        !           763:        register unsigned na;
        !           764: 
        !           765:        na = 1;
        !           766:        nb = 0;
        !           767:        if (usrvp != NULL) {
        !           768:                for (;;) {
        !           769:                        usrcp = getupd(usrvp++);
        !           770:                        if (u.u_error)
        !           771:                                return (0);
        !           772:                        if (usrcp == NULL)
        !           773:                                break;
        !           774:                        na++;
        !           775:                        for (;;) {
        !           776:                                c = getubd(usrcp++);
        !           777:                                if (u.u_error)
        !           778:                                        return (0);
        !           779:                                nb++;
        !           780:                                if (c == '\0')
        !           781:                                        break;
        !           782:                        }
        !           783:                }
        !           784:        }
        !           785:        *nap += na;
        !           786:        *nbp += nb;
        !           787:        return (1);
        !           788: }
        !           789: 
        !           790: /*
        !           791:  * Round up a size to a paragraph
        !           792:  * (mod 16) boundry.
        !           793:  * This is really mod 512 to make swapping work
        !           794:  */
        !           795: fsize_t
        !           796: exround(s)
        !           797: fsize_t        s;
        !           798: {
        !           799:        return ((s+15)&~0x0F);
        !           800: }

unix.superglobalmegacorp.com

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