aboutsummaryrefslogtreecommitdiff
path: root/shell/msh.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-02-01 01:43:54 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-02-01 01:43:54 +0000
commit1e3b06868932b81220039bdf148bf25d7f1603fd (patch)
tree16bd6b94c3f25f347f5debabbecd281c32c88a91 /shell/msh.c
parent6b50f73171a30a3837c09b73af911a76e7d3b429 (diff)
downloadbusybox-w32-1e3b06868932b81220039bdf148bf25d7f1603fd.tar.gz
busybox-w32-1e3b06868932b81220039bdf148bf25d7f1603fd.tar.bz2
busybox-w32-1e3b06868932b81220039bdf148bf25d7f1603fd.zip
msh: cleaning up for -Wwrite-strings part #4
Diffstat (limited to 'shell/msh.c')
-rw-r--r--shell/msh.c557
1 files changed, 287 insertions, 270 deletions
diff --git a/shell/msh.c b/shell/msh.c
index 754a6fc25..496435189 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -105,6 +105,27 @@ typedef void xint; /* base type of jmp_buf, for not broken compilers */
105#define NOWORDS ((char **)NULL) 105#define NOWORDS ((char **)NULL)
106#define NOPIPE ((int *)NULL) 106#define NOPIPE ((int *)NULL)
107 107
108
109/*
110 * redirection
111 */
112struct ioword {
113 short io_unit; /* unit affected */
114 short io_flag; /* action (below) */
115 char *io_name; /* file name */
116};
117
118#define IOREAD 1 /* < */
119#define IOHERE 2 /* << (here file) */
120#define IOWRITE 4 /* > */
121#define IOCAT 8 /* >> */
122#define IOXHERE 16 /* ${}, ` in << */
123#define IODUP 32 /* >&digit */
124#define IOCLOSE 64 /* >&- */
125
126#define IODEFAULT (-1) /* token for default IO unit */
127
128
108/* 129/*
109 * Description of a command or an operation on commands. 130 * Description of a command or an operation on commands.
110 * Might eventually use a union. 131 * Might eventually use a union.
@@ -183,7 +204,6 @@ static const char *const T_CMD_NAMES[] = {
183 204
184/* PROTOTYPES */ 205/* PROTOTYPES */
185static int newfile(char *s); 206static int newfile(char *s);
186static char *cclass(char *p, int sub);
187 207
188 208
189struct brkcon { 209struct brkcon {
@@ -193,39 +213,6 @@ struct brkcon {
193 213
194 214
195/* 215/*
196 * redirection
197 */
198struct ioword {
199 short io_unit; /* unit affected */
200 short io_flag; /* action (below) */
201 char *io_name; /* file name */
202};
203
204#define IOREAD 1 /* < */
205#define IOHERE 2 /* << (here file) */
206#define IOWRITE 4 /* > */
207#define IOCAT 8 /* >> */
208#define IOXHERE 16 /* ${}, ` in << */
209#define IODUP 32 /* >&digit */
210#define IOCLOSE 64 /* >&- */
211
212#define IODEFAULT (-1) /* token for default IO unit */
213
214
215
216/*
217 * parsing & execution environment
218 */
219static struct env {
220 char *linep;
221 struct io *iobase;
222 struct io *iop;
223 xint *errpt; /* void * */
224 int iofd;
225 struct env *oenv;
226} e;
227
228/*
229 * flags: 216 * flags:
230 * -e: quit on error 217 * -e: quit on error
231 * -k: look for name=value everywhere on command line 218 * -k: look for name=value everywhere on command line
@@ -264,10 +251,7 @@ static int areanum; /* current allocation area */
264/* 251/*
265 * other functions 252 * other functions
266 */ 253 */
267typedef int (*builtin_func_ptr)(struct op *); 254static const char *rexecve(char *c, char **v, char **envp);
268static builtin_func_ptr inbuilt(char *s);
269
270static char *rexecve(char *c, char **v, char **envp);
271static char *evalstr(char *cp, int f); 255static char *evalstr(char *cp, int f);
272static char *putn(int n); 256static char *putn(int n);
273static char *unquote(char *as); 257static char *unquote(char *as);
@@ -284,13 +268,10 @@ static void onintr(int s); /* SIGINT handler */
284 268
285static int newenv(int f); 269static int newenv(int f);
286static void quitenv(void); 270static void quitenv(void);
287static int anys(const char *s1, const char *s2);
288static int any(int c, const char *s);
289static void next(int f); 271static void next(int f);
290static void setdash(void); 272static void setdash(void);
291static void onecommand(void); 273static void onecommand(void);
292static void runtrap(int i); 274static void runtrap(int i);
293static int gmatch(char *s, char *p);
294 275
295 276
296/* -------- area stuff -------- */ 277/* -------- area stuff -------- */
@@ -391,41 +372,40 @@ static int yyparse(void);
391static int execute(struct op *t, int *pin, int *pout, int act); 372static int execute(struct op *t, int *pin, int *pout, int act);
392 373
393 374
375#define AFID_NOBUF (~0)
376#define AFID_ID 0
377
378
394/* -------- io.h -------- */ 379/* -------- io.h -------- */
395/* io buffer */ 380/* io buffer */
396struct iobuf { 381struct iobuf {
397 unsigned id; /* buffer id */ 382 unsigned id; /* buffer id */
398 char buf[512]; /* buffer */ 383 char buf[512]; /* buffer */
399 char *bufp; /* pointer into buffer */ 384 char *bufp; /* pointer into buffer */
400 char *ebufp; /* pointer to end of buffer */ 385 char *ebufp; /* pointer to end of buffer */
401}; 386};
402 387
403/* possible arguments to an IO function */ 388/* possible arguments to an IO function */
404struct ioarg { 389struct ioarg {
405 char *aword; 390 const char *aword;
406 char **awordlist; 391 char **awordlist;
407 int afile; /* file descriptor */ 392 int afile; /* file descriptor */
408 unsigned afid; /* buffer id */ 393 unsigned afid; /* buffer id */
409 long afpos; /* file position */ 394 long afpos; /* file position */
410 struct iobuf *afbuf; /* buffer for this file */ 395 struct iobuf *afbuf; /* buffer for this file */
411}; 396};
412 397
413//static struct ioarg ioargstack[NPUSH];
414#define AFID_NOBUF (~0)
415#define AFID_ID 0
416
417/* an input generator's state */ 398/* an input generator's state */
418struct io { 399struct io {
419 int (*iofn) (struct ioarg *, struct io *); 400 int (*iofn) (struct ioarg *, struct io *);
420 struct ioarg *argp; 401 struct ioarg *argp;
421 int peekc; 402 int peekc;
422 char prev; /* previous character read by readc() */ 403 char prev; /* previous character read by readc() */
423 char nlcount; /* for `'s */ 404 char nlcount; /* for `'s */
424 char xchar; /* for `'s */ 405 char xchar; /* for `'s */
425 char task; /* reason for pushed IO */ 406 char task; /* reason for pushed IO */
426}; 407};
427 408
428//static struct io iostack[NPUSH];
429#define XOTHER 0 /* none of the below */ 409#define XOTHER 0 /* none of the below */
430#define XDOLL 1 /* expanding ${} */ 410#define XDOLL 1 /* expanding ${} */
431#define XGRAVE 2 /* expanding `'s */ 411#define XGRAVE 2 /* expanding `'s */
@@ -434,6 +414,29 @@ struct io {
434/* in substitution */ 414/* in substitution */
435#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) 415#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL)
436 416
417static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 }; /* temporary for PUSHIO */
418static struct ioarg ioargstack[NPUSH];
419static struct io iostack[NPUSH];
420static struct iobuf sharedbuf = { AFID_NOBUF };
421static struct iobuf mainbuf = { AFID_NOBUF };
422static unsigned bufid = AFID_ID; /* buffer id counter */
423
424#define PUSHIO(what,arg,gen) ((temparg.what = (arg)), pushio(&temparg,(gen)))
425#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
426
427
428/*
429 * parsing & execution environment
430 */
431static struct env {
432 char *linep;
433 struct io *iobase;
434 struct io *iop;
435 xint *errpt; /* void * */
436 int iofd;
437 struct env *oenv;
438} e;
439
437 440
438/* 441/*
439 * input generators for IO structure 442 * input generators for IO structure
@@ -471,9 +474,6 @@ static int openpipe(int *pv);
471static void closepipe(int *pv); 474static void closepipe(int *pv);
472static struct io *setbase(struct io *ip); 475static struct io *setbase(struct io *ip);
473 476
474#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen)))
475#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
476
477/* -------- word.h -------- */ 477/* -------- word.h -------- */
478 478
479#define NSTART 16 /* default number of words to allow for initially */ 479#define NSTART 16 /* default number of words to allow for initially */
@@ -493,9 +493,6 @@ static char **getwords(struct wdblock *wb);
493 493
494static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp); 494static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp);
495static int iosetup(struct ioword *iop, int pipein, int pipeout); 495static int iosetup(struct ioword *iop, int pipein, int pipeout);
496static void echo(char **wp);
497static struct op **find1case(struct op *t, char *w);
498static struct op *findcase(struct op *t, char *w);
499static void brkset(struct brkcon *bc); 496static void brkset(struct brkcon *bc);
500static int dolabel(struct op *t); 497static int dolabel(struct op *t);
501static int dohelp(struct op *t); 498static int dohelp(struct op *t);
@@ -523,7 +520,7 @@ static void badid(char *s);
523static int doset(struct op *t); 520static int doset(struct op *t);
524static void varput(char *s, int out); 521static void varput(char *s, int out);
525static int dotimes(struct op *t); 522static int dotimes(struct op *t);
526static int expand(char *cp, struct wdblock **wbp, int f); 523static int expand(const char *cp, struct wdblock **wbp, int f);
527static char *blank(int f); 524static char *blank(int f);
528static int dollar(int quoted); 525static int dollar(int quoted);
529static int grave(int quoted); 526static int grave(int quoted);
@@ -533,9 +530,6 @@ static int anyspcl(struct wdblock *wb);
533static int xstrcmp(char *p1, char *p2); 530static int xstrcmp(char *p1, char *p2);
534static void glob0(char *a0, unsigned a1, int a2, 531static void glob0(char *a0, unsigned a1, int a2,
535 int (*a3) (char *, char *)); 532 int (*a3) (char *, char *));
536static void glob1(char *base, char *lim);
537static void glob2(char *i, char *j);
538static void glob3(char *i, char *j, char *k);
539static void readhere(char **name, char *s, int ec); 533static void readhere(char **name, char *s, int ec);
540static void pushio(struct ioarg *argp, int (*f) (struct ioarg *)); 534static void pushio(struct ioarg *argp, int (*f) (struct ioarg *));
541static int xxchar(struct ioarg *ap); 535static int xxchar(struct ioarg *ap);
@@ -661,7 +655,7 @@ static struct var *ifs; /* field separators */
661static int areanum; /* current allocation area */ 655static int areanum; /* current allocation area */
662static int intr; 656static int intr;
663static int inparse; 657static int inparse;
664static char *null = ""; 658static char *null = (char*)"";
665static int heedint = 1; 659static int heedint = 1;
666static void (*qflag) (int) = SIG_IGN; 660static void (*qflag) (int) = SIG_IGN;
667static int startl; 661static int startl;
@@ -671,12 +665,6 @@ static int iounit = IODEFAULT;
671static YYSTYPE yylval; 665static YYSTYPE yylval;
672static char *elinep = line + sizeof(line) - 5; 666static char *elinep = line + sizeof(line) - 5;
673 667
674static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 }; /* temporary for PUSHIO */
675static struct ioarg ioargstack[NPUSH];
676static struct io iostack[NPUSH];
677static struct iobuf sharedbuf = { AFID_NOBUF };
678static struct iobuf mainbuf = { AFID_NOBUF };
679static unsigned bufid = AFID_ID; /* buffer id counter */
680 668
681static struct here *inhere; /* list of hear docs while parsing */ 669static struct here *inhere; /* list of hear docs while parsing */
682static struct here *acthere; /* list of active here documents */ 670static struct here *acthere; /* list of active here documents */
@@ -739,6 +727,19 @@ static void prn(unsigned u)
739 prs(itoa(u)); 727 prs(itoa(u));
740} 728}
741 729
730static void echo(char **wp)
731{
732 int i;
733
734 prs("+");
735 for (i = 0; wp[i]; i++) {
736 if (i)
737 prs(" ");
738 prs(wp[i]);
739 }
740 prs("\n");
741}
742
742static void closef(int i) 743static void closef(int i)
743{ 744{
744 if (i > 2) 745 if (i > 2)
@@ -968,7 +969,7 @@ static char *space(int n)
968 char *cp; 969 char *cp;
969 970
970 cp = getcell(n); 971 cp = getcell(n);
971 if (cp == '\0') 972 if (cp == NULL)
972 err("out of string space"); 973 err("out of string space");
973 return cp; 974 return cp;
974} 975}
@@ -978,12 +979,13 @@ static char *strsave(const char *s, int a)
978 char *cp; 979 char *cp;
979 980
980 cp = space(strlen(s) + 1); 981 cp = space(strlen(s) + 1);
981 if (cp != NULL) { 982 if (cp == NULL) {
982 setarea(cp, a); 983// FIXME: I highly doubt this is good.
983 strcpy(cp, s); 984 return (char*)"";
984 return cp;
985 } 985 }
986 return ""; 986 setarea(cp, a);
987 strcpy(cp, s);
988 return cp;
987} 989}
988 990
989 991
@@ -997,7 +999,7 @@ static int eqname(const char *n1, const char *n2)
997 return *n2 == '\0' || *n2 == '='; 999 return *n2 == '\0' || *n2 == '=';
998} 1000}
999 1001
1000static char *findeq(const char *cp) 1002static const char *findeq(const char *cp)
1001{ 1003{
1002 while (*cp != '\0' && *cp != '=') 1004 while (*cp != '\0' && *cp != '=')
1003 cp++; 1005 cp++;
@@ -1012,32 +1014,39 @@ static char *findeq(const char *cp)
1012 */ 1014 */
1013static struct var *lookup(const char *n) 1015static struct var *lookup(const char *n)
1014{ 1016{
1017// FIXME: dirty hack
1018 static struct var dummy;
1019
1015 struct var *vp; 1020 struct var *vp;
1016 char *cp; 1021 const char *cp;
1022 char *xp;
1017 int c; 1023 int c;
1018 static struct var dummy;
1019 1024
1020 if (isdigit(*n)) { 1025 if (isdigit(*n)) {
1021 dummy.name = n; 1026 dummy.name = (char*)n;
1022 for (c = 0; isdigit(*n) && c < 1000; n++) 1027 for (c = 0; isdigit(*n) && c < 1000; n++)
1023 c = c * 10 + *n - '0'; 1028 c = c * 10 + *n - '0';
1024 dummy.status = RONLY; 1029 dummy.status = RONLY;
1025 dummy.value = (c <= dolc ? dolv[c] : null); 1030 dummy.value = (c <= dolc ? dolv[c] : null);
1026 return &dummy; 1031 return &dummy;
1027 } 1032 }
1033
1028 for (vp = vlist; vp; vp = vp->next) 1034 for (vp = vlist; vp; vp = vp->next)
1029 if (eqname(vp->name, n)) 1035 if (eqname(vp->name, n))
1030 return vp; 1036 return vp;
1037
1031 cp = findeq(n); 1038 cp = findeq(n);
1032 vp = (struct var *) space(sizeof(*vp)); 1039 vp = (struct var *) space(sizeof(*vp));
1033 if (vp == 0 || (vp->name = space((int) (cp - n) + 2)) == 0) { 1040 if (vp == 0 || (vp->name = space((int) (cp - n) + 2)) == 0) {
1034 dummy.name = dummy.value = ""; 1041 dummy.name = dummy.value = (char*)"";
1035 return &dummy; 1042 return &dummy;
1036 } 1043 }
1037 for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++); 1044
1038 if (*cp == '\0') 1045 xp = vp->name;
1039 *cp = '='; 1046 while ((*xp = *n++) != '\0' && *xp != '=')
1040 *++cp = '\0'; 1047 xp++;
1048 *xp++ = '=';
1049 *xp = '\0';
1041 setarea((char *) vp, 0); 1050 setarea((char *) vp, 0);
1042 setarea((char *) vp->name, 0); 1051 setarea((char *) vp->name, 0);
1043 vp->value = null; 1052 vp->value = null;
@@ -1085,8 +1094,8 @@ static void nameval(struct var *vp, const char *val, const char *name)
1085 } 1094 }
1086 if (vp->status & GETCELL) 1095 if (vp->status & GETCELL)
1087 freecell(vp->name); /* form new string `name=value' */ 1096 freecell(vp->name); /* form new string `name=value' */
1088 vp->name = name; 1097 vp->name = (char*)name;
1089 vp->value = val; 1098 vp->value = (char*)val;
1090 vp->status |= fl; 1099 vp->status |= fl;
1091} 1100}
1092 1101
@@ -1139,7 +1148,7 @@ static int isassign(const char *s)
1139 1148
1140static int assign(const char *s, int cf) 1149static int assign(const char *s, int cf)
1141{ 1150{
1142 char *cp; 1151 const char *cp;
1143 struct var *vp; 1152 struct var *vp;
1144 1153
1145 DBGPRINTF7(("ASSIGN: enter, s=%s, cf=%d\n", s, cf)); 1154 DBGPRINTF7(("ASSIGN: enter, s=%s, cf=%d\n", s, cf));
@@ -1172,7 +1181,7 @@ static void putvlist(int f, int out)
1172{ 1181{
1173 struct var *vp; 1182 struct var *vp;
1174 1183
1175 for (vp = vlist; vp; vp = vp->next) 1184 for (vp = vlist; vp; vp = vp->next) {
1176 if (vp->status & f && (isalpha(*vp->name) || *vp->name == '_')) { 1185 if (vp->status & f && (isalpha(*vp->name) || *vp->name == '_')) {
1177 if (vp->status & EXPORT) 1186 if (vp->status & EXPORT)
1178 write(out, "export ", 7); 1187 write(out, "export ", 7);
@@ -1181,6 +1190,7 @@ static void putvlist(int f, int out)
1181 write(out, vp->name, (int) (findeq(vp->name) - vp->name)); 1190 write(out, vp->name, (int) (findeq(vp->name) - vp->name));
1182 write(out, "\n", 1); 1191 write(out, "\n", 1);
1183 } 1192 }
1193 }
1184} 1194}
1185 1195
1186 1196
@@ -1429,6 +1439,7 @@ static void onintr(int s) /* ANSI C requires a parameter */
1429 } 1439 }
1430} 1440}
1431 1441
1442
1432/* -------- gmatch.c -------- */ 1443/* -------- gmatch.c -------- */
1433/* 1444/*
1434 * int gmatch(string, pattern) 1445 * int gmatch(string, pattern)
@@ -1442,12 +1453,36 @@ static void onintr(int s) /* ANSI C requires a parameter */
1442#define QMASK (CMASK&~QUOTE) 1453#define QMASK (CMASK&~QUOTE)
1443#define NOT '!' /* might use ^ */ 1454#define NOT '!' /* might use ^ */
1444 1455
1445static int gmatch(char *s, char *p) 1456static const char *cclass(const char *p, int sub)
1457{
1458 int c, d, not, found;
1459
1460 not = (*p == NOT);
1461 if (not != 0)
1462 p++;
1463 found = not;
1464 do {
1465 if (*p == '\0')
1466 return NULL;
1467 c = *p & CMASK;
1468 if (p[1] == '-' && p[2] != ']') {
1469 d = p[2] & CMASK;
1470 p++;
1471 } else
1472 d = c;
1473 if (c == sub || (c <= sub && sub <= d))
1474 found = !not;
1475 } while (*++p != ']');
1476 return found ? p + 1 : NULL;
1477}
1478
1479static int gmatch(const char *s, const char *p)
1446{ 1480{
1447 int sc, pc; 1481 int sc, pc;
1448 1482
1449 if (s == NULL || p == NULL) 1483 if (s == NULL || p == NULL)
1450 return 0; 1484 return 0;
1485
1451 while ((pc = *p++ & CMASK) != '\0') { 1486 while ((pc = *p++ & CMASK) != '\0') {
1452 sc = *s++ & QMASK; 1487 sc = *s++ & QMASK;
1453 switch (pc) { 1488 switch (pc) {
@@ -1478,29 +1513,6 @@ static int gmatch(char *s, char *p)
1478 return *s == '\0'; 1513 return *s == '\0';
1479} 1514}
1480 1515
1481static char *cclass(char *p, int sub)
1482{
1483 int c, d, not, found;
1484
1485 not = (*p == NOT);
1486 if (not != 0)
1487 p++;
1488 found = not;
1489 do {
1490 if (*p == '\0')
1491 return NULL;
1492 c = *p & CMASK;
1493 if (p[1] == '-' && p[2] != ']') {
1494 d = p[2] & CMASK;
1495 p++;
1496 } else
1497 d = c;
1498 if (c == sub || (c <= sub && sub <= d))
1499 found = !not;
1500 } while (*++p != ']');
1501 return found ? p + 1 : NULL;
1502}
1503
1504 1516
1505/* -------- csyn.c -------- */ 1517/* -------- csyn.c -------- */
1506/* 1518/*
@@ -2323,21 +2335,68 @@ static char *tree(unsigned size)
2323 return t; 2335 return t;
2324} 2336}
2325 2337
2338
2326/* VARARGS1 */ 2339/* VARARGS1 */
2327/* ARGSUSED */ 2340/* ARGSUSED */
2328 2341
2329/* -------- exec.c -------- */ 2342/* -------- exec.c -------- */
2330 2343
2344static struct op **find1case(struct op *t, const char *w)
2345{
2346 struct op *t1;
2347 struct op **tp;
2348 char **wp;
2349 char *cp;
2350
2351 if (t == NULL) {
2352 DBGPRINTF3(("FIND1CASE: enter, t==NULL, returning.\n"));
2353 return NULL;
2354 }
2355
2356 DBGPRINTF3(("FIND1CASE: enter, t->type=%d (%s)\n", t->type,
2357 T_CMD_NAMES[t->type]));
2358
2359 if (t->type == TLIST) {
2360 tp = find1case(t->left, w);
2361 if (tp != NULL) {
2362 DBGPRINTF3(("FIND1CASE: found one to the left, returning tp=%p\n", tp));
2363 return tp;
2364 }
2365 t1 = t->right; /* TPAT */
2366 } else
2367 t1 = t;
2368
2369 for (wp = t1->words; *wp;) {
2370 cp = evalstr(*wp++, DOSUB);
2371 if (cp && gmatch(w, cp)) {
2372 DBGPRINTF3(("FIND1CASE: returning &t1->left= %p.\n",
2373 &t1->left));
2374 return &t1->left;
2375 }
2376 }
2377
2378 DBGPRINTF(("FIND1CASE: returning NULL\n"));
2379 return NULL;
2380}
2381
2382static struct op *findcase(struct op *t, const char *w)
2383{
2384 struct op **tp;
2385
2386 tp = find1case(t, w);
2387 return tp != NULL ? *tp : NULL;
2388}
2389
2331/* 2390/*
2332 * execute tree 2391 * execute tree
2333 */ 2392 */
2334 2393
2335
2336static int execute(struct op *t, int *pin, int *pout, int act) 2394static int execute(struct op *t, int *pin, int *pout, int act)
2337{ 2395{
2338 struct op *t1; 2396 struct op *t1;
2339 volatile int i, rv, a; 2397 volatile int i, rv, a;
2340 char *cp, **wp, **wp2; 2398 const char *cp;
2399 char **wp, **wp2;
2341 struct var *vp; 2400 struct var *vp;
2342 struct op *outtree_save; 2401 struct op *outtree_save;
2343 struct brkcon bc; 2402 struct brkcon bc;
@@ -2551,14 +2610,25 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2551 return rv; 2610 return rv;
2552} 2611}
2553 2612
2554static int 2613typedef int (*builtin_func_ptr)(struct op *);
2555forkexec(struct op *t, int *pin, int *pout, int act, char **wp) 2614
2615static builtin_func_ptr inbuilt(const char *s) {
2616 const struct builtincmd *bp;
2617
2618 for (bp = builtincmds; bp->name != NULL; bp++)
2619 if (strcmp(bp->name, s) == 0)
2620 return bp->builtinfunc;
2621
2622 return NULL;
2623}
2624
2625static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2556{ 2626{
2557 pid_t newpid; 2627 pid_t newpid;
2558 int i, rv; 2628 int i, rv;
2559 builtin_func_ptr shcom = NULL; 2629 builtin_func_ptr shcom = NULL;
2560 int f; 2630 int f;
2561 char *cp = NULL; 2631 const char *cp = NULL;
2562 struct ioword **iopp; 2632 struct ioword **iopp;
2563 int resetsig; 2633 int resetsig;
2564 char **owp; 2634 char **owp;
@@ -2592,7 +2662,7 @@ forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2592 resetsig = 0; 2662 resetsig = 0;
2593 rv = -1; /* system-detected error */ 2663 rv = -1; /* system-detected error */
2594 if (t->type == TCOM) { 2664 if (t->type == TCOM) {
2595 while ((cp = *wp++) != NULL); 2665 while (*wp++ != NULL);
2596 cp = *wp; 2666 cp = *wp;
2597 2667
2598 /* strip all initial assignments */ 2668 /* strip all initial assignments */
@@ -2755,7 +2825,8 @@ forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2755static int iosetup(struct ioword *iop, int pipein, int pipeout) 2825static int iosetup(struct ioword *iop, int pipein, int pipeout)
2756{ 2826{
2757 int u = -1; 2827 int u = -1;
2758 char *cp = NULL, *msg; 2828 char *cp = NULL;
2829 const char *msg;
2759 2830
2760 DBGPRINTF(("IOSETUP: iop %p, pipein %i, pipeout %i\n", iop, 2831 DBGPRINTF(("IOSETUP: iop %p, pipein %i, pipeout %i\n", iop,
2761 pipein, pipeout)); 2832 pipein, pipeout));
@@ -2795,7 +2866,7 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
2795 case IOHERE: 2866 case IOHERE:
2796 case IOHERE | IOXHERE: 2867 case IOHERE | IOXHERE:
2797 u = herein(iop->io_name, iop->io_flag & IOXHERE); 2868 u = herein(iop->io_name, iop->io_flag & IOXHERE);
2798 cp = "here file"; 2869 cp = (char*)"here file";
2799 break; 2870 break;
2800 2871
2801 case IOWRITE | IOCAT: 2872 case IOWRITE | IOCAT:
@@ -2829,64 +2900,6 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
2829 return 0; 2900 return 0;
2830} 2901}
2831 2902
2832static void echo(char **wp)
2833{
2834 int i;
2835
2836 prs("+");
2837 for (i = 0; wp[i]; i++) {
2838 if (i)
2839 prs(" ");
2840 prs(wp[i]);
2841 }
2842 prs("\n");
2843}
2844
2845static struct op **find1case(struct op *t, char *w)
2846{
2847 struct op *t1;
2848 struct op **tp;
2849 char **wp, *cp;
2850
2851 if (t == NULL) {
2852 DBGPRINTF3(("FIND1CASE: enter, t==NULL, returning.\n"));
2853 return NULL;
2854 }
2855
2856 DBGPRINTF3(("FIND1CASE: enter, t->type=%d (%s)\n", t->type,
2857 T_CMD_NAMES[t->type]));
2858
2859 if (t->type == TLIST) {
2860 tp = find1case(t->left, w);
2861 if (tp != NULL) {
2862 DBGPRINTF3(("FIND1CASE: found one to the left, returning tp=%p\n", tp));
2863 return tp;
2864 }
2865 t1 = t->right; /* TPAT */
2866 } else
2867 t1 = t;
2868
2869 for (wp = t1->words; *wp;) {
2870 cp = evalstr(*wp++, DOSUB);
2871 if (cp && gmatch(w, cp)) {
2872 DBGPRINTF3(("FIND1CASE: returning &t1->left= %p.\n",
2873 &t1->left));
2874 return &t1->left;
2875 }
2876 }
2877
2878 DBGPRINTF(("FIND1CASE: returning NULL\n"));
2879 return NULL;
2880}
2881
2882static struct op *findcase(struct op *t, char *w)
2883{
2884 struct op **tp;
2885
2886 tp = find1case(t, w);
2887 return tp != NULL ? *tp : NULL;
2888}
2889
2890/* 2903/*
2891 * Enter a new loop level (marked for break/continue). 2904 * Enter a new loop level (marked for break/continue).
2892 */ 2905 */
@@ -2971,10 +2984,11 @@ static int setstatus(int s)
2971 * If getenv("PATH") were kept up-to-date, 2984 * If getenv("PATH") were kept up-to-date,
2972 * execvp might be used. 2985 * execvp might be used.
2973 */ 2986 */
2974static char *rexecve(char *c, char **v, char **envp) 2987static const char *rexecve(char *c, char **v, char **envp)
2975{ 2988{
2976 int i; 2989 int i;
2977 char *sp, *tp; 2990 const char *sp;
2991 char *tp;
2978 int eacces = 0, asis = 0; 2992 int eacces = 0, asis = 0;
2979 char *name = c; 2993 char *name = c;
2980 2994
@@ -2991,7 +3005,7 @@ static char *rexecve(char *c, char **v, char **envp)
2991 DBGPRINTF(("REXECVE: c=%p, v=%p, envp=%p\n", c, v, envp)); 3005 DBGPRINTF(("REXECVE: c=%p, v=%p, envp=%p\n", c, v, envp));
2992 3006
2993 sp = any('/', c) ? "" : path->value; 3007 sp = any('/', c) ? "" : path->value;
2994 asis = *sp == '\0'; 3008 asis = (*sp == '\0');
2995 while (asis || *sp != '\0') { 3009 while (asis || *sp != '\0') {
2996 asis = 0; 3010 asis = 0;
2997 tp = e.linep; 3011 tp = e.linep;
@@ -3138,7 +3152,7 @@ static int dolabel(struct op *t)
3138 3152
3139static int dochdir(struct op *t) 3153static int dochdir(struct op *t)
3140{ 3154{
3141 char *cp, *er; 3155 const char *cp, *er;
3142 3156
3143 cp = t->words[1]; 3157 cp = t->words[1];
3144 if (cp == NULL) { 3158 if (cp == NULL) {
@@ -3175,7 +3189,7 @@ static int doshift(struct op *t)
3175 */ 3189 */
3176static int dologin(struct op *t) 3190static int dologin(struct op *t)
3177{ 3191{
3178 char *cp; 3192 const char *cp;
3179 3193
3180 if (interactive) { 3194 if (interactive) {
3181 signal(SIGINT, SIG_DFL); 3195 signal(SIGINT, SIG_DFL);
@@ -3232,7 +3246,8 @@ static int doexec(struct op *t)
3232static int dodot(struct op *t) 3246static int dodot(struct op *t)
3233{ 3247{
3234 int i; 3248 int i;
3235 char *sp, *tp; 3249 const char *sp;
3250 char *tp;
3236 char *cp; 3251 char *cp;
3237 int maltmp; 3252 int maltmp;
3238 3253
@@ -3578,16 +3593,6 @@ static int dotimes(struct op *t)
3578} 3593}
3579 3594
3580 3595
3581static builtin_func_ptr inbuilt(char *s) {
3582 const struct builtincmd *bp;
3583
3584 for (bp = builtincmds; bp->name != NULL; bp++)
3585 if (strcmp(bp->name, s) == 0)
3586 return bp->builtinfunc;
3587
3588 return NULL;
3589}
3590
3591/* -------- eval.c -------- */ 3596/* -------- eval.c -------- */
3592 3597
3593/* 3598/*
@@ -3639,6 +3644,7 @@ static char **eval(char **ap, int f)
3639 return gflg ? (char **) NULL : wp; 3644 return gflg ? (char **) NULL : wp;
3640} 3645}
3641 3646
3647
3642/* 3648/*
3643 * Make the exported environment from the exported 3649 * Make the exported environment from the exported
3644 * names in the dictionary. Keyword assignments 3650 * names in the dictionary. Keyword assignments
@@ -3657,26 +3663,10 @@ static char **makenv(int all, struct wdblock *wb)
3657 return getwords(wb); 3663 return getwords(wb);
3658} 3664}
3659 3665
3660static char *evalstr(char *cp, int f) 3666static int expand(const char *cp, struct wdblock **wbp, int f)
3661{
3662 struct wdblock *wb;
3663
3664 DBGPRINTF6(("EVALSTR: enter, cp=%p, f=%d\n", cp, f));
3665
3666 wb = NULL;
3667 if (expand(cp, &wb, f)) {
3668 if (wb == NULL || wb->w_nword == 0
3669 || (cp = wb->w_words[0]) == NULL)
3670 cp = "";
3671 DELETE(wb);
3672 } else
3673 cp = NULL;
3674 return cp;
3675}
3676
3677static int expand(char *cp, struct wdblock **wbp, int f)
3678{ 3667{
3679 jmp_buf ev; 3668 jmp_buf ev;
3669 char *xp;
3680 3670
3681#if __GNUC__ 3671#if __GNUC__
3682 /* Avoid longjmp clobbering */ 3672 /* Avoid longjmp clobbering */
@@ -3690,27 +3680,28 @@ static int expand(char *cp, struct wdblock **wbp, int f)
3690 if (cp == NULL) 3680 if (cp == NULL)
3691 return 0; 3681 return 0;
3692 3682
3693 if (!anys("$`'\"", cp) && 3683 if (!anys("$`'\"", cp) && !anys(ifs->value, cp)
3694 !anys(ifs->value, cp) && ((f & DOGLOB) == 0 || !anys("[*?", cp))) { 3684 && ((f & DOGLOB) == 0 || !anys("[*?", cp))
3695 cp = strsave(cp, areanum); 3685 ) {
3686 xp = strsave(cp, areanum);
3696 if (f & DOTRIM) 3687 if (f & DOTRIM)
3697 unquote(cp); 3688 unquote(xp);
3698 *wbp = addword(cp, *wbp); 3689 *wbp = addword(xp, *wbp);
3699 return 1; 3690 return 1;
3700 } 3691 }
3701 errpt = ev; 3692 errpt = ev;
3702 if (newenv(setjmp(errpt)) == 0) { 3693 if (newenv(setjmp(errpt)) == 0) {
3703 PUSHIO(aword, cp, strchar); 3694 PUSHIO(aword, cp, strchar);
3704 e.iobase = e.iop; 3695 e.iobase = e.iop;
3705 while ((cp = blank(f)) && gflg == 0) { 3696 while ((xp = blank(f)) && gflg == 0) {
3706 e.linep = cp; 3697 e.linep = xp;
3707 cp = strsave(cp, areanum); 3698 xp = strsave(xp, areanum);
3708 if ((f & DOGLOB) == 0) { 3699 if ((f & DOGLOB) == 0) {
3709 if (f & DOTRIM) 3700 if (f & DOTRIM)
3710 unquote(cp); 3701 unquote(xp);
3711 *wbp = addword(cp, *wbp); 3702 *wbp = addword(xp, *wbp);
3712 } else 3703 } else
3713 *wbp = glob(cp, *wbp); 3704 *wbp = glob(xp, *wbp);
3714 } 3705 }
3715 quitenv(); 3706 quitenv();
3716 } else 3707 } else
@@ -3718,6 +3709,29 @@ static int expand(char *cp, struct wdblock **wbp, int f)
3718 return gflg == 0; 3709 return gflg == 0;
3719} 3710}
3720 3711
3712static char *evalstr(char *cp, int f)
3713{
3714 struct wdblock *wb;
3715
3716 DBGPRINTF6(("EVALSTR: enter, cp=%p, f=%d\n", cp, f));
3717
3718 wb = NULL;
3719 if (expand(cp, &wb, f)) {
3720 if (wb == NULL || wb->w_nword == 0
3721 || (cp = wb->w_words[0]) == NULL
3722 ) {
3723// TODO: I suspect that
3724// char *evalstr(char *cp, int f) is actually
3725// const char *evalstr(const char *cp, int f)!
3726 cp = (char*)"";
3727 }
3728 DELETE(wb);
3729 } else
3730 cp = NULL;
3731 return cp;
3732}
3733
3734
3721/* 3735/*
3722 * Blank interpretation and quoting 3736 * Blank interpretation and quoting
3723 */ 3737 */
@@ -3927,12 +3941,12 @@ static int dollar(int quoted)
3927 3941
3928static int grave(int quoted) 3942static int grave(int quoted)
3929{ 3943{
3930 char *cp; 3944 const char *cp;
3931 int i; 3945 int i;
3932 int j; 3946 int j;
3933 int pf[2]; 3947 int pf[2];
3934 static char child_cmd[LINELIM]; 3948 static char child_cmd[LINELIM];
3935 char *src; 3949 const char *src;
3936 char *dest; 3950 char *dest;
3937 int count; 3951 int count;
3938 int ignore; 3952 int ignore;
@@ -3945,11 +3959,12 @@ static int grave(int quoted)
3945 (void) &cp; 3959 (void) &cp;
3946#endif 3960#endif
3947 3961
3948 for (cp = e.iop->argp->aword; *cp != '`'; cp++) 3962 for (cp = e.iop->argp->aword; *cp != '`'; cp++) {
3949 if (*cp == 0) { 3963 if (*cp == 0) {
3950 err("no closing `"); 3964 err("no closing `");
3951 return 0; 3965 return 0;
3952 } 3966 }
3967 }
3953 3968
3954 /* string copy with dollar expansion */ 3969 /* string copy with dollar expansion */
3955 src = e.iop->argp->aword; 3970 src = e.iop->argp->aword;
@@ -4078,8 +4093,7 @@ static int grave(int quoted)
4078 e.iop->argp->aword = ++cp; 4093 e.iop->argp->aword = ++cp;
4079 close(pf[1]); 4094 close(pf[1]);
4080 PUSHIO(afile, remap(pf[0]), 4095 PUSHIO(afile, remap(pf[0]),
4081 (int (*)(struct ioarg *)) ((quoted) ? qgravechar : 4096 (int (*)(struct ioarg *)) ((quoted) ? qgravechar : gravechar));
4082 gravechar));
4083 return 1; 4097 return 1;
4084 } 4098 }
4085 /* allow trapped signals */ 4099 /* allow trapped signals */
@@ -4092,9 +4106,9 @@ static int grave(int quoted)
4092 closepipe(pf); 4106 closepipe(pf);
4093 4107
4094 argument_list[0] = (char *) DEFAULT_SHELL; 4108 argument_list[0] = (char *) DEFAULT_SHELL;
4095 argument_list[1] = "-c"; 4109 argument_list[1] = (char *) "-c";
4096 argument_list[2] = child_cmd; 4110 argument_list[2] = child_cmd;
4097 argument_list[3] = 0; 4111 argument_list[3] = NULL;
4098 4112
4099 cp = rexecve(argument_list[0], argument_list, makenv(1, wb)); 4113 cp = rexecve(argument_list[0], argument_list, makenv(1, wb));
4100 prs(argument_list[0]); 4114 prs(argument_list[0]);
@@ -4263,6 +4277,7 @@ static int xstrcmp(char *p1, char *p2)
4263 return strcmp(*(char **) p1, *(char **) p2); 4277 return strcmp(*(char **) p1, *(char **) p2);
4264} 4278}
4265 4279
4280
4266/* -------- word.c -------- */ 4281/* -------- word.c -------- */
4267 4282
4268static struct wdblock *newword(int nw) 4283static struct wdblock *newword(int nw)
@@ -4316,11 +4331,37 @@ char **getwords(struct wdblock *wb)
4316static int (*func) (char *, char *); 4331static int (*func) (char *, char *);
4317static int globv; 4332static int globv;
4318 4333
4319static void glob0(char *a0, unsigned a1, int a2, int (*a3) (char *, char *)) 4334static void glob3(char *i, char *j, char *k)
4320{ 4335{
4321 func = a3; 4336 char *index1, *index2, *index3;
4322 globv = a2; 4337 int c;
4323 glob1(a0, a0 + a1 * a2); 4338 int m;
4339
4340 m = globv;
4341 index1 = i;
4342 index2 = j;
4343 index3 = k;
4344 do {
4345 c = *index1;
4346 *index1++ = *index3;
4347 *index3++ = *index2;
4348 *index2++ = c;
4349 } while (--m);
4350}
4351
4352static void glob2(char *i, char *j)
4353{
4354 char *index1, *index2, c;
4355 int m;
4356
4357 m = globv;
4358 index1 = i;
4359 index2 = j;
4360 do {
4361 c = *index1;
4362 *index1++ = *index2;
4363 *index2++ = c;
4364 } while (--m);
4324} 4365}
4325 4366
4326static void glob1(char *base, char *lim) 4367static void glob1(char *base, char *lim)
@@ -4397,38 +4438,13 @@ static void glob1(char *base, char *lim)
4397 } 4438 }
4398} 4439}
4399 4440
4400static void glob2(char *i, char *j) 4441static void glob0(char *a0, unsigned a1, int a2, int (*a3) (char *, char *))
4401{ 4442{
4402 char *index1, *index2, c; 4443 func = a3;
4403 int m; 4444 globv = a2;
4404 4445 glob1(a0, a0 + a1 * a2);
4405 m = globv;
4406 index1 = i;
4407 index2 = j;
4408 do {
4409 c = *index1;
4410 *index1++ = *index2;
4411 *index2++ = c;
4412 } while (--m);
4413} 4446}
4414 4447
4415static void glob3(char *i, char *j, char *k)
4416{
4417 char *index1, *index2, *index3;
4418 int c;
4419 int m;
4420
4421 m = globv;
4422 index1 = i;
4423 index2 = j;
4424 index3 = k;
4425 do {
4426 c = *index1;
4427 *index1++ = *index3;
4428 *index3++ = *index2;
4429 *index2++ = c;
4430 } while (--m);
4431}
4432 4448
4433/* -------- io.c -------- */ 4449/* -------- io.c -------- */
4434 4450
@@ -4875,6 +4891,7 @@ static void closepipe(int *pv)
4875 } 4891 }
4876} 4892}
4877 4893
4894
4878/* -------- here.c -------- */ 4895/* -------- here.c -------- */
4879 4896
4880/* 4897/*