Annotation of 43BSD/ucb/lisp/franz/ffasl.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *rcsid =
        !             3:    "$Header: ffasl.c,v 1.10 83/12/09 16:45:04 sklower Exp $";
        !             4: #endif
        !             5: 
        !             6: /*                                     -[Mon Mar 21 19:37:21 1983 by jkf]-
        !             7:  *     ffasl.c                         $Locker:  $
        !             8:  * dynamically load C code
        !             9:  *
        !            10:  * (c) copyright 1982, Regents of the University of California
        !            11:  */
        !            12: 
        !            13: 
        !            14: #include "global.h"
        !            15: #include <sys/types.h>
        !            16: #include <sys/stat.h>
        !            17: #include <aout.h>
        !            18: #define round(x,s) ((((x)-1) & ~((s)-1)) + (s))
        !            19: 
        !            20: char *stabf = 0, *strcpy(), *sprintf(), *Ilibdir();
        !            21: extern int fvirgin;
        !            22: static seed=0, mypid = 0;
        !            23: static char myname[100];
        !            24: lispval verify();
        !            25: 
        !            26: /* dispget - get discipline of function
        !            27:  * this is used to handle the tricky defaulting of the discipline
        !            28:  * field of such functions as cfasl and getaddress.
        !            29:  * dispget is given the value supplied by the caller,
        !            30:  *     the error message to print if something goes wrong,
        !            31:  *     the default to use if nil was supplied.
        !            32:  * the discipline can be an atom or string.  If an atom it is supplied
        !            33:  * it must be lambda, nlambda or macro.  Otherwise the atoms pname
        !            34:  * is used.
        !            35:  */
        !            36: 
        !            37: lispval 
        !            38: dispget(given,messg,defult)
        !            39: lispval given,defult;
        !            40: char *messg;
        !            41: {
        !            42:        int typ;
        !            43: 
        !            44:        while(TRUE)
        !            45:        {
        !            46:                if(given == nil) 
        !            47:                   return(defult);
        !            48:                if((typ=TYPE(given)) == ATOM)
        !            49:                {  if(given == lambda ||
        !            50:                      given == nlambda ||
        !            51:                      given == macro) return(given);
        !            52:                   else return((lispval) given->a.pname);
        !            53:                } else if(typ == STRNG) return(given);
        !            54: 
        !            55:                given = errorh1(Vermisc,messg,nil,TRUE,0,given);
        !            56:        }
        !            57: }
        !            58: 
        !            59: lispval
        !            60: Lcfasl(){
        !            61:        register struct argent *mlbot = lbot;
        !            62:        register lispval work;
        !            63:        register int fildes, totsize;
        !            64:        int readsize;
        !            65:        lispval csegment();
        !            66:        char *sbrk(), *currend, *tfile, cbuf[6000], *mytemp(), *gstab();
        !            67:        char ostabf[128];
        !            68:        struct exec header;
        !            69:        char *largs;
        !            70:        Savestack(4);
        !            71: 
        !            72:        switch(np-lbot) {
        !            73:           case 3: protect(nil);        /* no discipline given */
        !            74:           case 4: protect(nil);        /* no library given  */
        !            75:        }
        !            76:        chkarg(5,"cfasl");
        !            77:        mlbot[0].val = verify(mlbot[0].val,"Incorrect .o file specification");
        !            78:        mlbot[1].val = verify(mlbot[1].val,"Incorrect entry specification for cfasl");
        !            79:        mlbot[3].val = dispget(mlbot[3].val,"Incorrect discipline specification for cfasl",(lispval)Vsubrou->a.pname);
        !            80:        while(TYPE(mlbot[2].val)!= ATOM) 
        !            81:        mlbot[2].val = errorh1(Vermisc,"Bad associated atom name for fasl",
        !            82:                                                 nil,TRUE,0,mlbot[2].val);
        !            83:        work = mlbot[4].val;
        !            84:        if(work==nil)
        !            85:                largs = 0;
        !            86:        else 
        !            87:                largs = (char *) verify(work,"Bad loader flags");
        !            88: 
        !            89:        /*
        !            90:         * Invoke loader.
        !            91:         */
        !            92:        strcpy(ostabf,gstab());
        !            93:        currend = sbrk(0);
        !            94: #if (!os_vms) | EUNICE_UNIX_OBJECT_FILE_CFASL
        !            95:                        /*** UNIX cfasl code ***/
        !            96:        tfile = mytemp();
        !            97:        sprintf(cbuf,
        !            98:                "%s/nld -N -x -A %s -T %x %s -e %s -o %s %s -lc",
        !            99:                Ilibdir(),
        !           100:                ostabf,
        !           101:                currend,
        !           102:                mlbot[0].val,
        !           103:                mlbot[1].val,
        !           104:                tfile,
        !           105:                largs);
        !           106:        /* if nil don't print cfasl/nld message */
        !           107:        if ( Vldprt->a.clb != nil ) {
        !           108:                printf(cbuf);
        !           109:                putchar('\n'); fflush(stdout);
        !           110:        }
        !           111:        if(system(cbuf)!=0) {
        !           112:                unlink(tfile);
        !           113:                ungstab();
        !           114:                fprintf(stderr,"Ld returns error status\n");
        !           115:                Restorestack();
        !           116:                return(nil);
        !           117:        }
        !           118:        if(fvirgin)
        !           119:                fvirgin = 0;
        !           120:        else
        !           121:                unlink(ostabf);
        !           122:        stabf = tfile;
        !           123:        if((fildes = open(tfile,0))<0) {
        !           124:                fprintf(stderr,"Couldn't open temporary file: %s\n",tfile);
        !           125:                Restorestack();
        !           126:                return(nil);
        !           127:        }
        !           128:        /*
        !           129:         * Read a.out header to find out how much room to
        !           130:         * allocate and attempt to do so.
        !           131:         */
        !           132:        if(read(fildes,(char *)&header,sizeof(header)) <= 0) {
        !           133:                close(fildes);
        !           134:                Restorestack();
        !           135:                return(nil);
        !           136:        }
        !           137:        readsize = round(header.a_text,4) + round(header.a_data,4);
        !           138:        totsize  = readsize + header.a_bss;
        !           139:        totsize  = round(totsize,512);
        !           140:        /*
        !           141:         * Fix up system indicators, typing info, etc.
        !           142:         */
        !           143:        currend = (char *)csegment(OTHER,totsize,FALSE);
        !           144:        
        !           145:        if(readsize!=read(fildes,currend,readsize))
        !           146:                {close(fildes);Restorestack(); return(nil);}
        !           147:        work = newfunct();
        !           148:        work->bcd.start = (lispval (*)())header.a_entry;
        !           149:        work->bcd.discipline = mlbot[3].val;
        !           150:        close(fildes);
        !           151:        Restorestack();
        !           152:        return(mlbot[2].val->a.fnbnd = work);
        !           153: #else
        !           154:                        /*** VMS cfasl code ***/
        !           155:        {
        !           156:          int pid = getpid() & 0xffff;  /* Our process ID number */
        !           157:          char objfil[100];             /* Absolute object file name */
        !           158:          char symfil[100];             /* Old symbol table file */
        !           159:          char filename[100];           /* Random filename buffer */
        !           160:          int strlen();                 /* String length function */
        !           161:          int cvt_unix_to_vms();        /* Convert UNIX to VMS filename */
        !           162:          lispval Lgetaddress(),matom();
        !           163:          struct stat stbuf;
        !           164: 
        !           165:          if (largs == 0) largs = " ";
        !           166:          sprintf(objfil,"tmp:cfasl%d.tmp",pid);
        !           167:          symfil[cvt_unix_to_vms(ostabf,symfil)] = 0;
        !           168:          sprintf(cbuf,                                 /* Create link cmd. */
        !           169:                "$ link/exe=%s/nom/syst=%%X%x/sym=tmp:sym%d.new %s,%s%s",
        !           170:                objfil,
        !           171:                currend,
        !           172:                pid,
        !           173:                mlbot[0].val,
        !           174:                symfil,
        !           175:                largs);
        !           176:          printf(                                       /* Echo link cmd. */
        !           177:                "$ link/exe=%s/nomap/system=%%X%x/symbol_table=tmp:sym%d.new %s,%s%s\n",
        !           178:                objfil,
        !           179:                currend,
        !           180:                pid,
        !           181:                mlbot[0].val,
        !           182:                symfil,
        !           183:                largs);
        !           184:          fflush(stdout);
        !           185:          vms_system(cbuf,0);
        !           186: 
        !           187:          if ((fildes = open(objfil,0)) < 0) /* Open abs file */
        !           188:                {Restorestack(); return(nil);}
        !           189:          fstat(fildes,&stbuf);                         /* Get its size */
        !           190:          readsize=stbuf.st_size;
        !           191:          currend = (char *)csegment(OTHER,readsize,FALSE);
        !           192:          readsize = read(fildes,currend,10000000);
        !           193:          close(fildes);
        !           194:          /*
        !           195:           * Delete the absolute object file
        !           196:           */
        !           197:          unlink(objfil);
        !           198:          /*
        !           199:           * Delete the old symbol table (if temporary)
        !           200:           */
        !           201:          unlink(sprintf(filename,"tmp:sym%d.stb",pid));
        !           202:          /*
        !           203:           * Rename the new symbol table so it is now the old symbol table
        !           204:           */
        !           205:          link(sprintf(symfil,"tmp:sym%d.new",pid),filename);
        !           206:          unlink(symfil);
        !           207:          sprintf(myname,"tmp:sym%d.stb",pid);
        !           208:          stabf = myname;
        !           209:          /*
        !           210:           * Return  Lgetaddress(entry,function_name,discipline)
        !           211:           */
        !           212:          {
        !           213:             struct argent *oldlbot, *oldnp;
        !           214:             lispval result;
        !           215: 
        !           216:             oldlbot = lbot;
        !           217:             oldnp = np;
        !           218:             lbot = np;
        !           219:             np++->val = matom(mlbot[1].val);
        !           220:             np++->val = mlbot[2].val;
        !           221:             np++->val = matom(mlbot[3].val);
        !           222:             result = Lgetaddress();
        !           223:             lbot = oldlbot;
        !           224:             np = oldnp;
        !           225:             return(result);
        !           226:          }
        !           227:        }
        !           228: #endif
        !           229: }
        !           230: #ifdef os_vms
        !           231: #define M 4
        !           232: #else
        !           233: #define M 1
        !           234: #endif
        !           235: #define oktox(n) \
        !           236:        (0==stat(n,&stbuf)&&(stbuf.st_mode&S_IFMT)==S_IFREG&&0==access(n,M))
        !           237: char *
        !           238: gstab()
        !           239: {
        !           240:        register char *cp, *cp2; char *getenv();
        !           241:        struct stat stbuf;
        !           242:        extern char **Xargv;
        !           243: 
        !           244:        if(stabf==0) {
        !           245:                cp = getenv("PATH");
        !           246:                if(cp==0)
        !           247:                        cp=":/usr/ucb:/bin:/usr/bin";
        !           248:                if(*cp==':'||*Xargv[0]=='/') {
        !           249:                        cp++;
        !           250:                        if(oktox(Xargv[0])) {
        !           251:                                strcpy(myname,Xargv[0]);
        !           252:                                return(stabf = myname);
        !           253:                        }
        !           254: #ifdef os_vms
        !           255:                        /*
        !           256:                         *      Try Xargv[0] with ".stb" concatenated
        !           257:                         */
        !           258:                        strcpy(myname,Xargv[0]);
        !           259:                        strcat(myname,".stb");
        !           260:                        if (oktox(myname)) return(stabf = myname);
        !           261:                        /*
        !           262:                         *      Try Xargv[0] with ".exe" concatenated
        !           263:                         */
        !           264:                        strcpy(myname,Xargv[0]);
        !           265:                        strcat(myname,".exe");
        !           266:                        if (oktox(myname)) return(stabf = myname);
        !           267: #endif
        !           268:                }
        !           269:                for(;*cp;) {
        !           270: 
        !           271:                        /* copy over current directory
        !           272:                           and then append argv[0] */
        !           273: 
        !           274:                        for(cp2=myname;(*cp)!=0 && (*cp)!=':';)
        !           275:                                *cp2++ = *cp++;
        !           276:                        *cp2++ = '/';
        !           277:                        strcpy(cp2,Xargv[0]);
        !           278:                        if(*cp) cp++;
        !           279: #ifndef        os_vms
        !           280:                        if(!oktox(myname)) continue;
        !           281: #else
        !           282:                        /*
        !           283:                         *      Also try ".stb" and ".exe" in VMS
        !           284:                         */
        !           285:                        if(!oktox(myname)) {
        !           286:                                char *end_of_name;
        !           287:                                end_of_name = cp2 + strlen(cp2);
        !           288:                                strcat(cp2,".stb");
        !           289:                                if(!oktox(myname)) {
        !           290:                                        /*
        !           291:                                         *      Try ".exe"
        !           292:                                         */
        !           293:                                        *end_of_name = 0;   /* Kill ".stb" */
        !           294:                                        strcat(cp2,".exe");
        !           295:                                        if (!oktox(myname)) continue;
        !           296:                                }
        !           297:                        }
        !           298: #endif
        !           299:                        return(stabf = myname);
        !           300:                }
        !           301:                /* one last try for dual systems */
        !           302:                strcpy(myname,Xargv[0]);
        !           303:                if(oktox(myname)) return(stabf = myname);
        !           304:                error("Could not find which file is being executed.",FALSE);
        !           305:                /* NOTREACHED */
        !           306:        } else return (stabf);
        !           307: }
        !           308: static char mybuff[40]; 
        !           309: char *
        !           310: mytemp()
        !           311: {
        !           312:        /*if(mypid==0) mypid = (getpid() & 0xffff);
        !           313:          fails if you do a dumplisp after doing a
        !           314:          cfasl */
        !           315:        sprintf(mybuff,"/tmp/Li%d.%d",(getpid() & 0xffff),seed++);
        !           316:        return(mybuff);
        !           317: }
        !           318: ungstab()
        !           319: {
        !           320:        seed--;
        !           321:        sprintf(mybuff,"/tmp/Li%d.%d",(getpid() & 0xffff),seed-1);
        !           322:        if(seed==0) {
        !           323:                stabf = 0;
        !           324:                fvirgin = 1;
        !           325:        }
        !           326: }
        !           327: lispval
        !           328: verify(in,error)
        !           329: register lispval in;
        !           330: char *error;
        !           331: {
        !           332:        for(EVER) {
        !           333:                switch(TYPE(in)) {
        !           334:                case STRNG:
        !           335:                        return(in);
        !           336:                case ATOM:
        !           337:                        return((lispval)in->a.pname);
        !           338:                }
        !           339:                in = errorh1(Vermisc,error,nil,TRUE,0,in);
        !           340:        }
        !           341: }
        !           342: 
        !           343: 
        !           344: /* extern      int fvirgin; */
        !           345:                        /* declared in ffasl.c tells if this is original
        !           346:                         *      lisp symbol table.
        !           347:                         * if fvirgin is 1 then we must copy the symbol
        !           348:                         *      table, else we can overwrite it, since
        !           349:                         *      it is a temporary file which only
        !           350:                         *      one user could be using(was not created
        !           351:                         *      as an original lisp or by a (dumplisp)
        !           352:                         *      or a (savelisp)).
        !           353:                         */
        !           354: 
        !           355: /* copy a block of data from one file to another of size size */
        !           356: copyblock(f1,f2,size)
        !           357: FILE *f1, *f2;
        !           358: long size;
        !           359: {
        !           360:        char block[BUFSIZ];
        !           361: 
        !           362:            while ( size > BUFSIZ ) {
        !           363:                size -= BUFSIZ;
        !           364:                fread(block,BUFSIZ,1,f1);
        !           365:                fwrite(block,BUFSIZ,1,f2);
        !           366:            }
        !           367:            if (size > 0 ) {
        !           368:                fread(block,(int)size,1,f1);
        !           369:                fwrite(block,(int)size,1,f2);
        !           370:            }
        !           371: }
        !           372: 
        !           373: /* removeaddress --
        !           374:  *
        !           375:  * (removeaddress '|_entry1| '|_entry2| ...)
        !           376:  *
        !           377:  *     removes the given entry points from the run time symbol table,
        !           378:  *             so that later cfasl'd files can have these label names.
        !           379:  *
        !           380:  */
        !           381: 
        !           382: lispval
        !           383: Lrmadd(){
        !           384:        register struct argent *mlbot = lbot;
        !           385:        register struct nlist *q; 
        !           386:        register int i;
        !           387:        int numberofargs, strsize;
        !           388:        char *gstab();
        !           389:        char ostabf[128];
        !           390:        char *nstabf,*mytemp();
        !           391:        char *strtbl,*alloca();
        !           392:        int i2, n, m, nargleft, savem;
        !           393:        FILE *f, *fa;
        !           394:        FILE *fnew;
        !           395:        off_t savesymadd,symadd;                /* symbol address */
        !           396:        struct exec buf;
        !           397:        struct nlist nlbuf[BUFSIZ/sizeof (struct nlist)];
        !           398:        int maxlen;
        !           399:        int change;
        !           400:        Keepxs();
        !           401: 
        !           402:        numberofargs = (np - lbot);
        !           403:        nargleft = numberofargs;
        !           404:        maxlen = 0;
        !           405:        for ( i=0; i<numberofargs; i++,mlbot ++) {
        !           406:                mlbot->val = verify(mlbot->val,"Incorrect entry specification.");
        !           407:                n = strlen((char *)mlbot->val);
        !           408:                if (n > maxlen)
        !           409:                        maxlen = n;
        !           410:        }
        !           411:        /* 
        !           412:         *  Must not disturb object file if it an original file which
        !           413:         *      other users can execute(signified by the variable fvirgin).
        !           414:         *      so the entire symbol table is copied to a new file.
        !           415:         */
        !           416:        if (fvirgin) {
        !           417:                strncpy(ostabf,gstab(),128);
        !           418:                nstabf = mytemp();
        !           419:                /*
        !           420:                 * copy over symbol table into a temporary file first
        !           421:                 *
        !           422:                 */
        !           423:                f = fopen(ostabf, "r");
        !           424:                fnew = fopen(nstabf, "w");
        !           425:                if (( f == NULL ) || (fnew == NULL)) {Freexs(); return( nil );}
        !           426:                /* read exec header on file */
        !           427: #ifndef        os_vms
        !           428:                fread((char *)&buf, sizeof buf, 1, f);
        !           429: #else  os_vms
        !           430:                /*
        !           431:                 *      Under VMS/EUNICE we have to try the 1st 512 byte
        !           432:                 *      block and the 2nd 512 byte block (there may be
        !           433:                 *      a VMS header in the 1st 512 bytes).
        !           434:                 */
        !           435:                get_aout_header(fileno(f),&buf);
        !           436: #endif os_vms
        !           437: 
        !           438:                /* Is this a legitimate a.out file? */
        !           439:                if (N_BADMAG(buf)) {
        !           440:                        unlink(nstabf);
        !           441:                        ungstab();
        !           442:                        fclose(f);
        !           443:                        fclose(fnew);
        !           444:                        errorh1(Vermisc,"Removeaddress: Bad file",nil,FALSE,0,inewstr(ostabf));
        !           445:                        {Freexs(); return(nil);}
        !           446:                }
        !           447:                /* set pointer on read file to symbol table */
        !           448:                /* must be done before the structure buf is reassigned 
        !           449:                 * so that it will be accurate for the read file 
        !           450:                 */
        !           451:                fseek(f,(long)N_SYMOFF(buf),0);
        !           452:                /* reset up exec header structure for new file */
        !           453:                buf.a_magic = OMAGIC;
        !           454:                buf.a_text = 0;
        !           455:                buf.a_data = 0;
        !           456:                buf.a_bss = 0;
        !           457:                buf.a_entry = 0;
        !           458:                buf.a_trsize = 0;
        !           459:                buf.a_drsize = 0;
        !           460:                fwrite((char *)&buf,
        !           461:                       sizeof buf,1,fnew);      /* write out exec header */
        !           462:                copyblock(f,fnew,(long)buf.a_syms); /* copy symbol table */
        !           463: #if ! (os_unisoft | os_unix_ts)
        !           464:                fread((char *)&strsize,
        !           465:                      sizeof (int),1,f);        /* find size of string table */
        !           466:                fwrite((char *)&strsize,
        !           467:                      sizeof (int),1,fnew);     /* find size of string table */
        !           468:                strsize -= 4;
        !           469:                strtbl = alloca(strsize);
        !           470:                fread(strtbl,strsize,1,f);      /* read and save string table*/
        !           471:                fwrite(strtbl,strsize,1,fnew);  /* copy out string table     */
        !           472: #endif
        !           473:                fclose(f);fclose(fnew);
        !           474:        } else {
        !           475:                nstabf = gstab();
        !           476:        }
        !           477: 
        !           478:        /*
        !           479:         * now unset the external bits it the entry points specified.
        !           480:         */
        !           481:        f = fopen(nstabf, "r");
        !           482:        fa = fopen(nstabf, "a");
        !           483:        if (( f == NULL ) || (fa == NULL)) {
        !           484:                unlink(nstabf);
        !           485:                ungstab();
        !           486:                if (f != NULL ) fclose(f);
        !           487:                if (fa != NULL ) fclose(fa);
        !           488:                return ( nil );
        !           489:        }
        !           490: 
        !           491:        /* read exec header on file */
        !           492: #ifndef        os_vms
        !           493:        fread((char *)&buf, sizeof buf, 1, f);
        !           494: #else  os_vms
        !           495:        /*
        !           496:         *      Under VMS/EUNICE we have to try the 1st 512 byte
        !           497:         *      block and the 2nd 512 byte block (there may be
        !           498:         *      a VMS header in the 1st 512 bytes).
        !           499:         */
        !           500:        get_aout_header(fileno(f),&buf);
        !           501: #endif os_vms
        !           502: 
        !           503:        /* Is this a legitimate a.out file? */
        !           504:        if (N_BADMAG(buf)) {
        !           505:                if (fvirgin) {
        !           506:                        unlink(nstabf);
        !           507:                        ungstab();
        !           508:                }
        !           509:                fclose(f);
        !           510:                fclose(fa);
        !           511:                errorh1(Vermisc,"Removeaddress: Bad file",nil,FALSE,0,inewstr(ostabf));
        !           512:                {Freexs(); return(nil);}
        !           513:        } else {
        !           514:                symadd = N_SYMOFF(buf);
        !           515: #if ! (os_unisoft | os_unix_ts)
        !           516:                /*
        !           517:                 * read in string table if not done during copying
        !           518:                 */
        !           519:                if (fvirgin==0){
        !           520:                        fseek(f,(long)N_STROFF(buf),0);
        !           521:                        fread((char *)&strsize,sizeof (int),1,f);
        !           522:                        strsize -= 4;
        !           523:                        strtbl = alloca(strsize);
        !           524:                        fread(strtbl,strsize,1,f);
        !           525:                }
        !           526: #endif
        !           527:                n = buf.a_syms;
        !           528:                fseek(f, (long)symadd, 0);
        !           529:                while (n) {
        !           530:                        m = sizeof (nlbuf);
        !           531:                        if (n < m)
        !           532:                                m = n;
        !           533: 
        !           534:                        /* read next block of symbols from a.out file */
        !           535:                        fread((char *)nlbuf, m, 1, f);
        !           536:                        savem = m;
        !           537:                        savesymadd = symadd;
        !           538:                        symadd += m;
        !           539:                        n -= m;
        !           540:                        change = 0;
        !           541: 
        !           542:                /* compare block of symbols against list of entry point
        !           543:                 *      names given, if a match occurs, clear the N_EXT bit
        !           544:                 *      for that given symbol and signal a change.
        !           545:                 */
        !           546:                        for (q = nlbuf; (m -= sizeof(struct nlist)) >= 0; q++) {
        !           547: 
        !           548:               /* make sure it is external */
        !           549:                                if (
        !           550:                                    (q->n_type & N_EXT)==0
        !           551: #if ! (os_unix_ts | os_unisoft)
        !           552:                                    || q->n_un.n_strx == 0 || q->n_type & N_STAB
        !           553: #endif
        !           554:                                   )    continue;
        !           555:                        for (mlbot=lbot,i2 = 0;i2<numberofargs;i2++,mlbot++) {
        !           556: #if ! (os_unix_ts | os_unisoft)
        !           557:                                if(strcmp((char *)mlbot->val,
        !           558:                                          strtbl+q->n_un.n_strx-4)!=0)
        !           559:                                                continue;
        !           560: #else
        !           561:                                if(strncmp((char *)mlbot->val,
        !           562:                                           q->n_name,8)!=0)
        !           563:                                                continue;
        !           564: #endif
        !           565:                                change = 1;
        !           566:                                q->n_type &= ~N_EXT;
        !           567:                                break;
        !           568:                        }
        !           569:                }
        !           570:                if ( change ) {
        !           571:                        fseek(fa,(long)savesymadd,0);
        !           572:                        fwrite((char *)nlbuf, savem, 1, fa);
        !           573:                        if (--nargleft == 0)
        !           574:                                goto alldone;
        !           575:                }
        !           576:                }
        !           577:        }
        !           578: alldone:
        !           579:        fclose(f);
        !           580:        fclose(fa);
        !           581:        if(fvirgin)
        !           582:                fvirgin = 0;
        !           583:        stabf = nstabf;
        !           584:        {Freexs(); return(tatom);}
        !           585: }
        !           586: char *
        !           587: Ilibdir()
        !           588: {
        !           589:        register lispval handy;
        !           590: tryagain:
        !           591:        handy = Vlibdir->a.clb;
        !           592:        switch(TYPE(handy)) {
        !           593:        case ATOM:
        !           594:                handy = (lispval) handy->a.pname;
        !           595:        case STRNG:
        !           596:                break;
        !           597:        default:
        !           598:                (void) error(
        !           599: "cfasl or load: lisp-library-directory not bound to string or atom",
        !           600:                                TRUE);
        !           601:                goto tryagain;
        !           602:        }
        !           603:        return((char *) handy);
        !           604: }

unix.superglobalmegacorp.com

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