Annotation of coherent/d/PS2_KERNEL/coh.386/exec.c, revision 1.1.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.