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
This commit is contained in:
Denis Vlasenko 2007-12-16 17:21:29 +00:00
parent 0163111325
commit c794c51a1a

View File

@ -202,24 +202,24 @@ struct op {
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 @@ struct brkcon {
};
/*
* 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 yyparse(void);
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 @@ struct io {
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 @@ static const char *const signame[] = {
};
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 struct region *areanxt; /* starting point of scan */
static void *brktop;
static void *brkaddr;
#define AFID_NOBUF (~0)
#define AFID_ID 0
/*
* parsing & execution environment
*/
@ -716,44 +661,68 @@ struct env {
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 @@ static void err(const char *s)
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 @@ static void onecommand(void)
DBGPRINTF(("ONECOMMAND: enter, outtree=%p\n", outtree));
while (e.oenv)
while (global_env.oenv)
quitenv();
areanum = 1;
@ -1373,8 +1342,8 @@ static void onecommand(void)
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 @@ static void onecommand(void)
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 @@ static int newenv(int f)
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 @@ static void quitenv(void)
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) ATTRIBUTE_NORETURN;
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 @@ static struct op *block(int type, struct op *t1, struct op *t2, char **wp)
/* 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 @@ static int yylex(int cf)
atstart = startl;
startl = 0;
yylval.i = 0;
e.linep = line;
global_env.linep = line;
/* MALAMO */
line[LINELIM - 1] = '\0';
@ -2212,7 +2208,7 @@ static int yylex(int cf)
iounit = c - '0';
goto loop;
}
*e.linep++ = c;
*global_env.linep++ = c;
c = c1;
}
break;
@ -2228,7 +2224,7 @@ static int yylex(int cf)
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 @@ static int yylex(int cf)
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 @@ static int yylex(int cf)
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 @@ static int yylex(int cf)
if (any(c, "\"'`$"))
goto loop;
*e.linep++ = '\0';
*global_env.linep++ = '\0';
if (atstart) {
c = rlookup(line);
@ -2323,7 +2319,7 @@ static int collect(int c, int c1)
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 @@ static int collect(int c, int c1)
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 @@ static const char *rexecve(char *c, char **v, char **envp)
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 @@ static const char *rexecve(char *c, char **v, char **envp)
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 @@ static int run(struct ioarg *argp, int (*f) (struct ioarg *))
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 @@ static int dodot(struct op *t)
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 @@ static int dodot(struct op *t)
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 @@ static int doread(struct op *t)
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 @@ static int doread(struct op *t)
*cp = '\0';
if (nb <= 0)
break;
setval(lookup(*wp), e.linep);
setval(lookup(*wp), global_env.linep);
}
return nb <= 0;
}
@ -3760,9 +3758,9 @@ static int expand(const char *cp, struct wdblock **wbp, int f)
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 @@ static char *blank(int f)
DBGPRINTF3(("BLANK: enter, f=%d\n", f));
sp = e.linep;
sp = global_env.linep;
scanequals = f & DOKEY;
foundequals = 0;
@ -3819,9 +3817,9 @@ static char *blank(int f)
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 @@ static char *blank(int f)
break;
if (c == '\'' || !any(c, "$`\""))
c |= QUOTE;
*e.linep++ = c;
*global_env.linep++ = c;
}
c = 0;
}
@ -3864,9 +3862,9 @@ static char *blank(int f)
} 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 @@ static int subgetc(char ec, int quoted)
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 @@ static int dollar(int quoted)
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 @@ static int dollar(int quoted)
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 @@ static int dollar(int quoted)
err(s);
gflg++;
}
e.linep = s;
global_env.linep = s;
PUSHIO(aword, dolp, quoted ? qstrchar : strchar);
return 0;
}
@ -4028,7 +4026,7 @@ static int grave(int quoted)
(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 @@ static int grave(int quoted)
}
/* 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 @@ static int grave(int quoted)
}
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 @@ static int my_getc(int ec)
{
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 int my_getc(int ec)
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 @@ static int readc(void)
}
} /* 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 ioecho(char c)
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 @@ static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *))
/* 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 @@ static int remap(int fd)
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 @@ static int remap(int fd)
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 @@ static void readhere(char **name, char *s, int ec)
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 @@ static int herein(char *hname, int xdoll)
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 @@ int msh_main(int argc, char **argv)
sharedbuf.id = AFID_NOBUF;
mainbuf.id = AFID_NOBUF;
e.linep = line;
elinep = line + sizeof(line) - 5;
#if ENABLE_FEATURE_EDITING
@ -5321,7 +5318,7 @@ int msh_main(int argc, char **argv)
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 @@ int msh_main(int argc, char **argv)
}
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