msh: reduce global data/bss usage

(add/remove: 1/5 grow/shrink: 28/6 up/down: 464/-394)          Total: 70 bytes
   text    data     bss     dec     hex filename
 778077     908    7568  786553   c0079 busybox_old
 778330     860    7408  786598   c00a6 busybox_unstripped

diff --git a/shell/msh.c b/shell/msh.c
index 9f95fe2..9edf793 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -202,24 +202,24 @@
 	char *str;					/* identifier for case and for */
 };
 
-#define	TCOM	1				/* command */
-#define	TPAREN	2				/* (c-list) */
-#define	TPIPE	3				/* a | b */
-#define	TLIST	4				/* a [&;] b */
-#define	TOR		5				/* || */
-#define	TAND	6				/* && */
-#define	TFOR	7
-#define	TDO		8
-#define	TCASE	9
-#define	TIF		10
-#define	TWHILE	11
-#define	TUNTIL	12
-#define	TELIF	13
-#define	TPAT	14				/* pattern in case */
-#define	TBRACE	15				/* {c-list} */
-#define	TASYNC	16				/* c & */
+#define TCOM    1       /* command */
+#define TPAREN  2       /* (c-list) */
+#define TPIPE   3       /* a | b */
+#define TLIST   4       /* a [&;] b */
+#define TOR     5       /* || */
+#define TAND    6       /* && */
+#define TFOR    7
+#define TDO     8
+#define TCASE   9
+#define TIF     10
+#define TWHILE  11
+#define TUNTIL  12
+#define TELIF   13
+#define TPAT    14      /* pattern in case */
+#define TBRACE  15      /* {c-list} */
+#define TASYNC  16      /* c & */
 /* Added to support "." file expansion */
-#define	TDOT	17
+#define TDOT    17
 
 /* Strings for names to make debug easier */
 #ifdef MSHDEBUG
@@ -270,22 +270,6 @@
 };
 
 
-/*
- * flags:
- * -e: quit on error
- * -k: look for name=value everywhere on command line
- * -n: no execution
- * -t: exit after reading and executing one command
- * -v: echo as read
- * -x: trace
- * -u: unset variables net diagnostic
- */
-static char flags['z' - 'a' + 1] ALIGN1;
-/* this looks weird, but is OK ... we index FLAG with 'a'...'z' */
-#define FLAG (flags - 'a')
-
-/* moved to G: static char *trap[_NSIG + 1]; */
-/* moved to G: static char ourtrap[_NSIG + 1]; */
 static int trapset;				/* trap pending */
 
 static int yynerrs;				/* yacc */
@@ -422,10 +406,6 @@
 static int execute(struct op *t, int *pin, int *pout, int act);
 
 
-#define AFID_NOBUF	(~0)
-#define AFID_ID		0
-
-
 /* -------- io.h -------- */
 /* io buffer */
 struct iobuf {
@@ -455,23 +435,11 @@
 	char xchar;             /* for `'s */
 	char task;              /* reason for pushed IO */
 };
-
-#define	XOTHER	0				/* none of the below */
-#define	XDOLL	1				/* expanding ${} */
-#define	XGRAVE	2				/* expanding `'s */
-#define	XIO	3				/* file IO */
-
-/* in substitution */
-#define	INSUB()	(e.iop->task == XGRAVE || e.iop->task == XDOLL)
-
-static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 };	/* temporary for PUSHIO */
-/* moved to G: static struct ioarg ioargstack[NPUSH]; */
-static struct io iostack[NPUSH];
-/* moved to G: static struct iobuf sharedbuf = { AFID_NOBUF }; */
-/* moved to G: static struct iobuf mainbuf = { AFID_NOBUF }; */
-static unsigned bufid = AFID_ID;	/* buffer id counter */
-
-#define	RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
+/* ->task: */
+#define	XOTHER	0	/* none of the below */
+#define	XDOLL	1	/* expanding ${} */
+#define	XGRAVE	2	/* expanding `'s */
+#define	XIO	3	/* file IO */
 
 
 /*
@@ -597,33 +565,6 @@
 };
 
 
-struct res {
-	const char *r_name;
-	int r_val;
-};
-static const struct res restab[] = {
-	{ "for"  , FOR    },
-	{ "case" , CASE   },
-	{ "esac" , ESAC   },
-	{ "while", WHILE  },
-	{ "do"   , DO     },
-	{ "done" , DONE   },
-	{ "if"   , IF     },
-	{ "in"   , IN     },
-	{ "then" , THEN   },
-	{ "else" , ELSE   },
-	{ "elif" , ELIF   },
-	{ "until", UNTIL  },
-	{ "fi"   , FI     },
-	{ ";;"   , BREAK  },
-	{ "||"   , LOGOR  },
-	{ "&&"   , LOGAND },
-	{ "{"    , '{'    },
-	{ "}"    , '}'    },
-	{ "."    , DOT    },
-	{ NULL   , 0      },
-};
-
 struct builtincmd {
 	const char *name;
 	int (*builtinfunc)(struct op *t);
@@ -704,6 +645,10 @@
 static void *brktop;
 static void *brkaddr;
 
+#define AFID_NOBUF	(~0)
+#define AFID_ID		0
+
+
 /*
  * parsing & execution environment
  */
