# 2.11BSD#431 - /usr/src/bin/csh/sh.func.c

##### Functions

    doagain           X
    doalias           X
    dobreak           X
    docontin          X
    doecho            X
    doelse            X
    doend             X
    doeval            X
    doexit            X
    doforeach         X
    doglob            X
    dogoto            X
    doif              X
    dolabel           X
    dolimit           X
    dologin           X
    dologout          X
    donewgrp          X
    donohup           X
    doonintr          X
    dorepeat          X
    dosetenv          X
    dosuspend         X
    doswbrk           X
    doswitch          X
    doumask           X
    dounlimit         X
    dounsetenv        X
    dowhile           X
    dozip             X
    echo              X
    findlim           X
    func              X
    getval            X
    getword           X
    isbfunc           X
    islogin           X
    limtail           X
    plim              X
    preread           X
    prvars            X
    reexecute         X
    search            X
    setenv            X
    setlim            X
    srchx             X
    toend             X
    unalias           X
    unsetenv          X
    wfree             X

##### Variables

    Sgoal             X
    Stype             X
    environ           X
    limits            X

##### struct's

    limits            X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley Software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char *sccsid = "@(#)sh.func.c	5.3 (Berkeley) 5/13/86";
       9: #endif
      10:
      11: #include "sh.h"
      12: #include <sys/ioctl.h>
      13:
      14: /*
      15:  * C shell
      16:  */
      17:
      18: struct biltins *
      19: isbfunc(t)
      20:     struct command *t;
      21: {
      22:     register char *cp = t->t_dcom[0];
      23:     register struct biltins *bp, *bp1, *bp2;
      24:     int dolabel(), dofg1(), dobg1();
      25:     static struct biltins label = { "", dolabel, 0, 0 };
      26:     static struct biltins foregnd = { "%job", dofg1, 0, 0 };
      27:     static struct biltins backgnd = { "%job &", dobg1, 0, 0 };
      28:
      29:     if (lastchr(cp) == ':') {
      30:         label.bname = cp;
      31:         return (&label);
      32:     }
      33:     if (*cp == '%') {
      34:         if (t->t_dflg & FAND) {
      35:             t->t_dflg &= ~FAND;
      36:             backgnd.bname = cp;
      37:             return (&backgnd);
      38:         }
      39:         foregnd.bname = cp;
      40:         return (&foregnd);
      41:     }
      42:     /*
      43: 	 * Binary search
      44: 	 * Bp1 is the beginning of the current search range.
      45: 	 * Bp2 is one past the end.
      46: 	 */
      47:     for (bp1 = bfunc, bp2 = bfunc + nbfunc; bp1 < bp2;) {
      48:         register i;
      49:
      50:         bp = bp1 + (bp2 - bp1 >> 1);
      51:         if ((i = *cp - *bp->bname) == 0 &&
      52:             (i = strcmp(cp, bp->bname)) == 0)
      53:             return bp;
      54:         if (i < 0)
      55:             bp2 = bp;
      56:         else
      57:             bp1 = bp + 1;
      58:     }
      59:     return (0);
      60: }
      61:
      62: func(t, bp)
      63:     register struct command *t;
      64:     register struct biltins *bp;
      65: {
      66:     int i;
      67:
      68:     xechoit(t->t_dcom);
      69:     setname(bp->bname);
      70:     i = blklen(t->t_dcom) - 1;
      71:     if (i < bp->minargs)
      72:         bferr("Too few arguments");
      73:     if (i > bp->maxargs)
      74:         bferr("Too many arguments");
      75:     (*bp->bfunct)(t->t_dcom, t);
      76: }
      77:
      78: dolabel()
      79: {
      80:
      81: }
      82:
      83: doonintr(v)
      84:     char **v;
      85: {
      86:     register char *cp;
      87:     register char *vv = v[1];
      88:
      89:     if (parintr == SIG_IGN)
      90:         return;
      91:     if (setintr && intty)
      92:         bferr("Can't from terminal");
      93:     cp = gointr, gointr = 0, xfree(cp);
      94:     if (vv == 0) {
      95:         if (setintr)
      96:             (void) sigblock(sigmask(SIGINT));
      97:         else
      98:             (void) signal(SIGINT, SIG_DFL);
      99:         gointr = 0;
     100:     } else if (eq((vv = strip(vv)), "-")) {
     101:         (void) signal(SIGINT, SIG_IGN);
     102:         gointr = "-";
     103:     } else {
     104:         gointr = savestr(vv);
     105:         (void) signal(SIGINT, pintr);
     106:     }
     107: }
     108:
     109: donohup()
     110: {
     111:
     112:     if (intty)
     113:         bferr("Can't from terminal");
     114:     if (setintr == 0) {
     115:         (void) signal(SIGHUP, SIG_IGN);
     116: #ifdef CC
     117:         submit(getpid());
     118: #endif
     119:     }
     120: }
     121:
     122: dozip()
     123: {
     124:
     125:     ;
     126: }
     127:
     128: prvars()
     129: {
     130:
     131:     plist(&shvhed);
     132: }
     133:
     134: doalias(v)
     135:     register char **v;
     136: {
     137:     register struct varent *vp;
     138:     register char *p;
     139:
     140:     v++;
     141:     p = *v++;
     142:     if (p == 0)
     143:         plist(&aliases);
     144:     else if (*v == 0) {
     145:         vp = adrof1(strip(p), &aliases);
     146:         if (vp)
     147:             blkpr(vp->vec), printf("\n");
     148:     } else {
     149:         if (eq(p, "alias") || eq(p, "unalias")) {
     150:             setname(p);
     151:             bferr("Too dangerous to alias that");
     152:         }
     153:         set1(strip(p), saveblk(v), &aliases);
     154:     }
     155: }
     156:
     157: unalias(v)
     158:     char **v;
     159: {
     160:
     161:     unset1(v, &aliases);
     162: }
     163:
     164: dologout()
     165: {
     166:
     167:     islogin();
     168:     goodbye();
     169: }
     170:
     171: dologin(v)
     172:     char **v;
     173: {
     174:
     175:     islogin();
     176:     rechist();
     177:     (void) signal(SIGTERM, parterm);
     178:     execl("/bin/login", "login", v[1], 0);
     179:     untty();
     180:     exit(1);
     181: }
     182:
     183: #ifdef NEWGRP
     184: donewgrp(v)
     185:     char **v;
     186: {
     187:
     188:     if (chkstop == 0 && setintr)
     189:         panystop(0);
     190:     (void) signal(SIGTERM, parterm);
     191:     execl("/bin/newgrp", "newgrp", v[1], 0);
     192:     execl("/usr/bin/newgrp", "newgrp", v[1], 0);
     193:     untty();
     194:     exit(1);
     195: }
     196: #endif
     197:
     198: islogin()
     199: {
     200:
     201:     if (chkstop == 0 && setintr)
     202:         panystop(0);
     203:     if (loginsh)
     204:         return;
     205:     error("Not login shell");
     206: }
     207:
     208: doif(v, kp)
     209:     char **v;
     210:     struct command *kp;
     211: {
     212:     register int i;
     213:     register char **vv;
     214:
     215:     v++;
     216:     i = exp(&v);
     217:     vv = v;
     218:     if (*vv == NOSTR)
     219:         bferr("Empty if");
     220:     if (eq(*vv, "then")) {
     221:         if (*++vv)
     222:             bferr("Improper then");
     223:         setname("then");
     224:         /*
     225: 		 * If expression was zero, then scan to else,
     226: 		 * otherwise just fall into following code.
     227: 		 */
     228:         if (!i)
     229:             search(ZIF, 0);
     230:         return;
     231:     }
     232:     /*
     233: 	 * Simple command attached to this if.
     234: 	 * Left shift the node in this tree, munging it
     235: 	 * so we can reexecute it.
     236: 	 */
     237:     if (i) {
     238:         lshift(kp->t_dcom, vv - kp->t_dcom);
     239:         reexecute(kp);
     240:         donefds();
     241:     }
     242: }
     243:
     244: /*
     245:  * Reexecute a command, being careful not
     246:  * to redo i/o redirection, which is already set up.
     247:  */
     248: reexecute(kp)
     249:     register struct command *kp;
     250: {
     251:
     252:     kp->t_dflg &= FSAVE;
     253:     kp->t_dflg |= FREDO;
     254:     /*
     255: 	 * If tty is still ours to arbitrate, arbitrate it;
     256: 	 * otherwise dont even set pgrp's as the jobs would
     257: 	 * then have no way to get the tty (we can't give it
     258: 	 * to them, and our parent wouldn't know their pgrp, etc.
     259: 	 */
     260:     execute(kp, tpgrp > 0 ? tpgrp : -1);
     261: }
     262:
     263: doelse()
     264: {
     265:
     266:     search(ZELSE, 0);
     267: }
     268:
     269: dogoto(v)
     270:     char **v;
     271: {
     272:     register struct whyle *wp;
     273:     char *lp;
     274:
     275:     /*
     276: 	 * While we still can, locate any unknown ends of existing loops.
     277: 	 * This obscure code is the WORST result of the fact that we
     278: 	 * don't really parse.
     279: 	 */
     280:     for (wp = whyles; wp; wp = wp->w_next)
     281:         if (wp->w_end == 0) {
     282:             search(ZBREAK, 0);
     283:             wp->w_end = btell();
     284:         } else
     285:             bseek(wp->w_end);
     286:     search(ZGOTO, 0, lp = globone(v[1]));
     287:     xfree(lp);
     288:     /*
     289: 	 * Eliminate loops which were exited.
     290: 	 */
     291:     wfree();
     292: }
     293:
     294: doswitch(v)
     295:     register char **v;
     296: {
     297:     register char *cp, *lp;
     298:
     299:     v++;
     300:     if (!*v || *(*v++) != '(')
     301:         goto syntax;
     302:     cp = **v == ')' ? "" : *v++;
     303:     if (*(*v++) != ')')
     304:         v--;
     305:     if (*v)
     306: syntax:
     307:         error("Syntax error");
     308:     search(ZSWITCH, 0, lp = globone(cp));
     309:     xfree(lp);
     310: }
     311:
     312: dobreak()
     313: {
     314:
     315:     if (whyles)
     316:         toend();
     317:     else
     318:         bferr("Not in while/foreach");
     319: }
     320:
     321: doexit(v)
     322:     char **v;
     323: {
     324:
     325:     if (chkstop == 0)
     326:         panystop(0);
     327:     /*
     328: 	 * Don't DEMAND parentheses here either.
     329: 	 */
     330:     v++;
     331:     if (*v) {
     332:         set("status", putn(exp(&v)));
     333:         if (*v)
     334:             bferr("Expression syntax");
     335:     }
     336:     btoeof();
     337:     if (intty)
     338:         (void) close(SHIN);
     339: }
     340:
     341: doforeach(v)
     342:     register char **v;
     343: {
     344:     register char *cp;
     345:     register struct whyle *nwp;
     346:
     347:     v++;
     348:     cp = strip(*v);
     349:     while (*cp && letter(*cp))
     350:         cp++;
     351:     if (*cp || strlen(*v) >= 20)
     352:         bferr("Invalid variable");
     353:     cp = *v++;
     354:     if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')')
     355:         bferr("Words not ()'ed");
     356:     v++;
     357:     gflag = 0, tglob(v);
     358:     v = glob(v);
     359:     if (v == 0)
     360:         bferr("No match");
     361:     nwp = (struct whyle *) calloc(1, sizeof *nwp);
     362:     nwp->w_fe = nwp->w_fe0 = v; gargv = 0;
     363:     nwp->w_start = btell();
     364:     nwp->w_fename = savestr(cp);
     365:     nwp->w_next = whyles;
     366:     whyles = nwp;
     367:     /*
     368: 	 * Pre-read the loop so as to be more
     369: 	 * comprehensible to a terminal user.
     370: 	 */
     371:     if (intty)
     372:         preread();
     373:     doagain();
     374: }
     375:
     376: dowhile(v)
     377:     char **v;
     378: {
     379:     register int status;
     380:     register bool again = whyles != 0 && whyles->w_start == lineloc &&
     381:         whyles->w_fename == 0;
     382:
     383:     v++;
     384:     /*
     385: 	 * Implement prereading here also, taking care not to
     386: 	 * evaluate the expression before the loop has been read up
     387: 	 * from a terminal.
     388: 	 */
     389:     if (intty && !again)
     390:         status = !exp0(&v, 1);
     391:     else
     392:         status = !exp(&v);
     393:     if (*v)
     394:         bferr("Expression syntax");
     395:     if (!again) {
     396:         register struct whyle *nwp = (struct whyle *) calloc(1, sizeof (*nwp));
     397:
     398:         nwp->w_start = lineloc;
     399:         nwp->w_end = 0;
     400:         nwp->w_next = whyles;
     401:         whyles = nwp;
     402:         if (intty) {
     403:             /*
     404: 			 * The tty preread
     405: 			 */
     406:             preread();
     407:             doagain();
     408:             return;
     409:         }
     410:     }
     411:     if (status)
     412:         /* We ain't gonna loop no more, no more! */
     413:         toend();
     414: }
     415:
     416: preread()
     417: {
     418:
     419:     whyles->w_end = -1;
     420:     if (setintr)
     421:         (void) sigsetmask(sigblock(0L) & ~sigmask(SIGINT));
     422:     search(ZBREAK, 0);
     423:     if (setintr)
     424:         (void) sigblock(sigmask(SIGINT));
     425:     whyles->w_end = btell();
     426: }
     427:
     428: doend()
     429: {
     430:
     431:     if (!whyles)
     432:         bferr("Not in while/foreach");
     433:     whyles->w_end = btell();
     434:     doagain();
     435: }
     436:
     437: docontin()
     438: {
     439:
     440:     if (!whyles)
     441:         bferr("Not in while/foreach");
     442:     doagain();
     443: }
     444:
     445: doagain()
     446: {
     447:
     448:     /* Repeating a while is simple */
     449:     if (whyles->w_fename == 0) {
     450:         bseek(whyles->w_start);
     451:         return;
     452:     }
     453:     /*
     454: 	 * The foreach variable list actually has a spurious word
     455: 	 * ")" at the end of the w_fe list.  Thus we are at the
     456: 	 * of the list if one word beyond this is 0.
     457: 	 */
     458:     if (!whyles->w_fe[1]) {
     459:         dobreak();
     460:         return;
     461:     }
     462:     set(whyles->w_fename, savestr(*whyles->w_fe++));
     463:     bseek(whyles->w_start);
     464: }
     465:
     466: dorepeat(v, kp)
     467:     char **v;
     468:     struct command *kp;
     469: {
     470:     register int i;
     471:     register long omask;
     472:
     473:     i = getn(v[1]);
     474:     if (setintr)
     475:         omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT);
     476:     lshift(v, 2);
     477:     while (i > 0) {
     478:         if (setintr)
     479:             (void) sigsetmask(omask);
     480:         reexecute(kp);
     481:         --i;
     482:     }
     483:     donefds();
     484:     if (setintr)
     485:         (void) sigsetmask(omask);
     486: }
     487:
     488: doswbrk()
     489: {
     490:
     491:     search(ZBRKSW, 0);
     492: }
     493:
     494: srchx(cp)
     495:     register char *cp;
     496: {
     497:     register struct srch *sp, *sp1, *sp2;
     498:     register i;
     499:
     500:     /*
     501: 	 * Binary search
     502: 	 * Sp1 is the beginning of the current search range.
     503: 	 * Sp2 is one past the end.
     504: 	 */
     505:     for (sp1 = srchn, sp2 = srchn + nsrchn; sp1 < sp2;) {
     506:         sp = sp1 + (sp2 - sp1 >> 1);
     507:         if ((i = *cp - *sp->s_name) == 0 &&
     508:             (i = strcmp(cp, sp->s_name)) == 0)
     509:             return sp->s_value;
     510:         if (i < 0)
     511:             sp2 = sp;
     512:         else
     513:             sp1 = sp + 1;
     514:     }
     515:     return (-1);
     516: }
     517:
     518: char    Stype;
     519: char    *Sgoal;
     520:
     521: /*VARARGS2*/
     522: search(type, level, goal)
     523:     int type;
     524:     register int level;
     525:     char *goal;
     526: {
     527:     char wordbuf[BUFSIZ];
     528:     register char *aword = wordbuf;
     529:     register char *cp;
     530:
     531:     Stype = type; Sgoal = goal;
     532:     if (type == ZGOTO)
     533:         bseek((off_t)0);
     534:     do {
     535:         if (intty && fseekp == feobp)
     536:             printf("? "), flush();
     537:         aword[0] = 0;
     538:         (void) getword(aword);
     539:         switch (srchx(aword)) {
     540:
     541:         case ZELSE:
     542:             if (level == 0 && type == ZIF)
     543:                 return;
     544:             break;
     545:
     546:         case ZIF:
     547:             while (getword(aword))
     548:                 continue;
     549:             if ((type == ZIF || type == ZELSE) && eq(aword, "then"))
     550:                 level++;
     551:             break;
     552:
     553:         case ZENDIF:
     554:             if (type == ZIF || type == ZELSE)
     555:                 level--;
     556:             break;
     557:
     558:         case ZFOREACH:
     559:         case ZWHILE:
     560:             if (type == ZBREAK)
     561:                 level++;
     562:             break;
     563:
     564:         case ZEND:
     565:             if (type == ZBREAK)
     566:                 level--;
     567:             break;
     568:
     569:         case ZSWITCH:
     570:             if (type == ZSWITCH || type == ZBRKSW)
     571:                 level++;
     572:             break;
     573:
     574:         case ZENDSW:
     575:             if (type == ZSWITCH || type == ZBRKSW)
     576:                 level--;
     577:             break;
     578:
     579:         case ZLABEL:
     580:             if (type == ZGOTO && getword(aword) && eq(aword, goal))
     581:                 level = -1;
     582:             break;
     583:
     584:         default:
     585:             if (type != ZGOTO && (type != ZSWITCH || level != 0))
     586:                 break;
     587:             if (lastchr(aword) != ':')
     588:                 break;
     589:             aword[strlen(aword) - 1] = 0;
     590:             if (type == ZGOTO && eq(aword, goal) || type == ZSWITCH && eq(aword, "default"))
     591:                 level = -1;
     592:             break;
     593:
     594:         case ZCASE:
     595:             if (type != ZSWITCH || level != 0)
     596:                 break;
     597:             (void) getword(aword);
     598:             if (lastchr(aword) == ':')
     599:                 aword[strlen(aword) - 1] = 0;
     600:             cp = strip(Dfix1(aword));
     601:             if (Gmatch(goal, cp))
     602:                 level = -1;
     603:             xfree(cp);
     604:             break;
     605:
     606:         case ZDEFAULT:
     607:             if (type == ZSWITCH && level == 0)
     608:                 level = -1;
     609:             break;
     610:         }
     611:         (void) getword(NOSTR);
     612:     } while (level >= 0);
     613: }
     614:
     615: getword(wp)
     616:     register char *wp;
     617: {
     618:     register int found = 0;
     619:     register int c, d;
     620:
     621:     c = readc(1);
     622:     d = 0;
     623:     do {
     624:         while (c == ' ' || c == '\t')
     625:             c = readc(1);
     626:         if (c == '#')
     627:             do
     628:                 c = readc(1);
     629:             while (c >= 0 && c != '\n');
     630:         if (c < 0)
     631:             goto past;
     632:         if (c == '\n') {
     633:             if (wp)
     634:                 break;
     635:             return (0);
     636:         }
     637:         unreadc(c);
     638:         found = 1;
     639:         do {
     640:             c = readc(1);
     641:             if (c == '\\' && (c = readc(1)) == '\n')
     642:                 c = ' ';
     643:             if (c == '\'' || c == '"')
     644:                 if (d == 0)
     645:                     d = c;
     646:                 else if (d == c)
     647:                     d = 0;
     648:             if (c < 0)
     649:                 goto past;
     650:             if (wp)
     651:                 *wp++ = c;
     652:         } while ((d || c != ' ' && c != '\t') && c != '\n');
     653:     } while (wp == 0);
     654:     unreadc(c);
     655:     if (found)
     656:         *--wp = 0;
     657:     return (found);
     658:
     659: past:
     660:     switch (Stype) {
     661:
     662:     case ZIF:
     663:         bferr("then/endif not found");
     664:
     665:     case ZELSE:
     666:         bferr("endif not found");
     667:
     668:     case ZBRKSW:
     669:     case ZSWITCH:
     670:         bferr("endsw not found");
     671:
     672:     case ZBREAK:
     673:         bferr("end not found");
     674:
     675:     case ZGOTO:
     676:         setname(Sgoal);
     677:         bferr("label not found");
     678:     }
     679:     /*NOTREACHED*/
     680: }
     681:
     682: toend()
     683: {
     684:
     685:     if (whyles->w_end == 0) {
     686:         search(ZBREAK, 0);
     687:         whyles->w_end = btell() - 1;
     688:     } else
     689:         bseek(whyles->w_end);
     690:     wfree();
     691: }
     692:
     693: wfree()
     694: {
     695:     long o = btell();
     696:
     697:     while (whyles) {
     698:         register struct whyle *wp = whyles;
     699:         register struct whyle *nwp = wp->w_next;
     700:
     701:         if (o >= wp->w_start && (wp->w_end == 0 || o < wp->w_end))
     702:             break;
     703:         if (wp->w_fe0)
     704:             blkfree(wp->w_fe0);
     705:         if (wp->w_fename)
     706:             xfree(wp->w_fename);
     707:         xfree((char *)wp);
     708:         whyles = nwp;
     709:     }
     710: }
     711:
     712: doecho(v)
     713:     char **v;
     714: {
     715:
     716:     echo(' ', v);
     717: }
     718:
     719: doglob(v)
     720:     char **v;
     721: {
     722:
     723:     echo(0, v);
     724:     flush();
     725: }
     726:
     727: echo(sep, v)
     728:     char sep;
     729:     register char **v;
     730: {
     731:     register char *cp;
     732:     int nonl = 0;
     733:
     734:     if (setintr)
     735:         (void) sigsetmask(sigblock(0L) & ~sigmask(SIGINT));
     736:     v++;
     737:     if (*v == 0)
     738:         return;
     739:     gflag = 0, tglob(v);
     740:     if (gflag) {
     741:         v = glob(v);
     742:         if (v == 0)
     743:             bferr("No match");
     744:     } else
     745:         trim(v);
     746:     if (sep == ' ' && *v && !strcmp(*v, "-n"))
     747:         nonl++, v++;
     748:     while (cp = *v++) {
     749:         register int c;
     750:
     751:         while (c = *cp++)
     752:             putchar(c | QUOTE);
     753:         if (*v)
     754:             putchar(sep | QUOTE);
     755:     }
     756:     if (sep && nonl == 0)
     757:         putchar('\n');
     758:     else
     759:         flush();
     760:     if (setintr)
     761:         (void) sigblock(sigmask(SIGINT));
     762:     if (gargv)
     763:         blkfree(gargv), gargv = 0;
     764: }
     765:
     766: char    **environ;
     767:
     768: dosetenv(v)
     769:     register char **v;
     770: {
     771:     char *vp, *lp;
     772:
     773:     v++;
     774:     if ((vp = *v++) == 0) {
     775:         register char **ep;
     776:
     777:         if (setintr)
     778:             (void) sigsetmask(sigblock(0L) & ~ sigmask(SIGINT));
     779:         for (ep = environ; *ep; ep++)
     780:             printf("%s\n", *ep);
     781:         return;
     782:     }
     783:     if ((lp = *v++) == 0)
     784:         lp = "";
     785:     setenv(vp, lp = globone(lp));
     786:     if (eq(vp, "PATH")) {
     787:         importpath(lp);
     788:         dohash();
     789:     }
     790:     xfree(lp);
     791: }
     792:
     793: dounsetenv(v)
     794:     register char **v;
     795: {
     796:
     797:     v++;
     798:     do
     799:         unsetenv(*v++);
     800:     while (*v);
     801: }
     802:
     803: setenv(name, val)
     804:     char *name, *val;
     805: {
     806:     register char **ep = environ;
     807:     register char *cp, *dp;
     808:     char *blk[2], **oep = ep;
     809:
     810:     for (; *ep; ep++) {
     811:         for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++)
     812:             continue;
     813:         if (*cp != 0 || *dp != '=')
     814:             continue;
     815:         cp = strspl("=", val);
     816:         xfree(*ep);
     817:         *ep = strspl(name, cp);
     818:         xfree(cp);
     819:         trim(ep);
     820:         return;
     821:     }
     822:     blk[0] = strspl(name, "="); blk[1] = 0;
     823:     environ = blkspl(environ, blk);
     824:     xfree((char *)oep);
     825:     setenv(name, val);
     826: }
     827:
     828: unsetenv(name)
     829:     char *name;
     830: {
     831:     register char **ep = environ;
     832:     register char *cp, *dp;
     833:     char **oep = ep;
     834:
     835:     for (; *ep; ep++) {
     836:         for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++)
     837:             continue;
     838:         if (*cp != 0 || *dp != '=')
     839:             continue;
     840:         cp = *ep;
     841:         *ep = 0;
     842:         environ = blkspl(environ, ep+1);
     843:         *ep = cp;
     844:         xfree(cp);
     845:         xfree((char *)oep);
     846:         return;
     847:     }
     848: }
     849:
     850: doumask(v)
     851:     register char **v;
     852: {
     853:     register char *cp = v[1];
     854:     register int i;
     855:
     856:     if (cp == 0) {
     857:         i = umask(0);
     858:         (void) umask(i);
     859:         printf("%o\n", i);
     860:         return;
     861:     }
     862:     i = 0;
     863:     while (digit(*cp) && *cp != '8' && *cp != '9')
     864:         i = i * 8 + *cp++ - '0';
     865:     if (*cp || i < 0 || i > 0777)
     866:         bferr("Improper mask");
     867:     (void) umask(i);
     868: }
     869:
     870:
     871: #ifndef NOLIMITS
     872: struct limits {
     873:     int limconst;
     874:     char    *limname;
     875:     int limdiv;
     876:     char    *limscale;
     877: } limits[] = {
     878:     RLIMIT_CPU, "cputime",  1,  "seconds",
     879:     RLIMIT_FSIZE,   "filesize", 1024,   "kbytes",
     880:     RLIMIT_DATA,    "datasize", 1024,   "kbytes",
     881:     RLIMIT_STACK,   "stacksize",    1024,   "kbytes",
     882:     RLIMIT_CORE,    "coredumpsize", 1024,   "kbytes",
     883:     RLIMIT_RSS, "memoryuse",    1024,   "kbytes",
     884:     -1,     0,
     885: };
     886:
     887: struct limits *
     888: findlim(cp)
     889:     char *cp;
     890: {
     891:     register struct limits *lp, *res;
     892:
     893:     res = 0;
     894:     for (lp = limits; lp->limconst >= 0; lp++)
     895:         if (prefix(cp, lp->limname)) {
     896:             if (res)
     897:                 bferr("Ambiguous");
     898:             res = lp;
     899:         }
     900:     if (res)
     901:         return (res);
     902:     bferr("No such limit");
     903:     /*NOTREACHED*/
     904: }
     905:
     906: dolimit(v)
     907:     register char **v;
     908: {
     909:     register struct limits *lp;
     910:     register long limit;
     911:     long getval();
     912:     char hard = 0;
     913:
     914:     v++;
     915:     if (*v && eq(*v, "-h")) {
     916:         hard = 1;
     917:         v++;
     918:     }
     919:     if (*v == 0) {
     920:         for (lp = limits; lp->limconst >= 0; lp++)
     921:             plim(lp, hard);
     922:         return;
     923:     }
     924:     lp = findlim(v[0]);
     925:     if (v[1] == 0) {
     926:         plim(lp,  hard);
     927:         return;
     928:     }
     929:     limit = getval(lp, v+1);
     930:     if (setlim(lp, hard, limit) < 0)
     931:         error(NOSTR);
     932: }
     933:
     934: long
     935: getval(lp, v)
     936:     register struct limits *lp;
     937:     char **v;
     938: {
     939:     register float f;
     940:     double atof();
     941:     char *cp = *v++;
     942:
     943:     f = atof(cp);
     944:     while (digit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E')
     945:         cp++;
     946:     if (*cp == 0) {
     947:         if (*v == 0)
     948:             return ((long)(f+0.5) * lp->limdiv);
     949:         cp = *v;
     950:     }
     951:     switch (*cp) {
     952:
     953:     case ':':
     954:         if (lp->limconst != RLIMIT_CPU)
     955:             goto badscal;
     956:         return ((long)(f * 60.0 + atof(cp+1)));
     957:
     958:     case 'h':
     959:         if (lp->limconst != RLIMIT_CPU)
     960:             goto badscal;
     961:         limtail(cp, "hours");
     962:         f *= 3600.;
     963:         break;
     964:
     965:     case 'm':
     966:         if (lp->limconst == RLIMIT_CPU) {
     967:             limtail(cp, "minutes");
     968:             f *= 60.;
     969:             break;
     970:         }
     971:     case 'M':
     972:         if (lp->limconst == RLIMIT_CPU)
     973:             goto badscal;
     974:         *cp = 'm';
     975:         limtail(cp, "megabytes");
     976:         f *= 1024.*1024.;
     977:         break;
     978:
     979:     case 's':
     980:         if (lp->limconst != RLIMIT_CPU)
     981:             goto badscal;
     982:         limtail(cp, "seconds");
     983:         break;
     984:
     985:     case 'k':
     986:         if (lp->limconst == RLIMIT_CPU)
     987:             goto badscal;
     988:         limtail(cp, "kbytes");
     989:         f *= 1024;
     990:         break;
     991:
     992:     case 'u':
     993:         limtail(cp, "unlimited");
     994:         return (RLIM_INFINITY);
     995:
     996:     default:
     997: badscal:
     998:         bferr("Improper or unknown scale factor");
     999:     }
    1000:     return ((long)(f+0.5));
    1001: }
    1002:
    1003: limtail(cp, str0)
    1004:     char *cp, *str0;
    1005: {
    1006:     register char *str = str0;
    1007:
    1008:     while (*cp && *cp == *str)
    1009:         cp++, str++;
    1010:     if (*cp)
    1011:         error("Bad scaling; did you mean ``%s''?", str0);
    1012: }
    1013:
    1014: plim(lp, hard)
    1015:     register struct limits *lp;
    1016:     char hard;
    1017: {
    1018:     struct rlimit rlim;
    1019:     long limit;
    1020:
    1021:     printf("%s \t", lp->limname);
    1022:     (void) getrlimit(lp->limconst, &rlim);
    1023:     limit = hard ? rlim.rlim_max : rlim.rlim_cur;
    1024:     if (limit == RLIM_INFINITY)
    1025:         printf("unlimited");
    1026:     else if (lp->limconst == RLIMIT_CPU)
    1027:         psecs((long)limit);
    1028:     else
    1029:         printf("%ld %s", limit / lp->limdiv, lp->limscale);
    1030:     printf("\n");
    1031: }
    1032:
    1033: dounlimit(v)
    1034:     register char **v;
    1035: {
    1036:     register struct limits *lp;
    1037:     int err = 0;
    1038:     char hard = 0;
    1039:
    1040:     v++;
    1041:     if (*v && eq(*v, "-h")) {
    1042:         hard = 1;
    1043:         v++;
    1044:     }
    1045:     if (*v == 0) {
    1046:         for (lp = limits; lp->limconst >= 0; lp++)
    1047:             if (setlim(lp, hard, (long)RLIM_INFINITY) < 0)
    1048:                 err++;
    1049:         if (err)
    1050:             error(NOSTR);
    1051:         return;
    1052:     }
    1053:     while (*v) {
    1054:         lp = findlim(*v++);
    1055:         if (setlim(lp, hard, (long)RLIM_INFINITY) < 0)
    1056:             error(NOSTR);
    1057:     }
    1058: }
    1059:
    1060: setlim(lp, hard, limit)
    1061:     register struct limits *lp;
    1062:     char hard;
    1063:     long limit;
    1064: {
    1065:     struct rlimit rlim;
    1066:
    1067:     (void) getrlimit(lp->limconst, &rlim);
    1068:     if (hard)
    1069:         rlim.rlim_max = limit;
    1070:     else if (limit == RLIM_INFINITY && geteuid() != 0)
    1071:         rlim.rlim_cur = rlim.rlim_max;
    1072:     else
    1073:         rlim.rlim_cur = limit;
    1074:     if (setrlimit(lp->limconst, &rlim) < 0) {
    1075:         printf("%s: %s: Can't %s%s limit\n", bname, lp->limname,
    1076:             limit == RLIM_INFINITY ? "remove" : "set",
    1077:             hard ? " hard" : "");
    1078:         return (-1);
    1079:     }
    1080:     return (0);
    1081: }
    1082: #endif !NOLIMITS
    1083:
    1084: dosuspend()
    1085: {
    1086:     int ldisc, ctpgrp;
    1087:     int (*old)();
    1088:
    1089:     if (loginsh)
    1090:         error("Can't suspend a login shell (yet)");
    1091:     untty();
    1092:     old = signal(SIGTSTP, SIG_DFL);
    1093:     (void) kill(0, SIGTSTP);
    1094:     /* the shell stops here */
    1095:     (void) signal(SIGTSTP, old);
    1096:     if (tpgrp != -1) {
    1097: retry:
    1098:         (void) ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp);
    1099:         if (ctpgrp != opgrp) {
    1100:             old = signal(SIGTTIN, SIG_DFL);
    1101:             (void) kill(0, SIGTTIN);
    1102:             (void) signal(SIGTTIN, old);
    1103:             goto retry;
    1104:         }
    1105:         (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&shpgrp);
    1106:         (void) setpgrp(0, shpgrp);
    1107:     }
    1108:     (void) ioctl(FSHTTY, TIOCGETD, (char *)&oldisc);
    1109:     if (oldisc != NTTYDISC) {
    1110:         printf("Switching to new tty driver...\n");
    1111:         ldisc = NTTYDISC;
    1112:         (void) ioctl(FSHTTY, TIOCSETD, (char *)&ldisc);
    1113:     }
    1114: }
    1115:
    1116: doeval(v)
    1117:     char **v;
    1118: {
    1119:     char **oevalvec = evalvec;
    1120:     char *oevalp = evalp;
    1121:     jmp_buf osetexit;
    1122:     int reenter;
    1123:     char **gv = 0;
    1124:
    1125:     v++;
    1126:     if (*v == 0)
    1127:         return;
    1128:     gflag = 0, tglob(v);
    1129:     if (gflag) {
    1130:         gv = v = glob(v);
    1131:         gargv = 0;
    1132:         if (v == 0)
    1133:             error("No match");
    1134:         v = copyblk(v);
    1135:     } else
    1136:         trim(v);
    1137:     getexit(osetexit);
    1138:     reenter = 0;
    1139:     setexit();
    1140:     reenter++;
    1141:     if (reenter == 1) {
    1142:         evalvec = v;
    1143:         evalp = 0;
    1144:         process(0);
    1145:     }
    1146:     evalvec = oevalvec;
    1147:     evalp = oevalp;
    1148:     doneinp = 0;
    1149:     if (gv)
    1150:         blkfree(gv);
    1151:     resexit(osetexit);
    1152:     if (reenter >= 2)
    1153:         error(NOSTR);
    1154: }

