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

Defined functions

Ibindvars defined in line 555; used 2 times
Iimplode defined in line 468; used 2 times
Iunbindvars defined in line 591; used 2 times
Lbcdad defined in line 350; never used
Lexece defined in line 86; never used
Lexit defined in line 458; never used
Lfdopen defined in line 70; never used
Lfork defined in line 18; never used
Lgensym defined in line 264; never used
Limplode defined in line 513; never used
Lmaknam defined in line 507; never used
Lntern defined in line 519; never used
Lpipe defined in line 49; never used
Lprname defined in line 407; never used
Lprocess defined in line 150; never used
Lrematom defined in line 385; never used
Lremprop defined in line 299; never used
Lstringp defined in line 367; never used
Lsymbolp defined in line 376; never used
Ltymestr defined in line 615; never used
Lwait defined in line 29; never used

Defined variables

rcsid defined in line 2; never used

Defined struct's

types defined in line 286; never used

Defined macros

QUTMASK defined in line 404; used 1 times
VNUM defined in line 405; used 1 times
Last modified: 1985-08-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1773
Valid CSS Valid XHTML 1.0 Strict