@@ -716,44 +661,68 @@
 	struct env *oenv;
 };
 
-static struct env e = {
-	NULL /* set to line in main() */, /* linep:  char ptr */
-	iostack,                /* iobase:  struct io ptr */
-	iostack - 1,            /* iop:  struct io ptr */
-	(xint *) NULL,          /* errpt:  void ptr for errors? */
-	FDBASE,                 /* iofd:  file desc  */
-	(struct env *) NULL     /* oenv:  struct env ptr */
-};
-
 
 struct globals {
+	struct env global_env;
+	struct ioarg temparg; // = { .afid = AFID_NOBUF };	/* temporary for PUSHIO */
+	unsigned bufid; // = AFID_ID;	/* buffer id counter */
 	char ourtrap[_NSIG + 1];
 	char *trap[_NSIG + 1];
 	struct iobuf sharedbuf; /* in main(): set to { AFID_NOBUF } */
 	struct iobuf mainbuf; /* in main(): set to { AFID_NOBUF } */
 	struct ioarg ioargstack[NPUSH];
+	/*
+	 * flags:
+	 * -e: quit on error
+	 * -k: look for name=value everywhere on command line
+	 * -n: no execution
+	 * -t: exit after reading and executing one command
+	 * -v: echo as read
+	 * -x: trace
+	 * -u: unset variables net diagnostic
+	 */
+	char flags['z' - 'a' + 1];
 	char filechar_cmdbuf[BUFSIZ];
 	char line[LINELIM];
 	char child_cmd[LINELIM];
 
+	struct io iostack[NPUSH];
+
 	char grave__var_name[LINELIM];
 	char grave__alt_value[LINELIM];
 };
 
 #define G (*ptr_to_globals)
+#define global_env      (G.global_env     )
+#define temparg         (G.temparg        )
+#define bufid           (G.bufid          )
 #define ourtrap         (G.ourtrap        )
 #define trap            (G.trap           )
 #define sharedbuf       (G.sharedbuf      )
 #define mainbuf         (G.mainbuf        )
 #define ioargstack      (G.ioargstack     )
+/* this looks weird, but is OK ... we index FLAG with 'a'...'z' */
+#define FLAG            (G.flags - 'a'    )
 #define filechar_cmdbuf (G.filechar_cmdbuf)
 #define line            (G.line           )
 #define child_cmd       (G.child_cmd      )
+#define iostack         (G.iostack        )
 #define INIT_G() do { \
 	PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
+	global_env.linep = line; \
+	global_env.iobase = iostack; \
+	global_env.iop = iostack - 1; \
+	global_env.iofd = FDBASE; \
+	temparg.afid = AFID_NOBUF; \
+	bufid = AFID_ID; \
 } while (0)
 
 
+/* in substitution */
+#define	INSUB()	(global_env.iop->task == XGRAVE || global_env.iop->task == XDOLL)
+
+#define	RUN(what, arg, gen) ((temparg.what = (arg)), run(&temparg, (gen)))
+
 #ifdef MSHDEBUG
 void print_t(struct op *t)
 {
@@ -867,10 +836,10 @@
 		return;
 	if (!interactive)
 		leave();
-	if (e.errpt)
-		longjmp(e.errpt, 1);
+	if (global_env.errpt)
+		longjmp(global_env.errpt, 1);
 	closeall();
-	e.iop = e.iobase = iostack;
+	global_env.iop = global_env.iobase = iostack;
 }
 
 
@@ -1364,7 +1333,7 @@
 
 	DBGPRINTF(("ONECOMMAND: enter, outtree=%p\n", outtree));
 
-	while (e.oenv)
+	while (global_env.oenv)
 		quitenv();
 
 	areanum = 1;
@@ -1373,8 +1342,8 @@
 	garbage();
 	wdlist = 0;
 	iolist = 0;
-	e.errpt = 0;
-	e.linep = line;
+	global_env.errpt = 0;
+	global_env.linep = line;
 	yynerrs = 0;
 	multiline = 0;
 	inparse = 1;