#### Defined functions

doagain defined in line 445; used 4 times

- in line 373, 407, 434, 442

doalias defined in line 134; used 2 times

- in /usr/src/bin/csh/sh.init.c line 17, 91

dobreak defined in line 312; used 3 times

- in line 459
- in /usr/src/bin/csh/sh.init.c line 19, 94

docontin defined in line 437; used 2 times

- in /usr/src/bin/csh/sh.init.c line 21, 102

doecho defined in line 712; used 2 times

- in /usr/src/bin/csh/sh.init.c line 23, 105

doelse defined in line 263; used 2 times

- in /usr/src/bin/csh/sh.init.c line 24, 106

doend defined in line 428; used 2 times

- in /usr/src/bin/csh/sh.init.c line 25, 107

doeval defined in line 1116; used 2 times

- in /usr/src/bin/csh/sh.init.c line 28, 110

doexit defined in line 321; used 2 times

- in /usr/src/bin/csh/sh.init.c line 29, 112

doforeach defined in line 341; used 2 times

- in /usr/src/bin/csh/sh.init.c line 31, 114

doglob defined in line 719; used 2 times

- in /usr/src/bin/csh/sh.init.c line 32, 118

dogoto defined in line 269; used 2 times

- in /usr/src/bin/csh/sh.init.c line 33, 119

