1 /* $Header: /src/pub/tcsh/sh.func.c,v 3.103 2002/07/09 12:56:55 christos Exp $ */
3 * sh.func.c: csh builtin functions
6 * Copyright (c) 1980, 1991 The Regents of the University of California.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 RCSID("$Id: sh.func.c,v 3.103 2002/07/09 12:56:55 christos Exp $")
42 #endif /* WINNT_NATIVE */
47 extern int just_signaled;
48 extern char **environ;
50 extern bool MapsAreInited;
51 extern bool NLSMapsAreInited;
52 extern bool NoNLSRebind;
53 extern bool GotTermCaps;
55 static int zlast = -1;
57 static void islogin __P((void));
58 static void preread __P((void));
59 static void doagain __P((void));
60 static char *isrchx __P((int));
61 static void search __P((int, int, Char *));
62 static int getword __P((Char *));
63 static void toend __P((void));
64 static void xecho __P((int, Char **));
65 static bool islocale_var __P((Char *));
71 register Char *cp = t->t_dcom[0];
72 register struct biltins *bp, *bp1, *bp2;
73 static struct biltins label = {"", dozip, 0, 0};
74 static struct biltins foregnd = {"%job", dofg1, 0, 0};
75 static struct biltins backgnd = {"%job &", dobg1, 0, 0};
78 * We never match a builtin that has quoted the first
79 * character; this has been the traditional way to escape
85 if (*cp != ':' && lastchr(cp) == ':') {
86 label.bname = short2str(cp);
90 if (t->t_dflg & F_AMPERSAND) {
91 t->t_dflg &= ~F_AMPERSAND;
92 backgnd.bname = short2str(cp);
95 foregnd.bname = short2str(cp);
100 * This is a perhaps kludgy way to determine if the warp builtin is to be
101 * acknowledged or not. If checkwarp() fails, then we are to assume that
102 * the warp command is invalid, and carry on as we would handle any other
103 * non-builtin command. -- JDK 2/4/88
105 if (eq(STRwarp, cp) && !checkwarp()) {
106 return (0); /* this builtin disabled */
110 * Binary search Bp1 is the beginning of the current search range. Bp2 is
113 for (bp1 = bfunc, bp2 = bfunc + nbfunc; bp1 < bp2;) {
116 bp = bp1 + ((bp2 - bp1) >> 1);
117 if ((i = ((char) *cp) - *bp->bname) == 0 &&
118 (i = StrQcmp(cp, str2short(bp->bname))) == 0)
126 return nt_check_additional_builtins(cp);
127 #endif /*WINNT_NATIVE*/
133 register struct command *t;
134 register struct biltins *bp;
140 i = blklen(t->t_dcom) - 1;
142 stderror(ERR_NAME | ERR_TOOFEW);
144 stderror(ERR_NAME | ERR_TOOMANY);
145 (*bp->bfunct) (t->t_dcom, t);
155 register Char *vv = v[1];
158 if (parintr == SIG_IGN)
160 if (setintr && intty)
161 stderror(ERR_NAME | ERR_TERMINAL);
168 (void) sigblock(sigmask(SIGINT));
169 (void) signal(SIGINT, pintr);
172 (void) signal(SIGINT, SIG_DFL);
175 (void) sighold(SIGINT);
176 (void) sigset(SIGINT, pintr);
179 (void) sigset(SIGINT, SIG_DFL);
183 else if (eq((vv = strip(vv)), STRminus)) {
185 (void) signal(SIGINT, SIG_IGN);
187 (void) sigset(SIGINT, SIG_IGN);
189 gointr = Strsave(STRminus);
192 gointr = Strsave(vv);
194 (void) signal(SIGINT, pintr);
196 (void) sigset(SIGINT, pintr);
210 stderror(ERR_NAME | ERR_TERMINAL);
212 (void) signal(SIGHUP, SIG_IGN);
228 stderror(ERR_NAME | ERR_TERMINAL);
230 (void) signal(SIGHUP, SIG_DFL);
250 Char **fileptr, *ftest, *res;
252 if (*(ftest = *++v) != '-')
253 stderror(ERR_NAME | ERR_FILEINQ);
261 stderror(ERR_NAME | ERR_NOMATCH);
264 v = gargv = saveblk(v);
267 while (*(fileptr = v++) != '\0') {
268 xprintf("%S", res = filetest(ftest, &fileptr, 0));
284 plist(&shvhed, VAR_ALL);
293 register struct varent *vp;
300 plist(&aliases, VAR_ALL);
302 vp = adrof1(strip(p), &aliases);
304 blkpr(vp->vec), xputchar('\n');
307 if (eq(p, STRalias) || eq(p, STRunalias)) {
308 setname(short2str(p));
309 stderror(ERR_NAME | ERR_DANGER);
311 set1(strip(p), saveblk(v), &aliases, VAR_READWRITE);
348 #else /* !WINNT_NATIVE */
350 rechist(NULL, adrof(STRsavehist) != NULL);
351 (void) signal(SIGTERM, parterm);
352 (void) execl(_PATH_BIN_LOGIN, "login", short2str(v[1]), NULL);
353 (void) execl(_PATH_USRBIN_LOGIN, "login", short2str(v[1]), NULL);
356 #endif /* !WINNT_NATIVE */
368 if (chkstop == 0 && setintr)
370 (void) signal(SIGTERM, parterm);
373 * From Beto Appleton (beto@aixwiz.austin.ibm.com)
374 * Newgrp can take 2 arguments...
376 (void) execv(_PATH_BIN_NEWGRP, p);
377 (void) execv(_PATH_USRBIN_NEWGRP, p);
378 blkfree((Char **) p);
387 if (chkstop == 0 && setintr)
391 stderror(ERR_NOTLOGIN);
406 stderror(ERR_NAME | ERR_EMPTYIF);
407 if (eq(*vv, STRthen)) {
409 stderror(ERR_NAME | ERR_IMPRTHEN);
410 setname(short2str(STRthen));
412 * If expression was zero, then scan to else , otherwise just fall into
416 search(TC_IF, 0, NULL);
420 * Simple command attached to this if. Left shift the node in this tree,
421 * munging it so we can reexecute it.
424 lshift(kp->t_dcom, vv - kp->t_dcom);
431 * Reexecute a command, being careful not
432 * to redo i/o redirection, which is already set up.
436 register struct command *kp;
438 kp->t_dflg &= F_SAVE;
439 kp->t_dflg |= F_REPEAT;
441 * If tty is still ours to arbitrate, arbitrate it; otherwise dont even set
442 * pgrp's as the jobs would then have no way to get the tty (we can't give
443 * it to them, and our parent wouldn't know their pgrp, etc.
445 execute(kp, (tpgrp > 0 ? tpgrp : -1), NULL, NULL, TRUE);
456 search(TC_ELSE, 0, NULL);
468 gotolab(lp = globone(v[1], G_ERROR));
476 register struct whyle *wp;
478 * While we still can, locate any unknown ends of existing loops. This
479 * obscure code is the WORST result of the fact that we don't really parse.
482 for (wp = whyles; wp; wp = wp->w_next)
483 if (wp->w_end.type == TCSH_F_SEEK && wp->w_end.f_seek == 0) {
484 search(TC_BREAK, 0, NULL);
490 search(TC_GOTO, 0, lab);
492 * Eliminate loops which were exited.
503 register Char *cp, *lp;
507 if (!*v || *(*v++) != '(')
508 stderror(ERR_SYNTAX);
509 cp = **v == ')' ? STRNULL : *v++;
513 stderror(ERR_SYNTAX);
514 search(TC_SWITCH, 0, lp = globone(cp, G_ERROR));
529 stderror(ERR_NAME | ERR_NOTWHILE);
540 if (chkstop == 0 && (intty || intact) && evalvec == 0)
543 * Don't DEMAND parentheses here either.
547 set(STRstatus, putn(expr(&v)), VAR_READWRITE);
549 stderror(ERR_NAME | ERR_EXPRESSION);
555 /* Always close, why only on ttys? */
565 register Char *cp, *sp;
566 register struct whyle *nwp;
572 stderror(ERR_NAME | ERR_VARBEGIN);
573 while (*cp && alnum(*cp))
576 stderror(ERR_NAME | ERR_VARALNUM);
577 if ((cp - sp) > MAXVARLEN)
578 stderror(ERR_NAME | ERR_VARTOOLONG);
580 if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')')
581 stderror(ERR_NAME | ERR_NOPAREN);
587 stderror(ERR_NAME | ERR_NOMATCH);
590 v = gargv = saveblk(v);
593 nwp = (struct whyle *) xcalloc(1, sizeof *nwp);
594 nwp->w_fe = nwp->w_fe0 = v;
596 btell(&nwp->w_start);
597 nwp->w_fename = Strsave(cp);
598 nwp->w_next = whyles;
599 nwp->w_end.type = TCSH_F_SEEK;
602 * Pre-read the loop so as to be more comprehensible to a terminal user.
617 register bool again = whyles != 0 &&
618 SEEKEQ(&whyles->w_start, &lineloc) &&
619 whyles->w_fename == 0;
624 * Implement prereading here also, taking care not to evaluate the
625 * expression before the loop has been read up from a terminal.
628 status = !exp0(&v, 1);
632 stderror(ERR_NAME | ERR_EXPRESSION);
634 register struct whyle *nwp =
635 (struct whyle *) xcalloc(1, sizeof(*nwp));
637 nwp->w_start = lineloc;
638 nwp->w_end.type = TCSH_F_SEEK;
639 nwp->w_end.f_seek = 0;
640 nwp->w_next = whyles;
653 /* We ain't gonna loop no more, no more! */
660 whyles->w_end.type = TCSH_I_SEEK;
663 (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
665 (void) sigrelse (SIGINT);
667 search(TC_BREAK, 0, NULL); /* read the expression in */
670 (void) sigblock(sigmask(SIGINT));
672 (void) sighold(SIGINT);
674 btell(&whyles->w_end);
686 stderror(ERR_NAME | ERR_NOTWHILE);
687 btell(&whyles->w_end);
700 stderror(ERR_NAME | ERR_NOTWHILE);
707 /* Repeating a while is simple */
708 if (whyles->w_fename == 0) {
709 bseek(&whyles->w_start);
713 * The foreach variable list actually has a spurious word ")" at the end of
714 * the w_fe list. Thus we are at the of the list if one word beyond this
717 if (!whyles->w_fe[1]) {
721 set(whyles->w_fename, quote(Strsave(*whyles->w_fe++)), VAR_READWRITE);
722 bseek(&whyles->w_start);
733 register sigmask_t omask = 0;
739 } while (v[0] != NULL && Strcmp(v[0], STRrepeat) == 0);
743 omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT);
745 (void) sighold(SIGINT);
750 (void) sigsetmask(omask);
752 (void) sigrelse (SIGINT);
760 (void) sigsetmask(omask);
762 (void) sigrelse (SIGINT);
774 search(TC_BRKSW, 0, NULL);
781 struct srch *sp, *sp1, *sp2;
785 * Ignore keywords inside heredocs
791 * Binary search Sp1 is the beginning of the current search range. Sp2 is
794 for (sp1 = srchn, sp2 = srchn + nsrchn; sp1 < sp2;) {
795 sp = sp1 + ((sp2 - sp1) >> 1);
796 if ((i = *cp - *sp->s_name) == 0 &&
797 (i = Strcmp(cp, str2short(sp->s_name))) == 0)
811 register struct srch *sp, *sp2;
813 for (sp = srchn, sp2 = srchn + nsrchn; sp < sp2; sp++)
814 if (sp->s_value == n)
824 search(type, level, goal)
829 Char wordbuf[BUFSIZE];
830 register Char *aword = wordbuf;
835 if (type == TC_GOTO) {
837 a.type = TCSH_F_SEEK;
842 if (intty && fseekp == feobp && aret == TCSH_F_SEEK)
843 printprompt(1, isrchx(type == TC_BREAK ? zlast : type));
844 /* xprintf("? "), flush(); */
846 (void) getword(aword);
847 switch (srchx(aword)) {
850 if (level == 0 && type == TC_IF)
855 while (getword(aword))
857 if ((type == TC_IF || type == TC_ELSE) &&
863 if (type == TC_IF || type == TC_ELSE)
869 if (type == TC_BREAK)
874 if (type == TC_BREAK)
879 if (type == TC_SWITCH || type == TC_BRKSW)
884 if (type == TC_SWITCH || type == TC_BRKSW)
889 if (type == TC_GOTO && getword(aword) && eq(aword, goal))
894 if (type != TC_GOTO && (type != TC_SWITCH || level != 0))
896 if (lastchr(aword) != ':')
898 aword[Strlen(aword) - 1] = 0;
899 if ((type == TC_GOTO && eq(aword, goal)) ||
900 (type == TC_SWITCH && eq(aword, STRdefault)))
905 if (type != TC_SWITCH || level != 0)
907 (void) getword(aword);
908 if (lastchr(aword) == ':')
909 aword[Strlen(aword) - 1] = 0;
910 cp = strip(Dfix1(aword));
911 if (Gmatch(goal, cp))
917 if (type == TC_SWITCH && level == 0)
921 (void) getword(NULL);
922 } while (level >= 0);
929 int found = 0, first;
935 while (c == ' ' || c == '\t')
940 while (c >= 0 && c != '\n');
953 if (c == '\\' && (c = readc(1)) == '\n')
955 if (c == '\'' || c == '"') {
967 if (!first && !d && c == '(') {
977 } while ((d || (c != ' ' && c != '\t')) && c != '\n');
990 stderror(ERR_NAME | ERR_NOTFOUND, "then/endif");
994 stderror(ERR_NAME | ERR_NOTFOUND, "endif");
999 stderror(ERR_NAME | ERR_NOTFOUND, "endsw");
1003 stderror(ERR_NAME | ERR_NOTFOUND, "end");
1007 setname(short2str(Sgoal));
1008 stderror(ERR_NAME | ERR_NOTFOUND, "label");
1021 if (whyles->w_end.type == TCSH_F_SEEK && whyles->w_end.f_seek == 0) {
1022 search(TC_BREAK, 0, NULL);
1023 btell(&whyles->w_end);
1024 whyles->w_end.f_seek--;
1027 bseek(&whyles->w_end);
1038 nwp = NULL; /* sun lint is dumb! */
1042 static char foo[] = "IAFE";
1048 xprintf("o->type %c o->a_seek %d o->f_seek %d\n",
1049 foo[o.type + 1], o.a_seek, o.f_seek);
1052 for (; whyles; whyles = nwp) {
1053 register struct whyle *wp = whyles;
1057 xprintf("start->type %c start->a_seek %d start->f_seek %d\n",
1058 foo[wp->w_start.type+1],
1059 wp->w_start.a_seek, wp->w_start.f_seek);
1060 xprintf("end->type %c end->a_seek %d end->f_seek %d\n",
1061 foo[wp->w_end.type + 1], wp->w_end.a_seek, wp->w_end.f_seek);
1065 * XXX: We free loops that have different seek types.
1067 if (wp->w_end.type != TCSH_I_SEEK && wp->w_start.type == wp->w_end.type &&
1068 wp->w_start.type == o.type) {
1069 if (wp->w_end.type == TCSH_F_SEEK) {
1070 if (o.f_seek >= wp->w_start.f_seek &&
1071 (wp->w_end.f_seek == 0 || o.f_seek < wp->w_end.f_seek))
1075 if (o.a_seek >= wp->w_start.a_seek &&
1076 (wp->w_end.a_seek == 0 || o.a_seek < wp->w_end.a_seek))
1084 xfree((ptr_t) wp->w_fename);
1118 int echo_style = ECHO_STYLE;
1119 #else /* !ECHO_STYLE */
1121 int echo_style = SYSV_ECHO;
1122 # else /* SYSVREL == 0 */
1123 int echo_style = BSD_ECHO;
1124 # endif /* SYSVREL */
1125 #endif /* ECHO_STYLE */
1128 if ((vp = adrof(STRecho_style)) != NULL && vp->vec != NULL &&
1129 vp->vec[0] != NULL) {
1130 if (Strcmp(vp->vec[0], STRbsd) == 0)
1131 echo_style = BSD_ECHO;
1132 else if (Strcmp(vp->vec[0], STRsysv) == 0)
1133 echo_style = SYSV_ECHO;
1134 else if (Strcmp(vp->vec[0], STRboth) == 0)
1135 echo_style = BOTH_ECHO;
1136 else if (Strcmp(vp->vec[0], STRnone) == 0)
1137 echo_style = NONE_ECHO;
1142 (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
1143 #else /* !BSDSIGS */
1144 (void) sigrelse (SIGINT);
1145 #endif /* BSDSIGS */
1149 gflag = 0, tglob(v);
1153 stderror(ERR_NAME | ERR_NOMATCH);
1156 v = gargv = saveblk(v);
1160 if ((echo_style & BSD_ECHO) != 0 && sep == ' ' && *v && eq(*v, STRmn))
1163 while ((cp = *v++) != 0) {
1166 while ((c = *cp++) != 0) {
1167 if ((echo_style & SYSV_ECHO) != 0 && c == '\\') {
1168 switch (c = *cp++) {
1179 #if 0 /* Windows does not understand \e */
1205 if (*cp >= '0' && *cp < '8')
1206 c = c * 8 + *cp++ - '0';
1207 if (*cp >= '0' && *cp < '8')
1208 c = c * 8 + *cp++ - '0';
1209 if (*cp >= '0' && *cp < '8')
1210 c = c * 8 + *cp++ - '0';
1217 xputchar('\\' | QUOTE);
1221 xputchar(c | QUOTE);
1225 xputchar(sep | QUOTE);
1228 if (sep && nonl == 0)
1234 (void) sigblock(sigmask(SIGINT));
1235 #else /* !BSDSIGS */
1236 (void) sighold(SIGINT);
1237 #endif /* BSDSIGS */
1239 blkfree(gargv), gargv = 0;
1242 /* check whether an environment variable should invoke 'set_locale()' */
1247 static Char *locale_vars[] = {
1248 STRLANG, STRLC_CTYPE, STRLC_NUMERIC, STRLC_TIME,
1249 STRLC_COLLATE, STRLC_MESSAGES, STRLC_MONETARY, 0
1253 for (v = locale_vars; *v; ++v)
1266 extern bool output_raw;
1267 extern bool xlate_cr;
1272 (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
1273 #else /* !BSDSIGS */
1274 (void) sigrelse (SIGINT);
1275 #endif /* BSDSIGS */
1282 for (ep = STR_environ; *ep; ep++)
1283 xprintf("%S\n", *ep);
1286 else if ((e = tgetenv(*v)) != NULL) {
1292 set(STRstatus, Strsave(STR1), VAR_READWRITE);
1295 /* from "Karl Berry." <karl%mote.umb.edu@relay.cs.net> -- for NeXT things
1296 (and anything else with a modern compiler) */
1316 stderror(ERR_NAME | ERR_VARBEGIN);
1318 for (; alnum(*lp); lp++)
1322 stderror(ERR_NAME | ERR_SYNTAX);
1324 if ((lp = *v++) == 0)
1327 tsetenv(vp, lp = globone(lp, G_APPEND));
1328 if (eq(vp, STRKPATH)) {
1336 if (eq(vp, STRSYSTYPE)) {
1343 /* dspkanji/dspmbyte autosetting */
1344 /* PATCH IDEA FROM Issei.Suzuki VERY THANKS */
1345 #if defined(DSPMBYTE)
1346 if(eq(vp, STRLANG) && !adrof(CHECK_MBYTEVAR)) {
1347 autoset_dspmbyte(lp);
1351 if (islocale_var(vp)) {
1355 # ifdef SETLOCALEBUG
1357 # endif /* SETLOCALEBUG */
1358 (void) setlocale(LC_ALL, "");
1360 (void) setlocale(LC_COLLATE, "");
1362 # ifdef NLS_CATALOGS
1364 (void) setlocale(LC_MESSAGES, "");
1365 # endif /* LC_MESSAGES */
1366 (void) catclose(catd);
1368 # endif /* NLS_CATALOGS */
1370 (void) setlocale(LC_CTYPE, ""); /* for iscntrl */
1371 # endif /* LC_CTYPE */
1372 # ifdef SETLOCALEBUG
1374 # endif /* SETLOCALEBUG */
1377 # endif /* STRCOLLBUG */
1378 tw_cmd_free(); /* since the collation sequence has changed */
1379 for (k = 0200; k <= 0377 && !Isprint(k); k++)
1381 AsciiOnly = k > 0377;
1385 NLSMapsAreInited = 0;
1387 if (MapsAreInited && !NLSMapsAreInited)
1394 if (eq(vp, STRNLSPATH)) {
1395 (void) catclose(catd);
1400 if (eq(vp, STRNOREBIND)) {
1403 NLSMapsAreInited = 0;
1409 if (eq(vp, STRtcshlang)) {
1414 #endif /* WINNT_NATIVE */
1415 if (eq(vp, STRKTERM)) {
1417 set(STRterm, quote(lp), VAR_READWRITE); /* lp memory used here */
1419 if (noediting && strcmp(t, "unknown") != 0 && strcmp(t,"dumb") != 0) {
1422 set(STRedit, Strsave(STRNULL), VAR_READWRITE);
1429 if (eq(vp, STRKHOME)) {
1431 * convert to canonical pathname (possibly resolving symlinks)
1433 lp = dcanon(lp, lp);
1434 set(STRhome, quote(lp), VAR_READWRITE); /* cp memory used here */
1436 /* fix directory stack for new tilde home */
1441 if (eq(vp, STRKSHLVL)) {
1442 /* lp memory used here */
1443 set(STRshlvl, quote(lp), VAR_READWRITE);
1447 if (eq(vp, STRKUSER)) {
1448 set(STRuser, quote(lp), VAR_READWRITE); /* lp memory used here */
1452 if (eq(vp, STRKGROUP)) {
1453 set(STRgroup, quote(lp), VAR_READWRITE); /* lp memory used here */
1458 if (eq(vp, STRLS_COLORS)) {
1462 #endif /* COLOR_LS_F */
1466 * Load/Update $LINES $COLUMNS
1468 if ((eq(lp, STRNULL) && (eq(vp, STRLINES) || eq(vp, STRCOLUMNS))) ||
1469 eq(vp, STRTERMCAP)) {
1471 check_window_size(1);
1476 * Change the size to the one directed by $LINES and $COLUMNS
1478 if (eq(vp, STRLINES) || eq(vp, STRCOLUMNS)) {
1486 #endif /* SIG_WINDOW */
1498 static Char *name = NULL;
1502 xfree((ptr_t) name);
1504 * Find the longest environment variable
1506 for (maxi = 0, ep = STR_environ; *ep; ep++) {
1507 for (i = 0, p = *ep; *p && *p != '='; p++, i++)
1513 name = (Char *) xmalloc((size_t) ((maxi + 1) * sizeof(Char)));
1516 for (maxi = 1; maxi;)
1517 for (maxi = 0, ep = STR_environ; *ep; ep++) {
1518 for (n = name, p = *ep; *p && *p != '='; *n++ = *p++)
1521 if (!Gmatch(name, *v))
1525 /* Unset the name. This wasn't being done until
1526 * later but most of the stuff following won't
1527 * work (particularly the setlocale() and getenv()
1528 * stuff) as intended until the name is actually
1533 if (eq(name, STRNOREBIND)) {
1536 NLSMapsAreInited = 0;
1540 else if (eq(name, STRSYSTYPE))
1543 else if (islocale_var(name)) {
1547 # ifdef SETLOCALEBUG
1549 # endif /* SETLOCALEBUG */
1550 (void) setlocale(LC_ALL, "");
1552 (void) setlocale(LC_COLLATE, "");
1554 # ifdef NLS_CATALOGS
1556 (void) setlocale(LC_MESSAGES, "");
1557 # endif /* LC_MESSAGES */
1558 (void) catclose(catd);
1560 # endif /* NLS_CATALOGS */
1562 (void) setlocale(LC_CTYPE, ""); /* for iscntrl */
1563 # endif /* LC_CTYPE */
1564 # ifdef SETLOCALEBUG
1566 # endif /* SETLOCALEBUG */
1569 # endif /* STRCOLLBUG */
1570 tw_cmd_free();/* since the collation sequence has changed */
1571 for (k = 0200; k <= 0377 && !Isprint(k); k++)
1573 AsciiOnly = k > 0377;
1575 AsciiOnly = getenv("LANG") == NULL &&
1576 getenv("LC_CTYPE") == NULL;
1578 NLSMapsAreInited = 0;
1580 if (MapsAreInited && !NLSMapsAreInited)
1585 else if (eq(name,(STRtcshlang))) {
1589 #endif /* WINNT_NATIVE */
1591 else if (eq(name, STRLS_COLORS))
1593 #endif /* COLOR_LS_F */
1595 else if (eq(name, STRNLSPATH)) {
1596 (void) catclose(catd);
1601 * start again cause the environment changes
1605 xfree((ptr_t) name); name = NULL;
1612 #ifdef SETENV_IN_LIB
1614 * XXX: This does not work right, since tcsh cannot track changes to
1615 * the environment this way. (the builtin setenv without arguments does
1616 * not print the right stuff neither does unsetenv). This was for Mach,
1617 * it is not needed anymore.
1620 char nameBuf[BUFSIZE];
1621 char *cname = short2str(name);
1625 (void) strcpy(nameBuf, cname);
1626 setenv(nameBuf, short2str(val), 1);
1627 #else /* !SETENV_IN_LIB */
1628 register Char **ep = STR_environ;
1629 register Char *cp, *dp;
1634 nt_set_env(name,val);
1635 #endif /* WINNT_NATIVE */
1638 for (cp = name, dp = *ep; *cp && Tolower(*cp & TRIM) == Tolower(*dp);
1641 for (cp = name, dp = *ep; *cp && (*cp & TRIM) == *dp; cp++, dp++)
1642 #endif /* WINNT_NATIVE */
1644 if (*cp != 0 || *dp != '=')
1646 cp = Strspl(STRequal, val);
1647 xfree((ptr_t) * ep);
1648 *ep = strip(Strspl(name, cp));
1650 blkfree((Char **) environ);
1651 environ = short2blk(STR_environ);
1654 cp = Strspl(name, STRequal);
1655 blk[0] = strip(Strspl(cp, val));
1658 STR_environ = blkspl(STR_environ, blk);
1659 blkfree((Char **) environ);
1660 environ = short2blk(STR_environ);
1662 #endif /* SETENV_IN_LIB */
1669 register Char **ep = STR_environ;
1670 register Char *cp, *dp;
1674 nt_set_env(name,NULL);
1675 #endif /*WINNT_NATIVE */
1677 for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++)
1679 if (*cp != 0 || *dp != '=')
1683 STR_environ = blkspl(STR_environ, ep + 1);
1684 blkfree((Char **) environ);
1685 environ = short2blk(STR_environ);
1699 register Char *cp = v[1];
1710 while (Isdigit(*cp) && *cp != '8' && *cp != '9')
1711 i = i * 8 + *cp++ - '0';
1712 if (*cp || i < 0 || i > 0777)
1713 stderror(ERR_NAME | ERR_MASK);
1719 typedef long RLIM_TYPE;
1720 # ifndef RLIM_INFINITY
1721 # if !defined(_MINIX) && !defined(__clipper__) && !defined(_CRAY)
1722 extern RLIM_TYPE ulimit();
1723 # endif /* ! _MINIX && !__clipper__ */
1724 # define RLIM_INFINITY 0x003fffff
1725 # define RLIMIT_FSIZE 1
1726 # endif /* RLIM_INFINITY */
1728 # define toset(a) (((a) == 3) ? 1004 : (a) + 1)
1729 # define RLIMIT_DATA 3
1730 # define RLIMIT_STACK 1005
1732 # define toset(a) ((a) + 1)
1734 # else /* BSDLIMIT */
1735 # if (defined(BSD4_4) || defined(__linux__)) && !defined(__386BSD__)
1736 typedef rlim_t RLIM_TYPE;
1738 # if defined(SOLARIS2) || (defined(sgi) && SYSVREL > 3)
1739 typedef rlim_t RLIM_TYPE;
1742 typedef long long RLIM_TYPE;
1744 typedef unsigned long RLIM_TYPE;
1746 # endif /* SOLARIS2 || (sgi && SYSVREL > 3) */
1747 # endif /* BSD4_4 && !__386BSD__ */
1748 # endif /* BSDLIMIT */
1750 # if (HPUXVERSION > 700) && defined(BSDLIMIT)
1751 /* Yes hpux8.0 has limits but <sys/resource.h> does not make them public */
1752 /* Yes, we could have defined _KERNEL, and -I/etc/conf/h, but is that better? */
1754 # define RLIMIT_CPU 0
1755 # define RLIMIT_FSIZE 1
1756 # define RLIMIT_DATA 2
1757 # define RLIMIT_STACK 3
1758 # define RLIMIT_CORE 4
1759 # define RLIMIT_RSS 5
1760 # define RLIMIT_NOFILE 6
1761 # endif /* RLIMIT_CPU */
1762 # ifndef RLIM_INFINITY
1763 # define RLIM_INFINITY 0x7fffffff
1764 # endif /* RLIM_INFINITY */
1766 * old versions of HP/UX counted limits in 512 bytes
1769 # define FILESIZE512
1770 # endif /* SIGRTMIN */
1771 # endif /* (HPUXVERSION > 700) && BSDLIMIT */
1773 # if SYSVREL > 3 && defined(BSDLIMIT) && !defined(_SX)
1774 /* In order to use rusage, we included "/usr/ucbinclude/sys/resource.h" in */
1775 /* sh.h. However, some SVR4 limits are defined in <sys/resource.h>. Rather */
1776 /* than include both and get warnings, we define the extra SVR4 limits here. */
1777 /* XXX: I don't understand if RLIMIT_AS is defined, why don't we define */
1778 /* RLIMIT_VMEM based on it? */
1779 # ifndef RLIMIT_VMEM
1780 # define RLIMIT_VMEM 6
1783 # define RLIMIT_AS RLIMIT_VMEM
1785 # endif /* SYSVREL > 3 && BSDLIMIT */
1787 # if defined(__linux__) && defined(RLIMIT_AS) && !defined(RLIMIT_VMEM)
1788 # define RLIMIT_VMEM RLIMIT_AS
1791 struct limits limits[] =
1794 { RLIMIT_CPU, "cputime", 1, "seconds" },
1795 # endif /* RLIMIT_CPU */
1797 # ifdef RLIMIT_FSIZE
1799 { RLIMIT_FSIZE, "filesize", 1024, "kbytes" },
1801 { RLIMIT_FSIZE, "filesize", 512, "blocks" },
1803 # endif /* RLIMIT_FSIZE */
1806 { RLIMIT_DATA, "datasize", 1024, "kbytes" },
1807 # endif /* RLIMIT_DATA */
1809 # ifdef RLIMIT_STACK
1811 { RLIMIT_STACK, "stacksize", 1024, "kbytes" },
1813 { RLIMIT_STACK, "stacksize", 1024 * 1024, "kbytes"},
1815 # endif /* RLIMIT_STACK */
1818 { RLIMIT_CORE, "coredumpsize", 1024, "kbytes" },
1819 # endif /* RLIMIT_CORE */
1822 { RLIMIT_RSS, "memoryuse", 1024, "kbytes" },
1823 # endif /* RLIMIT_RSS */
1826 { RLIMIT_UMEM, "memoryuse", 1024, "kbytes" },
1827 # endif /* RLIMIT_UMEM */
1830 { RLIMIT_VMEM, "vmemoryuse", 1024, "kbytes" },
1831 # endif /* RLIMIT_VMEM */
1833 # ifdef RLIMIT_NOFILE
1834 { RLIMIT_NOFILE, "descriptors", 1, "" },
1835 # endif /* RLIMIT_NOFILE */
1837 # ifdef RLIMIT_CONCUR
1838 { RLIMIT_CONCUR, "concurrency", 1, "thread(s)" },
1839 # endif /* RLIMIT_CONCUR */
1841 # ifdef RLIMIT_MEMLOCK
1842 { RLIMIT_MEMLOCK, "memorylocked", 1024, "kbytes" },
1843 # endif /* RLIMIT_MEMLOCK */
1845 # ifdef RLIMIT_NPROC
1846 { RLIMIT_NPROC, "maxproc", 1, "" },
1847 # endif /* RLIMIT_NPROC */
1849 # if defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE)
1850 { RLIMIT_OFILE, "openfiles", 1, "" },
1851 # endif /* RLIMIT_OFILE && !defined(RLIMIT_NOFILE) */
1853 # ifdef RLIMIT_SBSIZE
1854 { RLIMIT_SBSIZE, "sbsize", 1, "" },
1855 # endif /* RLIMIT_SBSIZE */
1857 #ifdef RLIMIT_POSIXLOCKS
1858 { RLIMIT_POSIXLOCKS, "posixlocks", 1, "" },
1859 #endif /* RLIMIT_POSIXLOCKS */
1861 { -1, NULL, 0, NULL }
1864 static struct limits *findlim __P((Char *));
1865 static RLIM_TYPE getval __P((struct limits *, Char **));
1866 static void limtail __P((Char *, char*));
1867 static void plim __P((struct limits *, int));
1868 static int setlim __P((struct limits *, int, RLIM_TYPE));
1872 restrict_limit(value)
1876 * is f too large to cope with? return the maximum or minimum int
1878 if (value > (double) INT_MAX)
1879 return (RLIM_TYPE) INT_MAX;
1880 else if (value < (double) INT_MIN)
1881 return (RLIM_TYPE) INT_MIN;
1883 return (RLIM_TYPE) value;
1886 # define restrict_limit(x) ((RLIM_TYPE) (x))
1890 static struct limits *
1894 register struct limits *lp, *res;
1896 res = (struct limits *) NULL;
1897 for (lp = limits; lp->limconst >= 0; lp++)
1898 if (prefix(cp, str2short(lp->limname))) {
1900 stderror(ERR_NAME | ERR_AMBIG);
1905 stderror(ERR_NAME | ERR_LIMIT);
1916 register struct limits *lp;
1917 register RLIM_TYPE limit;
1922 if (*v && eq(*v, STRmh)) {
1927 for (lp = limits; lp->limconst >= 0; lp++)
1936 limit = getval(lp, v + 1);
1937 if (setlim(lp, hard, limit) < 0)
1938 stderror(ERR_SILENT);
1943 register struct limits *lp;
1947 #ifndef atof /* This can be a macro on linux */
1948 extern double atof __P((const char *));
1952 f = atof(short2str(cp));
1956 * is f too large to cope with. limit f to minint, maxint - X-6768 by
1959 if ((f < (double) INT_MIN) || (f > (double) INT_MAX)) {
1960 stderror(ERR_NAME | ERR_TOOLARGE);
1962 # endif /* convex */
1964 while (Isdigit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E')
1968 return restrict_limit((f * lp->limdiv) + 0.5);
1974 if (lp->limconst != RLIMIT_CPU)
1976 return f == 0.0 ? (RLIM_TYPE) 0 : restrict_limit((f * 60.0 + atof(short2str(cp + 1))));
1978 if (lp->limconst != RLIMIT_CPU)
1980 limtail(cp, "hours");
1984 if (lp->limconst == RLIMIT_CPU) {
1985 limtail(cp, "minutes");
1990 limtail(cp, "megabytes");
1991 f *= 1024.0 * 1024.0;
1994 if (lp->limconst != RLIMIT_CPU)
1996 limtail(cp, "seconds");
1998 # endif /* RLIMIT_CPU */
2001 if (lp->limconst == RLIMIT_CPU)
2003 # endif /* RLIMIT_CPU */
2005 limtail(cp, "megabytes");
2006 f *= 1024.0 * 1024.0;
2010 if (lp->limconst == RLIMIT_CPU)
2012 # endif /* RLIMIT_CPU */
2013 limtail(cp, "kbytes");
2018 if (lp->limconst == RLIMIT_CPU)
2020 # endif /* RLIMIT_CPU */
2021 limtail(cp, "blocks");
2025 limtail(cp, "unlimited");
2026 return ((RLIM_TYPE) RLIM_INFINITY);
2030 # endif /* RLIMIT_CPU */
2031 stderror(ERR_NAME | ERR_SCALEF);
2034 return f == 0.0 ? (RLIM_TYPE) 0 : restrict_limit((f + 0.5));
2037 if (f > (float) RLIM_INFINITY)
2038 return ((RLIM_TYPE) RLIM_INFINITY);
2040 return ((RLIM_TYPE) f);
2041 # endif /* convex */
2052 while (*cp && *cp == *str)
2055 stderror(ERR_BADSCALE, sp);
2062 register struct limits *lp;
2067 # endif /* BSDLIMIT */
2069 int div = lp->limdiv;
2071 xprintf("%s \t", lp->limname);
2074 limit = ulimit(lp->limconst, 0);
2076 if (lp->limconst == RLIMIT_DATA)
2077 limit -= 0x20000000;
2079 # else /* BSDLIMIT */
2080 (void) getrlimit(lp->limconst, &rlim);
2081 limit = hard ? rlim.rlim_max : rlim.rlim_cur;
2082 # endif /* BSDLIMIT */
2084 # if !defined(BSDLIMIT) || defined(FILESIZE512)
2086 * Christos: filesize comes in 512 blocks. we divide by 2 to get 1024
2087 * blocks. Note we cannot pre-multiply cause we might overflow (A/UX)
2089 if (lp->limconst == RLIMIT_FSIZE) {
2090 if (limit >= (RLIM_INFINITY / 512))
2091 limit = RLIM_INFINITY;
2093 div = (div == 1024 ? 2 : 1);
2095 # endif /* !BSDLIMIT || FILESIZE512 */
2097 if (limit == RLIM_INFINITY)
2098 xprintf("unlimited");
2101 if (lp->limconst == RLIMIT_CPU)
2102 psecs((long) limit);
2104 # endif /* RLIMIT_CPU */
2105 xprintf("%ld %s", (long) (limit / div), lp->limscale);
2115 register struct limits *lp;
2121 while (*++v && **v == '-') {
2132 stderror(ERR_ULIMUS);
2138 for (lp = limits; lp->limconst >= 0; lp++)
2139 if (setlim(lp, hard, (RLIM_TYPE) RLIM_INFINITY) < 0)
2142 stderror(ERR_SILENT);
2147 if (setlim(lp, hard, (RLIM_TYPE) RLIM_INFINITY) < 0 && !force)
2148 stderror(ERR_SILENT);
2153 setlim(lp, hard, limit)
2154 register struct limits *lp;
2161 (void) getrlimit(lp->limconst, &rlim);
2164 /* Even though hpux has setrlimit(), it expects fsize in 512 byte blocks */
2165 if (limit != RLIM_INFINITY && lp->limconst == RLIMIT_FSIZE)
2167 # endif /* FILESIZE512 */
2169 rlim.rlim_max = limit;
2170 else if (limit == RLIM_INFINITY && euid != 0)
2171 rlim.rlim_cur = rlim.rlim_max;
2173 rlim.rlim_cur = limit;
2175 if (rlim.rlim_cur > rlim.rlim_max)
2176 rlim.rlim_max = rlim.rlim_cur;
2178 if (setrlimit(lp->limconst, &rlim) < 0) {
2179 # else /* BSDLIMIT */
2180 if (limit != RLIM_INFINITY && lp->limconst == RLIMIT_FSIZE)
2183 if (lp->limconst == RLIMIT_DATA)
2184 limit += 0x20000000;
2186 if (ulimit(toset(lp->limconst), limit) < 0) {
2187 # endif /* BSDLIMIT */
2188 xprintf(CGETS(15, 1, "%s: %s: Can't %s%s limit (%s)\n"), bname,
2189 lp->limname, limit == RLIM_INFINITY ? CGETS(15, 2, "remove") :
2190 CGETS(15, 3, "set"), hard ? CGETS(14, 4, " hard") : "",
2197 #endif /* !HAVENOLIMIT */
2209 #endif /* BSDJOBS */
2215 stderror(ERR_SUSPLOG);
2219 old = signal(SIGTSTP, SIG_DFL);
2220 (void) kill(0, SIGTSTP);
2221 /* the shell stops here */
2222 (void) signal(SIGTSTP, old);
2223 #else /* !BSDJOBS */
2224 stderror(ERR_JOBCONTROL);
2225 #endif /* BSDJOBS */
2230 ctpgrp = tcgetpgrp(FSHTTY);
2231 if (ctpgrp != opgrp) {
2232 old = signal(SIGTTIN, SIG_DFL);
2233 (void) kill(0, SIGTTIN);
2234 (void) signal(SIGTTIN, old);
2237 (void) setpgid(0, shpgrp);
2238 (void) tcsetpgrp(FSHTTY, shpgrp);
2240 #endif /* BSDJOBS */
2241 (void) setdisc(FSHTTY);
2244 /* This is the dreaded EVAL built-in.
2245 * If you don't fiddle with file descriptors, and reset didfds,
2246 * this command will either ignore redirection inside or outside
2247 * its arguments, e.g. eval "date >x" vs. eval "date" >x
2248 * The stuff here seems to work, but I did it by trial and error rather
2249 * than really knowing what was going on. If tpgrp is zero, we are
2250 * probably a background eval, e.g. "eval date &", and we want to
2251 * make sure that any processes we start stay in our pgrp.
2252 * This is also the case for "time eval date" -- stay in same pgrp.
2253 * Otherwise, under stty tostop, processes will stop in the wrong
2254 * pgrp, with no way for the shell to get them going again. -IAN!
2257 static Char **gv = NULL, **gav = NULL;
2268 #ifndef CLOSE_ON_EXEC
2270 #endif /* CLOSE_ON_EXEC */
2274 int saveIN, saveOUT, saveDIAG;
2275 int oSHIN, oSHOUT, oSHDIAG;
2281 #ifndef CLOSE_ON_EXEC
2283 #endif /* CLOSE_ON_EXEC */
2294 gflag = 0, tglob(gav);
2296 gv = gav = globall(gav);
2299 stderror(ERR_NOMATCH);
2308 saveIN = dcopy(SHIN, -1);
2309 saveOUT = dcopy(SHOUT, -1);
2310 saveDIAG = dcopy(SHDIAG, -1);
2314 /* PWP: setjmp/longjmp bugfix for optimizing compilers */
2316 my_reenter = 1; /* assume non-zero return val */
2317 if (setexit() == 0) {
2318 my_reenter = 0; /* Oh well, we were wrong */
2320 if ((my_reenter = setexit()) == 0) {
2324 SHIN = dcopy(0, -1);
2325 SHOUT = dcopy(1, -1);
2326 SHDIAG = dcopy(2, -1);
2327 #ifndef CLOSE_ON_EXEC
2329 #endif /* CLOSE_ON_EXEC */
2337 #ifndef CLOSE_ON_EXEC
2339 #endif /* CLOSE_ON_EXEC */
2342 (void) close(SHOUT);
2343 (void) close(SHDIAG);
2344 SHIN = dmove(saveIN, oSHIN);
2345 SHOUT = dmove(saveOUT, oSHOUT);
2346 SHDIAG = dmove(saveDIAG, oSHDIAG);
2354 stderror(ERR_SILENT);
2357 /*************************************************************************/
2358 /* print list of builtin commands */
2366 /* would use print_by_column() in tw.parse.c but that assumes
2367 * we have an array of Char * to pass.. (sg)
2369 extern int Tty_raw_mode;
2370 extern int TermH; /* from the editor routines */
2371 extern int lbuffed; /* from sh.print.c */
2373 register struct biltins *b;
2374 register int row, col, columns, rows;
2375 unsigned int w, maxwidth;
2379 lbuffed = 0; /* turn off line buffering */
2381 /* find widest string */
2382 for (maxwidth = 0, b = bfunc; b < &bfunc[nbfunc]; ++b)
2383 maxwidth = max(maxwidth, strlen(b->bname));
2384 ++maxwidth; /* for space */
2386 columns = (TermH + 1) / maxwidth; /* PWP: terminal size change */
2389 rows = (nbfunc + (columns - 1)) / columns;
2391 for (b = bfunc, row = 0; row < rows; row++) {
2392 for (col = 0; col < columns; col++) {
2393 if (b < &bfunc[nbfunc]) {
2394 w = strlen(b->bname);
2395 xprintf("%s", b->bname);
2396 if (col < (columns - 1)) /* Not last column? */
2397 for (; w < maxwidth; w++)
2402 if (row < (rows - 1)) {
2409 nt_print_builtins(maxwidth);
2414 #endif /* WINNT_NATIVE */
2416 lbuffed = 1; /* turn back on line buffering */
2424 char catalog[ 256 ] = { 't', 'c', 's', 'h', '\0' };
2426 if (adrof(STRcatalog) != NULL)
2427 xsnprintf((char *)catalog, sizeof(catalog), "tcsh.%s",
2428 short2str(varval(STRcatalog)));
2429 catd = catopen(catalog, MCLoadBySet);
2430 #endif /* NLS_CATALOGS */
2433 #endif /* WINNT_NATIVE */
2434 errinit(); /* init the errorlist in correct locale */
2435 mesginit(); /* init the messages for signals */
2436 dateinit(); /* init the messages for dates */
2437 editinit(); /* init the editor messages */
2438 terminit(); /* init the termcap messages */