@@ -1387,7 +1356,7 @@
 	if (setjmp(failpt) || yyparse() || intr) {
 		DBGPRINTF(("ONECOMMAND: this is not good.\n"));
 
-		while (e.oenv)
+		while (global_env.oenv)
 			quitenv();
 		scraphere();
 		if (!interactive && intr)
@@ -1433,13 +1402,13 @@
 
 	ep = (struct env *) space(sizeof(*ep));
 	if (ep == NULL) {
-		while (e.oenv)
+		while (global_env.oenv)
 			quitenv();
 		fail();
 	}
-	*ep = e;
-	e.oenv = ep;
-	e.errpt = errpt;
+	*ep = global_env;
+	global_env.oenv = ep;
+	global_env.errpt = errpt;
 
 	return 0;
 }
@@ -1449,15 +1418,15 @@
 	struct env *ep;
 	int fd;
 
-	DBGPRINTF(("QUITENV: e.oenv=%p\n", e.oenv));
+	DBGPRINTF(("QUITENV: global_env.oenv=%p\n", global_env.oenv));
 
-	ep = e.oenv;
+	ep = global_env.oenv;
 	if (ep != NULL) {
-		fd = e.iofd;
-		e = *ep;
+		fd = global_env.iofd;
+		global_env = *ep;
 		/* should close `'d files */
 		DELETE(ep);
-		while (--fd >= e.iofd)
+		while (--fd >= global_env.iofd)
 			close(fd);
 	}
 }