doif defined in line 208; used 2 times

- in /usr/src/bin/csh/sh.init.c line 36, 124

dolabel defined in line 78; used 2 times

- in line 24-25(2)

dolimit defined in line 906; used 2 times

- in /usr/src/bin/csh/sh.init.c line 41, 128

dologin defined in line 171; used 2 times

- in /usr/src/bin/csh/sh.init.c line 43, 130

dologout defined in line 164; used 2 times

- in /usr/src/bin/csh/sh.init.c line 44, 131

donewgrp defined in line 184; used 2 times

- in /usr/src/bin/csh/sh.init.c line 46, 133

donohup defined in line 109; used 2 times

- in /usr/src/bin/csh/sh.init.c line 50, 136

doonintr defined in line 83; used 2 times

- in /usr/src/bin/csh/sh.init.c line 51, 138

dorepeat defined in line 466; used 2 times

- in /usr/src/bin/csh/sh.init.c line 54, 145

dosetenv defined in line 768; used 2 times

- in /usr/src/bin/csh/sh.init.c line 56, 147

dosuspend defined in line 1084; used 2 times

- in /usr/src/bin/csh/sh.init.c line 59, 151

doswbrk defined in line 488; used 2 times

- in /usr/src/bin/csh/sh.init.c line 60, 95

