Annotation of 43BSDReno/pgrm/lisp/franz/lam7.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid =
                      3:    "$Header: lam7.c,v 1.9 87/12/14 18:48:02 sklower Exp $";
                      4: #endif
                      5: 
                      6: /*                                     -[Fri Aug  5 12:51:31 1983 by jkf]-
                      7:  *     lam7.c                          $Locker:  $
                      8:  * lambda functions
                      9:  *
                     10:  * (c) copyright 1982, Regents of the University of California
                     11:  */
                     12: 
                     13: #include "global.h"
                     14: #include <signal.h>
                     15: 
                     16: 
                     17: lispval
                     18: Lfork() {
                     19:        int pid;
                     20: 
                     21:        chkarg(0,"fork");
                     22:        if ((pid=fork())) {
                     23:                return(inewint(pid));
                     24:        } else
                     25:                return(nil);
                     26: }
                     27: 
                     28: lispval
                     29: Lwait()
                     30: {
                     31:        register lispval ret, temp;
                     32:        int status = -1, pid;
                     33:        Savestack(2);
                     34: 
                     35: 
                     36:        chkarg(0,"wait");
                     37:        pid = wait(&status);
                     38:        ret = newdot();
                     39:        protect(ret);
                     40:        temp = inewint(pid);
                     41:        ret->d.car = temp;
                     42:        temp = inewint(status);
                     43:        ret->d.cdr = temp;
                     44:        Restorestack();
                     45:        return(ret);
                     46: }
                     47: 
                     48: lispval
                     49: Lpipe()
                     50: {
                     51:        register lispval ret, temp;
                     52:        int pipes[2];
                     53:        Savestack(2);
                     54: 
                     55:        chkarg(0,"pipe");
                     56:        pipes[0] = -1;
                     57:        pipes[1] = -1;
                     58:        pipe(pipes);
                     59:        ret = newdot();
                     60:        protect(ret);
                     61:        temp = inewint(pipes[0]);
                     62:        ret->d.car = temp;
                     63:        temp = inewint(pipes[1]);
                     64:        ret->d.cdr = temp;
                     65:        Restorestack();
                     66:        return(ret);
                     67: }
                     68: 
                     69: lispval
                     70: Lfdopen()
                     71: {
                     72:        register lispval fd, type;
                     73:        FILE *ptr;
                     74: 
                     75:        chkarg(2,"fdopen");
                     76:        type = (np-1)->val;
                     77:        fd = lbot->val;
                     78:        if( TYPE(fd)!=INT )
                     79:                return(nil);
                     80:        if ( (ptr=fdopen((int)fd->i, (char *)type->a.pname))==NULL)
                     81:                return(nil);
                     82:        return(P(ptr));
                     83: }
                     84: 
                     85: lispval
                     86: Lexece()
                     87: {
                     88:        lispval fname, arglist, envlist, temp;
                     89:        char *args[100], *envs[100], estrs[1024];
                     90:        char *p, *cp, **argsp;
                     91: 
                     92:        fname = nil;
                     93:        arglist = nil;
                     94:        envlist = nil;
                     95: 
                     96:        switch(np-lbot) {
                     97:        case 3: envlist = lbot[2].val;
                     98:        case 2: arglist = lbot[1].val;
                     99:        case 1: fname   = lbot[0].val;
                    100:        case 0: break;
                    101:        default:
                    102:                argerr("exece");
                    103:        }
                    104: 
                    105:        while (TYPE(fname)!=ATOM)
                    106:           fname = error("exece: non atom function name",TRUE);
                    107:        while (TYPE(arglist)!=DTPR && arglist!=nil)
                    108:                arglist = error("exece: non list arglist",TRUE);
                    109:        for (argsp=args; arglist!=nil; arglist=arglist->d.cdr) {
                    110:                temp = arglist->d.car;
                    111:                if (TYPE(temp)!=ATOM)
                    112:                        error("exece: non atom argument seen",FALSE);
                    113:                *argsp++ = temp->a.pname;
                    114:        }
                    115:        *argsp = 0;
                    116:        if (TYPE(envlist)!=DTPR && envlist!=nil)
                    117:                return(nil);
                    118:        for (argsp=envs,cp=estrs; envlist!=nil; envlist=envlist->d.cdr) {
                    119:                temp = envlist->d.car;
                    120:                if (TYPE(temp)!=DTPR || TYPE(temp->d.car)!=ATOM
                    121:                  || TYPE(temp->d.cdr)!=ATOM)
                    122:                     error("exece: Bad enviroment list",FALSE);
                    123:                *argsp++ = cp;
                    124:                for (p=temp->d.car->a.pname; (*cp++ = *p++);) ;
                    125:                *(cp-1) = '=';
                    126:                for (p=temp->d.cdr->a.pname; (*cp++ = *p++);) ;
                    127:        }
                    128:        *argsp = 0;
                    129:        
                    130:        return(inewint(execve(fname->a.pname, args, envs)));
                    131: }
                    132: 
                    133: /* Lprocess -
                    134:  * C code to implement the *process function
                    135:  * call:
                    136:  *     (*process 'st_command ['s_readp ['s_writep]])
                    137:  * where st_command is the command to execute
                    138:  *   s_readp is non nil if you want a port to read from returned
                    139:  *   s_writep is non nil if you want a port to write to returned
                    140:  *   both flags default to nil
                    141:  * *process returns
                    142:  *    the exit status of the process if s_readp and s_writep not given
                    143:  *     (in this case the parent waits for the child to finish)
                    144:  *    a list of (readport writeport childpid) if one of s_readp or s_writep
                    145:  *    is given.  If only s_readp is non nil, then writeport will be nil,
                    146:  *    If only s_writep is non nil, then readport will be nil
                    147:  */
                    148: 
                    149: lispval
                    150: Lprocess()
                    151: {
                    152:        int wflag , childsi , childso , child;
                    153:        lispval handy;
                    154:        char *command, *p;
                    155:        int writep, readp;
                    156:        int itemp;
                    157:        int (*handler)(), (*signal())();
                    158:        FILE *bufs[2],*obufs[2], *fpipe();
                    159:        Savestack(0);
                    160: 
                    161:        writep = readp = FALSE;
                    162:        wflag = TRUE;
                    163:        
                    164:        switch(np-lbot) {
                    165:        case 3:  if(lbot[2].val != nil) writep = TRUE;
                    166:        case 2:  if(lbot[1].val != nil) readp = TRUE;
                    167:                 wflag = 0;
                    168:        case 1:  command = (char *) verify(lbot[0].val,
                    169:                                            "*process: non atom first arg");
                    170:                 break;
                    171:        default:
                    172:                argerr("*process");
                    173:        }
                    174:        
                    175:        childsi = 0;
                    176:        childso = 1;
                    177: 
                    178:        /* if there will be communication between the processes,
                    179:         * it will be through these pipes:
                    180:         *  parent ->  bufs[1] ->  bufs[0] -> child    if writep
                    181:         *  parent <- obufs[0] <- obufs[1] <- parent   if readp
                    182:         */
                    183:        if(writep) {
                    184:            fpipe(bufs);
                    185:            childsi = fileno(bufs[0]);
                    186:        }
                    187:        
                    188:        if(readp) {
                    189:                fpipe(obufs);
                    190:                childso = fileno(obufs[1]);
                    191:        }
                    192:        
                    193:        handler = signal(SIGINT,SIG_IGN);
                    194:        if((child = vfork()) == 0 ) {
                    195:                /* if we will wait for the child to finish
                    196:                 * and if the process had ignored interrupts before
                    197:                 * we were called, then leave them ignored, else
                    198:                 * set it back the the default (death)
                    199:                 */
                    200:                if(wflag && handler != SIG_IGN)
                    201:                        signal(2,SIG_DFL);
                    202:                        
                    203:                if(writep) {
                    204:                        close(0);
                    205:                        dup(childsi);
                    206:                }
                    207:                if (readp) {
                    208:                        close(1);
                    209:                        dup(childso);
                    210:                }
                    211:                if ((p = (char *)getenv("SHELL")) != (char *)0) {
                    212:                        execlp(p , p, "-c",command,0);
                    213:                        _exit(-1); /* if exec fails, signal problems*/
                    214:                } else {
                    215:                        execlp("csh", "csh", "-c",command,0);
                    216:                        execlp("sh", "sh", "-c",command,0);
                    217:                        _exit(-1); /* if exec fails, signal problems*/
                    218:                }
                    219:        }
                    220: 
                    221:        /* close the duplicated file descriptors
                    222:         * e.g. if writep is true then we've created two desriptors,
                    223:         *  bufs[0] and bufs[1],  we will write to bufs[1] and the
                    224:         *  child (who has a copy of our bufs[0]) will read from bufs[0]
                    225:         *  We (the parent) close bufs[0] since we will not be reading
                    226:         *  from it.
                    227:         */
                    228:        if(writep) fclose(bufs[0]);
                    229:        if(readp) fclose(obufs[1]);
                    230: 
                    231:        if(wflag && child!= -1) {
                    232:                int status=0;
                    233:                /* we await the death of the child */
                    234:                while(wait(&status)!=child) {}
                    235:                /* the child has died */
                    236:                signal(2,handler);      /* restore the interrupt handler */
                    237:                itemp = status >> 8;
                    238:                Restorestack();
                    239:                return(inewint(itemp)); /* return its status */
                    240:        }
                    241:        /* we are not waiting for the childs death
                    242:         * build a list containing the write and read ports
                    243:         */
                    244:        protect(handy = newdot());
                    245:        handy->d.cdr = newdot();
                    246:        handy->d.cdr->d.cdr = newdot();
                    247:        if(readp) {
                    248:            handy->d.car = P(obufs[0]);
                    249:            ioname[PN(obufs[0])] = (lispval) inewstr((char *) "from-process");
                    250:        }
                    251:        if(writep) {
                    252:            handy->d.cdr->d.car = P(bufs[1]);
                    253:            ioname[PN(bufs[1])] = (lispval) inewstr((char *) "to-process");
                    254:        }
                    255:        handy->d.cdr->d.cdr->d.car = (lispval) inewint(child);
                    256:        signal(SIGINT,handler);
                    257:        Restorestack();
                    258:        return(handy);
                    259: }
                    260: 
                    261: extern int gensymcounter;
                    262: 
                    263: lispval
                    264: Lgensym()
                    265: {
                    266:        lispval arg;
                    267:        char leader;
                    268: 
                    269:        switch(np-lbot)
                    270:        {
                    271:            case 0: arg = nil;
                    272:                    break;
                    273:            case 1: arg = lbot->val;
                    274:                    break;
                    275:            default: argerr("gensym");
                    276:        }
                    277:        leader = 'g';
                    278:        if (arg != nil && TYPE(arg)==ATOM)
                    279:                leader = arg->a.pname[0];
                    280:        sprintf(strbuf, "%c%05d", leader, gensymcounter++);
                    281:        atmlen = 7;
                    282:        return((lispval)newatom(0));
                    283: }
                    284: 
                    285: extern struct types {
                    286: char   *next_free;
                    287: int    space_left,
                    288:        space,
                    289:        type,
                    290:        type_len;                       /*  note type_len is in units of int */
                    291: lispval *items,
                    292:        *pages,
                    293:        *type_name;
                    294: struct heads
                    295:        *first;
                    296: } atom_str ;
                    297: 
                    298: lispval
                    299: Lremprop()
                    300: {
                    301:        register struct argent *argp;
                    302:        register lispval pptr, ind, opptr;
                    303:        lispval atm;
                    304:        int disemp = FALSE;
                    305: 
                    306:        chkarg(2,"remprop");
                    307:        argp = lbot;
                    308:        ind = argp[1].val;
                    309:        atm = argp->val;
                    310:        switch (TYPE(atm)) {
                    311:        case DTPR:
                    312:                pptr = atm->d.cdr;
                    313:                disemp = TRUE;
                    314:                break;
                    315:        case ATOM:
                    316:                if((lispval)atm==nil)
                    317:                        pptr = nilplist;
                    318:                else
                    319:                        pptr = atm->a.plist;
                    320:                break;
                    321:        default:
                    322:                errorh1(Vermisc, "remprop: Illegal first argument :",
                    323:                       nil, FALSE, 0, atm);
                    324:        }
                    325:        opptr = nil;
                    326:        if (pptr==nil) 
                    327:                return(nil);
                    328:        while(TRUE) {
                    329:                if (TYPE(pptr->d.cdr)!=DTPR)
                    330:                        errorh1(Vermisc, "remprop: Bad property list",
                    331:                               nil, FALSE, 0,atm);
                    332:                if (pptr->d.car == ind) {
                    333:                        if( opptr != nil)
                    334:                                opptr->d.cdr = pptr->d.cdr->d.cdr;
                    335:                        else if(disemp)
                    336:                                atm->d.cdr = pptr->d.cdr->d.cdr;
                    337:                        else if(atm==nil)
                    338:                                nilplist = pptr->d.cdr->d.cdr;
                    339:                        else
                    340:                                atm->a.plist = pptr->d.cdr->d.cdr;
                    341:                        return(pptr->d.cdr);
                    342:                }
                    343:                if ((pptr->d.cdr)->d.cdr == nil) return(nil);
                    344:                opptr = pptr->d.cdr;
                    345:                pptr = (pptr->d.cdr)->d.cdr;
                    346:        }
                    347: }
                    348: 
                    349: lispval
                    350: Lbcdad()
                    351: {
                    352:        lispval ret, temp;
                    353: 
                    354:        chkarg(1,"bcdad");
                    355:        temp = lbot->val;
                    356:        if (TYPE(temp)!=ATOM)
                    357:                error("ONLY ATOMS HAVE FUNCTION BINDINGS", FALSE);
                    358:        temp = temp->a.fnbnd;
                    359:        if (TYPE(temp)!=BCD)
                    360:                return(nil);
                    361:        ret = newint();
                    362:        ret->i = (int)temp;
                    363:        return(ret);
                    364: }
                    365: 
                    366: lispval
                    367: Lstringp()
                    368: {
                    369:        chkarg(1,"stringp");
                    370:        if (TYPE(lbot->val)==STRNG)
                    371:                return(tatom);
                    372:        return(nil);
                    373: }
                    374: 
                    375: lispval
                    376: Lsymbolp()
                    377: {
                    378:        chkarg(1,"symbolp");
                    379:        if (TYPE(lbot->val)==ATOM)
                    380:                return(tatom);
                    381:        return(nil);
                    382: }
                    383: 
                    384: lispval
                    385: Lrematom()
                    386: {
                    387:        register lispval temp;
                    388: 
                    389:        chkarg(1,"rematom");
                    390:        temp = lbot->val;
                    391:        if (TYPE(temp)!=ATOM)
                    392:                return(nil);
                    393:        temp->a.fnbnd = nil;
                    394:        temp->a.pname = (char *)CNIL;
                    395:        temp->a.plist = nil;
                    396:        (atom_items->i)--;
                    397:        (atom_str.space_left)++;
                    398:        temp->a.clb=(lispval)atom_str.next_free;
                    399:        atom_str.next_free=(char *) temp;
                    400:        return(tatom);
                    401: }
                    402: 
                    403: #define QUTMASK 0200
                    404: #define VNUM 0000
                    405: 
                    406: lispval
                    407: Lprname()
                    408: {
                    409:        lispval a, ret;
                    410:        register lispval work, prev;
                    411:        char    *front, *temp; int clean;
                    412:        char ctemp[100];
                    413:        extern unsigned char *ctable;
                    414:        Savestack(2);
                    415: 
                    416:        chkarg(1,"prname");
                    417:        a = lbot->val;
                    418:        switch (TYPE(a)) {
                    419:                case INT:
                    420:                        sprintf(ctemp,"%d",a->i);
                    421:                        break;
                    422: 
                    423:                case DOUB:
                    424:                        sprintf(ctemp,"%f",a->r);
                    425:                        break;
                    426:        
                    427:                case ATOM:
                    428:                        temp = front = a->a.pname;
                    429:                        clean = *temp;
                    430:                        if (*temp == '-') temp++;
                    431:                        clean = clean && (ctable[*temp] != VNUM);
                    432:                        while (clean && *temp)
                    433:                                clean = (!(ctable[*temp++] & QUTMASK));
                    434:                        if (clean)
                    435:                                strncpy(ctemp, front, 99);
                    436:                        else    
                    437:                                sprintf(ctemp,"\"%s\"",front);
                    438:                        break;
                    439:        
                    440:                default:
                    441:                        error("prname does not support this type", FALSE);
                    442:        }
                    443:        temp = ctemp;
                    444:        protect(ret = prev = newdot());
                    445:        while (*temp) {
                    446:                prev->d.cdr = work = newdot();
                    447:                strbuf[0] = *temp++;
                    448:                strbuf[1] = 0;
                    449:                work->d.car = getatom(FALSE);
                    450:                work->d.cdr = nil;
                    451:                prev = work;
                    452:        }
                    453:        Restorestack();
                    454:        return(ret->d.cdr);
                    455: }
                    456: 
                    457: lispval
                    458: Lexit()
                    459: {
                    460:        register lispval handy;
                    461:        if(np-lbot==0) franzexit(0);
                    462:        handy = lbot->val;
                    463:        if(TYPE(handy)==INT)
                    464:                franzexit((int) handy->i);
                    465:        franzexit(-1);
                    466: }
                    467: lispval
                    468: Iimplode(unintern)
                    469: {
                    470:        register lispval handy, work;
                    471:        register char *cp = strbuf;
                    472:        extern int atmlen;      /* used by newatom and getatom */
                    473:        extern char *atomtoolong();
                    474: 
                    475:        chkarg(1,"implode");
                    476:        for(handy = lbot->val; handy!=nil; handy = handy->d.cdr)
                    477:        {
                    478:                work = handy->d.car;
                    479:                if(cp >= endstrb)
                    480:                        cp = atomtoolong(cp);
                    481:        again:
                    482:                switch(TYPE(work))
                    483:                {
                    484:                case ATOM:
                    485:                        *cp++ = work->a.pname[0];
                    486:                        break;
                    487:                case SDOT:
                    488:                        *cp++ = work->s.I;
                    489:                        break;
                    490:                case INT:
                    491:                        *cp++ = work->i;
                    492:                        break;
                    493:                case STRNG:
                    494:                        *cp++ = * (char *) work;
                    495:                        break;
                    496:                default:
                    497:                        work = errorh1(Vermisc,"implode/maknam: Illegal type for this arg:",nil,FALSE,44,work);
                    498:                        goto again;
                    499:                }
                    500:        }
                    501:        *cp = 0;
                    502:        if(unintern) return((lispval)newatom(FALSE));
                    503:        else return((lispval) getatom(FALSE));
                    504: }
                    505: 
                    506: lispval
                    507: Lmaknam()
                    508: {
                    509:        return(Iimplode(TRUE));         /* unintern result */
                    510: }
                    511: 
                    512: lispval
                    513: Limplode()
                    514: {
                    515:        return(Iimplode(FALSE));        /* intern result */
                    516: }
                    517: 
                    518: lispval
                    519: Lntern()
                    520: {
                    521:        register int hash;
                    522:        register lispval handy,atpr;
                    523: 
                    524: 
                    525:        chkarg(1,"intern");
                    526:        if(TYPE(handy=lbot->val) != ATOM)
                    527:                errorh1(Vermisc,"non atom to intern ",nil,FALSE,0,handy);
                    528:        /* compute hash of pname of arg */
                    529:        hash = hashfcn(handy->a.pname);
                    530: 
                    531:        /* search for atom with same pname on hash list */
                    532: 
                    533:        atpr = (lispval) hasht[hash];
                    534:        for(atpr = (lispval) hasht[hash] 
                    535:                 ; atpr != CNIL 
                    536:                 ; atpr = (lispval)atpr->a.hshlnk)
                    537:        {
                    538:                if(strcmp(atpr->a.pname,handy->a.pname) == 0) return(atpr);
                    539:        }
                    540:        
                    541:        /* not there yet, put the given one on */
                    542: 
                    543:        handy->a.hshlnk = hasht[hash];
                    544:        hasht[hash] = (struct atom *)handy;
                    545:        return(handy);
                    546: }
                    547: 
                    548: /*** Ibindvars :: lambda bind values to variables
                    549:        called with a list of variables and values.
                    550:        does the special binding and returns a fixnum which represents
                    551:        the value of bnp before the binding
                    552:        Use by compiled progv's.
                    553:  ***/
                    554: lispval
                    555: Ibindvars()
                    556: {
                    557:     register lispval vars,vals,handy;
                    558:     struct nament *oldbnp = bnp;
                    559: 
                    560:     chkarg(2,"int:bindvars");
                    561: 
                    562:     vars = lbot[0].val;
                    563:     vals = lbot[1].val;
                    564: 
                    565:     if(vars == nil) return(inewint(oldbnp));
                    566: 
                    567:     if(TYPE(vars) != DTPR)
                    568:       errorh1(Vermisc,"progv (int:bindvars): bad first argument ", nil,
                    569:                FALSE,0,vars);
                    570:    if((vals != nil) && (TYPE(vals) != DTPR))
                    571:      errorh1(Vermisc,"progv (int:bindvars): bad second argument ",nil,
                    572:                FALSE,0,vals);
                    573: 
                    574:    for( ; vars != nil ; vars = vars->d.cdr , vals=vals->d.cdr)
                    575:    {
                    576:        handy = vars->d.car;
                    577:        if(TYPE(handy) != ATOM)
                    578:           errorh1(Vermisc,"progv (int:bindvars): non symbol argument to bind ",
                    579:                nil,FALSE,0,handy);
                    580:        PUSHDOWN(handy,vals->d.car);
                    581:    }
                    582:    return(inewint(oldbnp));
                    583: }
                    584: 
                    585: 
                    586: /*** Iunbindvars :: unbind the variable stacked by Ibindvars
                    587:      called by compiled progv's
                    588:  ***/
                    589:  
                    590: lispval
                    591: Iunbindvars()
                    592: {
                    593:     struct nament *oldbnp;
                    594:     
                    595:     chkarg(1,"int:unbindvars");
                    596:     oldbnp = (struct nament *) (lbot[0].val->i);
                    597:     if((oldbnp < orgbnp)  || ( oldbnp > bnp))
                    598:        errorh1(Vermisc,"int:unbindvars: bad bnp value given ",nil,FALSE,0,
                    599:                        lbot[0].val);
                    600:     popnames(oldbnp);
                    601:     return(nil);
                    602: }
                    603: 
                    604: /*
                    605:  * (time-string ['x_milliseconds])
                    606:  * if given no argument, returns the current time as a string
                    607:  * if given an argument which is a fixnum representing the current time
                    608:  * as a fixnum, it generates a string from that
                    609:  *
                    610:  * the format of the string returned is that defined in the Unix manual
                    611:  * except the trailing newline is removed.
                    612:  *
                    613:  */
                    614: lispval
                    615: Ltymestr()
                    616: {
                    617:     long timevalue;
                    618:     char *retval;
                    619:     
                    620:     switch(np-lbot)
                    621:     {
                    622:        case 0: time(&timevalue);
                    623:                break;
                    624:        case 1: while (TYPE(lbot[0].val) != INT)
                    625:                  lbot[0].val =
                    626:                     errorh(Vermisc,"time-string: non fixnum argument ",
                    627:                                nil,TRUE,0,lbot[0].val);
                    628:                timevalue = lbot[0].val->i;
                    629:                break;
                    630:        default:
                    631:                argerr("time-string");
                    632:     }
                    633: 
                    634:     retval = (char *) ctime(&timevalue);
                    635:     /* remove newline character */
                    636:     retval[strlen(retval)-1] = '\0';
                    637:     return((lispval) inewstr(retval));
                    638: }

unix.superglobalmegacorp.com

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