@@ -1593,7 +1562,7 @@
 static void yyerror(const char *s)
 {
 	yynerrs++;
-	if (interactive && e.iop <= iostack) {
+	if (interactive && global_env.iop <= iostack) {
 		multiline = 0;
 		while (eofc() == 0 && yylex(0) != '\n');
 	}
@@ -2085,11 +2054,38 @@
 /* See if given string is a shell multiline (FOR, IF, etc) */
 static int rlookup(char *n)
 {
+	struct res {
+		char r_name[6];
+		int16_t r_val;
+	};
+	static const struct res restab[] = {
+		{ "for"  , FOR    },
+		{ "case" , CASE   },
+		{ "esac" , ESAC   },
+		{ "while", WHILE  },
+		{ "do"   , DO     },
+		{ "done" , DONE   },
+		{ "if"   , IF     },
+		{ "in"   , IN     },
+		{ "then" , THEN   },
+		{ "else" , ELSE   },
+		{ "elif" , ELIF   },
+		{ "until", UNTIL  },
+		{ "fi"   , FI     },
+		{ ";;"   , BREAK  },
+		{ "||"   , LOGOR  },
+		{ "&&"   , LOGAND },
+		{ "{"    , '{'    },
+		{ "}"    , '}'    },
+		{ "."    , DOT    },
+		{ },
+	};
+
 	const struct res *rp;
 
 	DBGPRINTF7(("RLOOKUP: enter, n is %s\n", n));
 
-	for (rp = restab; rp->r_name; rp++)
+	for (rp = restab; rp->r_name[0]; rp++)
 		if (strcmp(rp->r_name, n) == 0) {
 			DBGPRINTF7(("RLOOKUP: match, returning %d\n", rp->r_val));
 			return rp->r_val;	/* Return numeric code for shell multiline */
@@ -2194,7 +2190,7 @@
 	atstart = startl;
 	startl = 0;
 	yylval.i = 0;
-	e.linep = line;
+	global_env.linep = line;
 
 /* MALAMO */
 	line[LINELIM - 1] = '\0';
@@ -2212,7 +2208,7 @@
 				iounit = c - '0';
 				goto loop;
 			}
-			*e.linep++ = c;
+			*global_env.linep++ = c;
 			c = c1;
 		}
 		break;
@@ -2228,7 +2224,7 @@
 
 	case '$':
 		DBGPRINTF9(("YYLEX: found $\n"));
-		*e.linep++ = c;
+		*global_env.linep++ = c;
 		c = my_getc(0);
 		if (c == '{') {
 			c = collect(c, '}');
@@ -2269,7 +2265,7 @@
 		gethere();
 		startl = 1;
 		if (multiline || cf & CONTIN) {
-			if (interactive && e.iop <= iostack) {
+			if (interactive && global_env.iop <= iostack) {
 #if ENABLE_FEATURE_EDITING
 				current_prompt = cprompt->value;
 #else
@@ -2291,10 +2287,10 @@
 
  pack:
 	while ((c = my_getc(0)) != '\0' && !any(c, "`$ '\"\t;&<>()|^\n")) {
-		if (e.linep >= elinep)
+		if (global_env.linep >= elinep)
 			err("word too long");
 		else
-			*e.linep++ = c;
+			*global_env.linep++ = c;
 	};
 
 	unget(c);
@@ -2302,7 +2298,7 @@
 	if (any(c, "\"'`$"))
 		goto loop;
 
-	*e.linep++ = '\0';
+	*global_env.linep++ = '\0';
 
 	if (atstart) {
 		c = rlookup(line);
@@ -2323,7 +2319,7 @@
 
 	DBGPRINTF8(("COLLECT: enter, c=%d, c1=%d\n", c, c1));
 
-	*e.linep++ = c;
+	*global_env.linep++ = c;
 	while ((c = my_getc(c1)) != c1) {
 		if (c == 0) {
 			unget(c);
@@ -2333,17 +2329,17 @@
 			yyerror(s);
 			return YYERRCODE;
 		}
-		if (interactive && c == '\n' && e.iop <= iostack) {
+		if (interactive && c == '\n' && global_env.iop <= iostack) {
 #if ENABLE_FEATURE_EDITING
 			current_prompt = cprompt->value;
 #else
 			prs(cprompt->value);
 #endif
 		}
-		*e.linep++ = c;
+		*global_env.linep++ = c;
 	}
 
-	*e.linep++ = c;
+	*global_env.linep++ = c;
 
 	DBGPRINTF8(("COLLECT: return 0, line is %s\n", line));
 
@@ -3077,7 +3073,7 @@
 	asis = (*sp == '\0');
 	while (asis || *sp != '\0') {
 		asis = 0;
-		tp = e.linep;
+		tp = global_env.linep;
 		for (; *sp != '\0'; tp++) {
 			*tp = *sp++;
 			if (*tp == ':') {
@@ -3085,19 +3081,19 @@
 				break;
 			}
 		}
-		if (tp != e.linep)
+		if (tp != global_env.linep)
 			*tp++ = '/';
 		for (i = 0; (*tp++ = c[i++]) != '\0';);
 
-		DBGPRINTF3(("REXECVE: e.linep is %s\n", e.linep));
+		DBGPRINTF3(("REXECVE: global_env.linep is %s\n", global_env.linep));
 
-		execve(e.linep, v, envp);
+		execve(global_env.linep, v, envp);
 
 		switch (errno) {
 		case ENOEXEC:
-			*v = e.linep;
+			*v = global_env.linep;
 			tp = *--v;
-			*v = e.linep;
+			*v = global_env.linep;
 			execve(DEFAULT_SHELL, v, envp);
 			*v = tp;
 			return "no Shell";
@@ -3149,7 +3145,7 @@
 		wdlist = 0;
 		iolist = 0;
 		pushio(argp, f);
-		e.iobase = e.iop;
+		global_env.iobase = global_env.iop;
 		yynerrs = 0;
 		failpt = rt;
 		if (setjmp(failpt) == 0 && yyparse() == 0)
@@ -3319,7 +3315,8 @@
 	char *cp;
 	int maltmp;
 
-	DBGPRINTF(("DODOT: enter, t=%p, tleft %p, tright %p, e.linep is %s\n", t, t->left, t->right, ((e.linep == NULL) ? "NULL" : e.linep)));
+	DBGPRINTF(("DODOT: enter, t=%p, tleft %p, tright %p, global_env.linep is %s\n",
+		t, t->left, t->right, ((global_env.linep == NULL) ? "NULL" : global_env.linep)));
 
 	cp = t->words[1];
 	if (cp == NULL) {
@@ -3330,25 +3327,26 @@
 
 	sp = any('/', cp) ? ":" : path->value;
 
-	DBGPRINTF(("DODOT: sp is %s,  e.linep is %s\n",
+	DBGPRINTF(("DODOT: sp is %s,  global_env.linep is %s\n",
 			   ((sp == NULL) ? "NULL" : sp),
-			   ((e.linep == NULL) ? "NULL" : e.linep)));
+			   ((global_env.linep == NULL) ? "NULL" : global_env.linep)));
 
 	while (*sp) {
-		tp = e.linep;
+		tp = global_env.linep;
 		while (*sp && (*tp = *sp++) != ':')
 			tp++;
-		if (tp != e.linep)
+		if (tp != global_env.linep)
 			*tp++ = '/';
 
 		for (i = 0; (*tp++ = cp[i++]) != '\0';);
 
 		/* Original code */
-		i = open(e.linep, O_RDONLY);
+		i = open(global_env.linep, O_RDONLY);
 		if (i >= 0) {
 			exstat = 0;
 			maltmp = remap(i);
-			DBGPRINTF(("DODOT: remap=%d, exstat=%d, e.iofd %d, i %d, e.linep is %s\n", maltmp, exstat, e.iofd, i, e.linep));
+			DBGPRINTF(("DODOT: remap=%d, exstat=%d, global_env.iofd %d, i %d, global_env.linep is %s\n",
+				maltmp, exstat, global_env.iofd, i, global_env.linep));
 
 			next(maltmp);		/* Basically a PUSHIO */
 
@@ -3391,7 +3389,7 @@
 		return 1;
 	}
 	for (wp = t->words + 1; *wp; wp++) {
-		for (cp = e.linep; !nl && cp < elinep - 1; cp++) {
+		for (cp = global_env.linep; !nl && cp < elinep - 1; cp++) {
 			nb = read(0, cp, sizeof(*cp));
 			if (nb != sizeof(*cp))
 				break;
@@ -3402,7 +3400,7 @@
 		*cp = '\0';
 		if (nb <= 0)
 			break;
-		setval(lookup(*wp), e.linep);
+		setval(lookup(*wp), global_env.linep);
 	}
 	return nb <= 0;
 }
@@ -3760,9 +3758,9 @@
 	errpt = ev;
 	if (newenv(setjmp(errpt)) == 0) {
 		PUSHIO(aword, cp, strchar);
-		e.iobase = e.iop;
+		global_env.iobase = global_env.iop;
 		while ((xp = blank(f)) && gflg == 0) {
-			e.linep = xp;
+			global_env.linep = xp;
 			xp = strsave(xp, areanum);
 			if ((f & DOGLOB) == 0) {
 				if (f & DOTRIM)
@@ -3811,7 +3809,7 @@
 
 	DBGPRINTF3(("BLANK: enter, f=%d\n", f));
 
-	sp = e.linep;
+	sp = global_env.linep;
 	scanequals = f & DOKEY;
 	foundequals = 0;
 
@@ -3819,9 +3817,9 @@
 	c = subgetc('"', foundequals);
 	switch (c) {
 	case 0:
-		if (sp == e.linep)
+		if (sp == global_env.linep)
 			return 0;
-		*e.linep++ = 0;
+		*global_env.linep++ = 0;
 		return sp;
 
 	default:
@@ -3839,7 +3837,7 @@
 				break;
 			if (c == '\'' || !any(c, "$`\""))
 				c |= QUOTE;
-			*e.linep++ = c;
+			*global_env.linep++ = c;
 		}
 		c = 0;
 	}
@@ -3864,9 +3862,9 @@
 			} else if (!isalnum(c) && c != '_')
 				scanequals = 0;
 		}
-		*e.linep++ = c;
+		*global_env.linep++ = c;
 	}
-	*e.linep++ = 0;
+	*global_env.linep++ = 0;
 	return sp;
 }
 
@@ -3885,13 +3883,13 @@
 		if (c == '`') {
 			if (grave(quoted) == 0)
 				return 0;
-			e.iop->task = XGRAVE;
+			global_env.iop->task = XGRAVE;
 			goto again;
 		}
 		if (c == '$') {
 			c = dollar(quoted);
 			if (c == 0) {
-				e.iop->task = XDOLL;
+				global_env.iop->task = XDOLL;
 				goto again;
 			}
 		}
@@ -3913,38 +3911,38 @@
 	DBGPRINTF3(("DOLLAR: enter, quoted=%d\n", quoted));
 
 	c = readc();
-	s = e.linep;
+	s = global_env.linep;
 	if (c != '{') {
-		*e.linep++ = c;
+		*global_env.linep++ = c;
 		if (isalpha(c) || c == '_') {
 			while ((c = readc()) != 0 && (isalnum(c) || c == '_'))
-				if (e.linep < elinep)
-					*e.linep++ = c;
+				if (global_env.linep < elinep)
+					*global_env.linep++ = c;
 			unget(c);
 		}
 		c = 0;
 	} else {
-		oiop = e.iop;
-		otask = e.iop->task;
+		oiop = global_env.iop;
+		otask = global_env.iop->task;
 
-		e.iop->task = XOTHER;
+		global_env.iop->task = XOTHER;
 		while ((c = subgetc('"', 0)) != 0 && c != '}' && c != '\n')
-			if (e.linep < elinep)
-				*e.linep++ = c;
-		if (oiop == e.iop)
-			e.iop->task = otask;
+			if (global_env.linep < elinep)
+				*global_env.linep++ = c;
+		if (oiop == global_env.iop)
+			global_env.iop->task = otask;
 		if (c != '}') {
 			err("unclosed ${");
 			gflg++;
 			return c;
 		}
 	}
-	if (e.linep >= elinep) {
+	if (global_env.linep >= elinep) {
 		err("string in ${} too long");
 		gflg++;
-		e.linep -= 10;
+		global_env.linep -= 10;
 	}
-	*e.linep = 0;
+	*global_env.linep = 0;
 	if (*s)
 		for (cp = s + 1; *cp; cp++)
 			if (any(*cp, "=-+?")) {
@@ -3956,7 +3954,7 @@
 		if (dolc > 1) {
 			/* currently this does not distinguish $* and $@ */
 			/* should check dollar */
-			e.linep = s;
+			global_env.linep = s;
 			PUSHIO(awordlist, dolv + 1, dolchar);
 			return 0;
 		} else {				/* trap the nasty ${=} */
@@ -3998,7 +3996,7 @@
 		err(s);
 		gflg++;
 	}
-	e.linep = s;
+	global_env.linep = s;
 	PUSHIO(aword, dolp, quoted ? qstrchar : strchar);
 	return 0;
 }
@@ -4028,7 +4026,7 @@
 	(void) &cp;
 #endif
 
-	for (cp = e.iop->argp->aword; *cp != '`'; cp++) {
+	for (cp = global_env.iop->argp->aword; *cp != '`'; cp++) {
 		if (*cp == 0) {
 			err("no closing `");
 			return 0;
@@ -4036,7 +4034,7 @@
 	}
 
 	/* string copy with dollar expansion */
-	src = e.iop->argp->aword;
+	src = global_env.iop->argp->aword;
 	dest = child_cmd;
 	count = 0;
 	ignore = 0;
@@ -4165,7 +4163,7 @@
 	}
 	if (i != 0) {
 		waitpid(i, NULL, 0);
-		e.iop->argp->aword = ++cp;
+		global_env.iop->argp->aword = ++cp;
 		close(pf[1]);
 		PUSHIO(afile, remap(pf[0]),
 			(int (*)(struct ioarg *)) ((quoted) ? qgravechar : gravechar));
@@ -4535,14 +4533,14 @@
 {
 	int c;
 
-	if (e.linep > elinep) {
+	if (global_env.linep > elinep) {
 		while ((c = readc()) != '\n' && c);
 		err("input line too long");
 		gflg++;
 		return c;
 	}
 	c = readc();
-	if ((ec != '\'') && (ec != '`') && (e.iop->task != XGRAVE)) {
+	if ((ec != '\'') && (ec != '`') && (global_env.iop->task != XGRAVE)) {
 		if (c == '\\') {
 			c = readc();
 			if (c == '\n' && ec != '\"')
@@ -4555,53 +4553,53 @@
 
 static void unget(int c)
 {
-	if (e.iop >= e.iobase)
-		e.iop->peekc = c;
+	if (global_env.iop >= global_env.iobase)
+		global_env.iop->peekc = c;
 }
 
 static int eofc(void)
 {
-	return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);
+	return global_env.iop < global_env.iobase || (global_env.iop->peekc == 0 && global_env.iop->prev == 0);
 }
 
 static int readc(void)
 {
 	int c;
 
-	RCPRINTF(("READC: e.iop %p, e.iobase %p\n", e.iop, e.iobase));
+	RCPRINTF(("READC: global_env.iop %p, global_env.iobase %p\n", global_env.iop, global_env.iobase));
 
-	for (; e.iop >= e.iobase; e.iop--) {
-		RCPRINTF(("READC: e.iop %p, peekc 0x%x\n", e.iop, e.iop->peekc));
-		c = e.iop->peekc;
+	for (; global_env.iop >= global_env.iobase; global_env.iop--) {
+		RCPRINTF(("READC: global_env.iop %p, peekc 0x%x\n", global_env.iop, global_env.iop->peekc));
+		c = global_env.iop->peekc;
 		if (c != '\0') {
-			e.iop->peekc = 0;
+			global_env.iop->peekc = 0;
 			return c;
 		}
-		if (e.iop->prev != 0) {
-			c = (*e.iop->iofn)(e.iop->argp, e.iop);
+		if (global_env.iop->prev != 0) {
+			c = (*global_env.iop->iofn)(global_env.iop->argp, global_env.iop);
 			if (c != '\0') {
 				if (c == -1) {
-					e.iop++;
+					global_env.iop++;
 					continue;
 				}
-				if (e.iop == iostack)
+				if (global_env.iop == iostack)
 					ioecho(c);
-				e.iop->prev = c;
-				return e.iop->prev;
+				global_env.iop->prev = c;
+				return global_env.iop->prev;
 			}
-			if (e.iop->task == XIO && e.iop->prev != '\n') {
-				e.iop->prev = 0;
-				if (e.iop == iostack)
+			if (global_env.iop->task == XIO && global_env.iop->prev != '\n') {
+				global_env.iop->prev = 0;
+				if (global_env.iop == iostack)
 					ioecho('\n');
 				return '\n';
 			}
 		}
-		if (e.iop->task == XIO) {
+		if (global_env.iop->task == XIO) {
 			if (multiline) {
-				e.iop->prev = 0;
-				return e.iop->prev;
+				global_env.iop->prev = 0;
+				return global_env.iop->prev;
 			}
-			if (interactive && e.iop == iostack + 1) {
+			if (interactive && global_env.iop == iostack + 1) {
 #if ENABLE_FEATURE_EDITING
 				current_prompt = prompt->value;
 #else
@@ -4611,8 +4609,8 @@
 		}
 	}							/* FOR */
 
-	if (e.iop >= iostack) {
-		RCPRINTF(("READC: return 0, e.iop %p\n", e.iop));
+	if (global_env.iop >= iostack) {
+		RCPRINTF(("READC: return 0, global_env.iop %p\n", global_env.iop));
 		return 0;
 	}
 
@@ -4632,12 +4630,12 @@
 
 static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *))
 {
-	DBGPRINTF(("PUSHIO: argp %p, argp->afid 0x%x, e.iop %p\n", argp,
-			   argp->afid, e.iop));
+	DBGPRINTF(("PUSHIO: argp %p, argp->afid 0x%x, global_env.iop %p\n", argp,
+			   argp->afid, global_env.iop));
 
 	/* Set env ptr for io source to next array spot and check for array overflow */
-	if (++e.iop >= &iostack[NPUSH]) {
-		e.iop--;
+	if (++global_env.iop >= &iostack[NPUSH]) {
+		global_env.iop--;
 		err("Shell input nested too deeply");
 		gflg++;
 		return;
@@ -4645,60 +4643,60 @@
 
 	/* We did not overflow the NPUSH array spots so setup data structs */
 
-	e.iop->iofn = (int (*)(struct ioarg *, struct io *)) fn;	/* Store data source func ptr */
+	global_env.iop->iofn = (int (*)(struct ioarg *, struct io *)) fn;	/* Store data source func ptr */
 
 	if (argp->afid != AFID_NOBUF)
-		e.iop->argp = argp;
+		global_env.iop->argp = argp;
 	else {
 
-		e.iop->argp = ioargstack + (e.iop - iostack);	/* MAL - index into stack */
-		*e.iop->argp = *argp;	/* copy data from temp area into stack spot */
+		global_env.iop->argp = ioargstack + (global_env.iop - iostack);	/* MAL - index into stack */
+		*global_env.iop->argp = *argp;	/* copy data from temp area into stack spot */
 
 		/* MAL - mainbuf is for 1st data source (command line?) and all nested use a single shared buffer? */
 
-		if (e.iop == &iostack[0])
-			e.iop->argp->afbuf = &mainbuf;
+		if (global_env.iop == &iostack[0])
+			global_env.iop->argp->afbuf = &mainbuf;
 		else
-			e.iop->argp->afbuf = &sharedbuf;
+			global_env.iop->argp->afbuf = &sharedbuf;
 
 		/* MAL - if not a termimal AND (commandline OR readable file) then give it a buffer id? */
 		/* This line appears to be active when running scripts from command line */
-		if ((isatty(e.iop->argp->afile) == 0)
-			&& (e.iop == &iostack[0]
-				|| lseek(e.iop->argp->afile, 0L, SEEK_CUR) != -1)) {
+		if ((isatty(global_env.iop->argp->afile) == 0)
+			&& (global_env.iop == &iostack[0]
+				|| lseek(global_env.iop->argp->afile, 0L, SEEK_CUR) != -1)) {
 			if (++bufid == AFID_NOBUF)	/* counter rollover check, AFID_NOBUF = 11111111  */
 				bufid = AFID_ID;	/* AFID_ID = 0 */
 
-			e.iop->argp->afid = bufid;	/* assign buffer id */
+			global_env.iop->argp->afid = bufid;	/* assign buffer id */
 		}
 
-		DBGPRINTF(("PUSHIO: iostack %p,  e.iop %p, afbuf %p\n",
-				   iostack, e.iop, e.iop->argp->afbuf));
-		DBGPRINTF(("PUSHIO: mbuf %p, sbuf %p, bid %d, e.iop %p\n",
-				   &mainbuf, &sharedbuf, bufid, e.iop));
+		DBGPRINTF(("PUSHIO: iostack %p,  global_env.iop %p, afbuf %p\n",
+				   iostack, global_env.iop, global_env.iop->argp->afbuf));
+		DBGPRINTF(("PUSHIO: mbuf %p, sbuf %p, bid %d, global_env.iop %p\n",
+				   &mainbuf, &sharedbuf, bufid, global_env.iop));
 
 	}
 
-	e.iop->prev = ~'\n';
-	e.iop->peekc = 0;
-	e.iop->xchar = 0;
-	e.iop->nlcount = 0;
+	global_env.iop->prev = ~'\n';
+	global_env.iop->peekc = 0;
+	global_env.iop->xchar = 0;
+	global_env.iop->nlcount = 0;
 
 	if (fn == filechar || fn == linechar)
-		e.iop->task = XIO;
+		global_env.iop->task = XIO;
 	else if (fn == (int (*)(struct ioarg *)) gravechar
 	 || fn == (int (*)(struct ioarg *)) qgravechar)
-		e.iop->task = XGRAVE;
+		global_env.iop->task = XGRAVE;
 	else
-		e.iop->task = XOTHER;
+		global_env.iop->task = XOTHER;
 }
 
 static struct io *setbase(struct io *ip)
 {
 	struct io *xp;
 
-	xp = e.iobase;
-	e.iobase = ip;
+	xp = global_env.iobase;
+	global_env.iobase = ip;
 	return xp;
 }
 
@@ -4929,9 +4927,9 @@
 	int map[NOFILE];
 	int newfd;
 
-	DBGPRINTF(("REMAP: fd=%d, e.iofd=%d\n", fd, e.iofd));
+	DBGPRINTF(("REMAP: fd=%d, global_env.iofd=%d\n", fd, global_env.iofd));
 
-	if (fd < e.iofd) {
+	if (fd < global_env.iofd) {
 		for (i = 0; i < NOFILE; i++)
 			map[i] = 0;
 
@@ -4939,7 +4937,7 @@
 			map[fd] = 1;
 			newfd = dup(fd);
 			fd = newfd;
-		} while (fd >= 0 && fd < e.iofd);
+		} while (fd >= 0 && fd < global_env.iofd);
 
 		for (i = 0; i < NOFILE; i++)
 			if (map[i])
@@ -5052,10 +5050,10 @@
 	if (newenv(setjmp(errpt)) != 0)
 		unlink(tname);
 	else {
-		pushio(e.iop->argp, (int (*)(struct ioarg *)) e.iop->iofn);
-		e.iobase = e.iop;
+		pushio(global_env.iop->argp, (int (*)(struct ioarg *)) global_env.iop->iofn);
+		global_env.iobase = global_env.iop;
 		for (;;) {
-			if (interactive && e.iop <= iostack) {
+			if (interactive && global_env.iop <= iostack) {
 #if ENABLE_FEATURE_EDITING
 				current_prompt = cprompt->value;
 #else
@@ -5121,7 +5119,7 @@
 		errpt = ev;
 		if (newenv(setjmp(errpt)) == 0) {
 			PUSHIO(afile, hf, herechar);
-			setbase(e.iop);
+			setbase(global_env.iop);
 			while ((c = subgetc(0, 0)) != 0) {
 				c &= ~QUOTE;
 				write(tf, &c, sizeof c);
@@ -5189,7 +5187,6 @@
 
 	sharedbuf.id = AFID_NOBUF;
 	mainbuf.id = AFID_NOBUF;
-	e.linep = line;
 	elinep = line + sizeof(line) - 5;
 
 #if ENABLE_FEATURE_EDITING
@@ -5321,7 +5318,7 @@
 	setdash();
 
 	/* This won't be true if PUSHIO has been called, say from newfile() above */
-	if (e.iop < iostack) {
+	if (global_env.iop < iostack) {
 		PUSHIO(afile, 0, iof);
 		if (isatty(0) && isatty(1) && !cflag) {
 			interactive++;
@@ -5366,10 +5363,10 @@
 	}
 	setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc));
 
-	DBGPRINTF(("MSH_MAIN: begin FOR loop, interactive %d, e.iop %p, iostack %p\n", interactive, e.iop, iostack));
+	DBGPRINTF(("MSH_MAIN: begin FOR loop, interactive %d, global_env.iop %p, iostack %p\n", interactive, global_env.iop, iostack));
 
 	for (;;) {
-		if (interactive && e.iop <= iostack) {
+		if (interactive && global_env.iop <= iostack) {
 #if ENABLE_FEATURE_EDITING
 			current_prompt = prompt->value;
 #else