doswitch defined in line 294; used 2 times

- in /usr/src/bin/csh/sh.init.c line 61, 152

doumask defined in line 850; used 2 times

- in /usr/src/bin/csh/sh.init.c line 66, 154

dounlimit defined in line 1033; used 2 times

- in /usr/src/bin/csh/sh.init.c line 64, 158

dounsetenv defined in line 793; used 2 times

- in /usr/src/bin/csh/sh.init.c line 81, 161

dowhile defined in line 376; used 2 times

- in /usr/src/bin/csh/sh.init.c line 68, 164

dozip defined in line 122; used 5 times

- in /usr/src/bin/csh/sh.init.c line 70, 99-109(4)

echo defined in line 727; used 2 times

- in line 716, 723

findlim defined in line 887; used 2 times

- in line 924, 1054

func defined in line 62; used 1 times

- in /usr/src/bin/csh/sh.sem.c line 240

getval defined in line 934; used 2 times

- in line 911, 929

getword defined in line 615; used 5 times

- in line 538, 547, 580, 597, 611

isbfunc defined in line 18; used 2 times

- in /usr/src/bin/csh/sh.h line 426
- in /usr/src/bin/csh/sh.sem.c line 105

islogin defined in line 198; used 2 times

- in line 167, 175

limtail defined in line 1003; used 6 times

- in line 961, 967, 975, 982, 988-993(2)

plim defined in line 1014; used 2 times

- in line 921-926(2)

preread defined in line 416; used 2 times

- in line 372, 406

prvars defined in line 128; used 2 times

- in /usr/src/bin/csh/sh.set.c line 29, 149

reexecute defined in line 248; used 2 times

- in line 239, 480

search defined in line 522; used 9 times

- in line 229, 266, 282-286(2), 308, 422, 491, 686
- in /usr/src/bin/csh/sh.c line 651

setenv defined in line 803; used 6 times

- in line 785, 825
- in /usr/src/bin/csh/sh.set.c line 85-89(3), 557

setlim defined in line 1060; used 3 times

- in line 930, 1047, 1055

srchx defined in line 494; used 2 times

- in line 539
- in /usr/src/bin/csh/sh.parse.c line 445

toend defined in line 682; used 2 times

- in line 316, 413

unalias defined in line 157; used 2 times

- in /usr/src/bin/csh/sh.init.c line 78, 155

unsetenv defined in line 828; used 1 times

- in line 799

wfree defined in line 693; used 3 times

- in line 291, 690
- in /usr/src/bin/csh/sh.lex.c line 1318

#### Defined variables

Sgoal defined in line 519; used 2 times

- in line 531, 676

Stype defined in line 518; used 2 times

- in line 531, 660

environ defined in line 766; used 7 times

- in line 779, 806, 823(2), 831, 842(2)

limits defined in line 877; used 3 times

- in line 894, 920, 1046

sccsid defined in line 8; never used

#### Defined struct's

limits defined in line 872; used 14 times

- in line 887-891(4), 909(2), 936(2), 1015(2), 1036(2), 1061(2)

Last modified: 1991-08-31 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3248 |