[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [BusyBox] Msh.c broken when sourcing files within a compound
From:       Michael Leibow <MichaelLe () belkin ! com>
Date:       2004-06-29 14:53:17
Message-ID: 006B22B846854640942D08F78855FCE18160DE () addison ! belkin ! com
[Download RAW message or body]

A question was posted a month ago by Mark Alamo to see if others had
problems with sourcing subscripts within msh.  We asked his firm to fix the
msh.c bug he described because we didn't have enough time to do it
ourselves.

When msh.c is executing a compound statement and there is a . command to
source another script file, msh.c will not execute the subscript until it's
completed executing the rest of the compound statement.

His example was this:

Echo "Start" ; . ./subA; echo "mid" ; . ./subB ; echo "end"

subA and subB execute AFTER end is printed in reverse order.  The same is
true if the sourced files are inside an if else fi, case esac, or any
compound statement.

Attached is a patch to msh.c.  It fixes the problem.  Cd to the root of your
busybox tree and execute "patch -p1 < msh.c.patch"

Unfortunately, I won't have more time to work on this so I hope that there
aren't any problems!

Michael Leibow
Senior Software Engineer

Belkin Corporation
Research & Development Labs
585 324-7815
www.belkin.com



["msh.c.patch" (application/octet-stream)]

--- busybox.orig/shell/msh.c	2004-04-14 17:51:32.000000000 +0000
+++ busybox/shell/msh.c	2004-06-28 17:22:31.000000000 +0000
@@ -49,24 +49,66 @@
 #include "busybox.h"
 
 
+/* Conditional use of "register" keyword */
+#define REGISTER register
+
+
+/*#define MSHDEBUG 1*/
+
+#ifdef MSHDEBUG
+int mshdbg=0;
+#define DBGPRINTF(x)	if(mshdbg>0)printf x
+#define DBGPRINTF0(x)	if(mshdbg>0)printf x
+#define DBGPRINTF1(x)	if(mshdbg>1)printf x
+#define DBGPRINTF2(x)	if(mshdbg>2)printf x
+#define DBGPRINTF3(x)	if(mshdbg>3)printf x
+#define DBGPRINTF4(x)	if(mshdbg>4)printf x
+#define DBGPRINTF5(x)	if(mshdbg>5)printf x
+#define DBGPRINTF6(x)	if(mshdbg>6)printf x
+#define DBGPRINTF7(x)	if(mshdbg>7)printf x
+#define DBGPRINTF8(x)	if(mshdbg>8)printf x
+#define DBGPRINTF9(x)	if(mshdbg>9)printf x
+
+int mshdbg_rc=0;
+#define RCPRINTF(x)		if(mshdbg_rc)printf x
+
+#else
+
+#define DBGPRINTF(x)
+#define DBGPRINTF0(x)
+#define DBGPRINTF1(x)
+#define DBGPRINTF2(x)
+#define DBGPRINTF3(x)
+#define DBGPRINTF4(x)
+#define DBGPRINTF5(x)
+#define DBGPRINTF6(x)
+#define DBGPRINTF7(x)
+#define DBGPRINTF8(x)
+#define DBGPRINTF9(x)
+
+#define RCPRINTF(x)
+
+#endif  /* MSHDEBUG */
+
+
 /* -------- sh.h -------- */
 /*
  * shell
  */
 
-#define	LINELIM	2100
-#define	NPUSH	8	/* limit to input nesting */
+#define	LINELIM	  2100
+#define	NPUSH	  8		/* limit to input nesting */
 
 #undef NOFILE
-#define	NOFILE	20	/* Number of open files */
-#define	NUFILE	10	/* Number of user-accessible files */
-#define	FDBASE	10	/* First file usable by Shell */
+#define	NOFILE	  20	/* Number of open files */
+#define	NUFILE	  10	/* Number of user-accessible files */
+#define	FDBASE	  10	/* First file usable by Shell */
 
 /*
  * values returned by wait
  */
-#define	WAITSIG(s) ((s)&0177)
-#define	WAITVAL(s) (((s)>>8)&0377)
+#define	WAITSIG(s)  ((s)&0177)
+#define	WAITVAL(s)  (((s)>>8)&0377)
 #define	WAITCORE(s) (((s)&0200)!=0)
 
 /*
@@ -90,7 +132,7 @@
  * Might eventually use a union.
  */
 struct op {
-	int	type;	/* operation type, see below */
+	int		type;	/* operation type, see below */
 	char	**words;	/* arguments to a command */
 	struct	ioword	**ioact;	/* IO actions (eg, < > >>) */
 	struct op *left;
@@ -102,18 +144,43 @@
 #define	TPAREN	2	/* (c-list) */
 #define	TPIPE	3	/* a | b */
 #define	TLIST	4	/* a [&;] b */
-#define	TOR	5	/* || */
+#define	TOR		5	/* || */
 #define	TAND	6	/* && */
 #define	TFOR	7
-#define	TDO	8
+#define	TDO		8
 #define	TCASE	9
-#define	TIF	10
+#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
+
+/* Strings for names to make debug easier */
+char * T_CMD_NAMES[]={
+	"PLACEHOLDER",
+	"TCOM",
+	"TPAREN",
+	"TPIPE",
+	"TLIST",
+	"TOR",
+	"TAND",
+	"TFOR",
+	"TDO",
+	"TCASE",
+	"TIF",
+	"TWHILE",
+	"TUNTIL",
+	"TELIF",
+	"TPAT",
+	"TBRACE",
+	"TASYNC",
+	"TDOT",
+};
+
 
 /*
  * actions determining the environment of a process
@@ -121,35 +188,30 @@
 #define	BIT(i)	(1<<(i))
 #define	FEXEC	BIT(0)	/* execute without forking */
 
+#if 0  /* Original value */
+#define AREASIZE	(65000)
+#else
+#define AREASIZE	(90000)
+#endif
+
 /*
  * flags to control evaluation of words
  */
-#define	DOSUB	1	/* interpret $, `, and quotes */
-#define	DOBLANK	2	/* perform blank interpretation */
-#define	DOGLOB	4	/* interpret [?* */
-#define	DOKEY	8	/* move words with `=' to 2nd arg. list */
-#define	DOTRIM	16	/* trim resulting string */
+#define	DOSUB	 1	/* interpret $, `, and quotes */
+#define	DOBLANK	 2	/* perform blank interpretation */
+#define	DOGLOB	 4	/* interpret [?* */
+#define	DOKEY	 8	/* move words with `=' to 2nd arg. list */
+#define	DOTRIM	 16	/* trim resulting string */
 
 #define	DOALL	(DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM)
 
-static	char	**dolv;
-static	int	dolc;
-static	int	exstat;
-static  char	gflg;
-static  int	interactive;	/* Is this an interactive shell */
-static  int	execflg;
-static  int	multiline;	/* \n changed to ; */
-static  struct	op	*outtree;	/* result from parser */
-
-static	xint	*failpt;
-static	xint	*errpt;
-static	struct brkcon	*brklist;
-static	int	isbreak;
-static int newfile(char *s);
+
+/* PROTOTYPES */
+static int 	newfile(char *s);
 static char *findeq(char *cp);
 static char *cclass(char *p, int sub);
 static void initarea(void);
-extern int msh_main(int argc, char **argv);
+extern int 	msh_main(int argc, char **argv);
 
 
 struct	brkcon {
@@ -157,6 +219,7 @@
 	struct	brkcon	*nextlev;
 } ;
 
+
 /*
  * redirection
  */
@@ -165,18 +228,17 @@
 	short	io_flag;	/* action (below) */
 	char	*io_name;	/* file name */
 };
-#define	IOREAD	1	/* < */
-#define	IOHERE	2	/* << (here file) */
-#define	IOWRITE	4	/* > */
-#define	IOCAT	8	/* >> */
-#define	IOXHERE	16	/* ${}, ` in << */
-#define	IODUP	32	/* >&digit */
-#define	IOCLOSE	64	/* >&- */
+#define	IOREAD	 1		/* < */
+#define	IOHERE	 2		/* << (here file) */
+#define	IOWRITE	 4		/* > */
+#define	IOCAT	 8		/* >> */
+#define	IOXHERE	 16		/* ${}, ` in << */
+#define	IODUP	 32		/* >&digit */
+#define	IOCLOSE	 64		/* >&- */
 
 #define	IODEFAULT (-1)	/* token for default IO unit */
 
-static	struct	wdblock	*wdlist;
-static	struct	wdblock	*iolist;
+
 
 /*
  * parsing & execution environment
@@ -185,8 +247,8 @@
 	char	*linep;
 	struct	io	*iobase;
 	struct	io	*iop;
-	xint	*errpt;
-	int	iofd;
+	xint	*errpt;  /* void * */
+	int	iofd; 
 	struct	env	*oenv;
 } e;
 
@@ -203,25 +265,25 @@
 static	char	*flag;
 
 static	char	*null;	/* null value for variable */
-static	int	intr;	/* interrupt pending */
+static	int		intr;	/* interrupt pending */
 
 static	char	*trap[_NSIG+1];
 static	char	ourtrap[_NSIG+1];
-static	int	trapset;	/* trap pending */
+static	int		trapset;	/* trap pending */
 
-static	int	heedint;	/* heed interrupt signals */
+static	int		heedint;	/* heed interrupt signals */
 
-static	int	yynerrs;	/* yacc */
+static	int		yynerrs;	/* yacc */
 
 static	char	line[LINELIM];
 static	char	*elinep;
 
+
 /*
  * other functions
  */
 static int(*inbuilt(char *s))(struct op *);
 
-
 static char *rexecve (char *c , char **v, char **envp );
 static char *space (int n );
 static char *strsave (char *s, int a );
@@ -234,7 +296,7 @@
 static struct wdblock *glob (char *cp, struct wdblock *wb );
 static int my_getc( int ec);
 static int subgetc (int ec, int quoted );
-static char **makenv (void);
+static char **makenv(int all);
 static char **eval (char **ap, int f );
 static int setstatus (int s );
 static int waitfor (int lastpid, int canintr );
@@ -252,6 +314,7 @@
 static void runtrap (int i );
 static int gmatch (char *s, char *p );
 
+
 /*
  * error handling
  */
@@ -264,13 +327,13 @@
 
 /* -------- area stuff -------- */
 
-#define	REGSIZE		sizeof(struct region)
-#define GROWBY		256
-//#define	SHRINKBY   64
+#define	REGSIZE	  sizeof(struct region)
+#define GROWBY	  (256)
+/* #define	SHRINKBY   (64) */
 #undef	SHRINKBY
-#define FREE 32767
-#define BUSY 0
-#define	ALIGN (sizeof(int)-1)
+#define FREE 	  (32767)
+#define BUSY 	  (0)
+#define	ALIGN 	  (sizeof(int)-1)
 
 
 struct region {
@@ -291,25 +354,29 @@
 #define	LOGAND	257
 #define	LOGOR	258
 #define	BREAK	259
-#define	IF	260
+#define	IF		260
 #define	THEN	261
 #define	ELSE	262
 #define	ELIF	263
-#define	FI	264
+#define	FI		264
 #define	CASE	265
 #define	ESAC	266
-#define	FOR	267
+#define	FOR		267
 #define	WHILE	268
 #define	UNTIL	269
-#define	DO	270
+#define	DO		270
 #define	DONE	271
-#define	IN	272
+#define	IN		272
+/* Added for "." file expansion */
+#define	DOT		273
+
 #define	YYERRCODE 300
 
 /* flags to yylex */
 #define	CONTIN	01	/* skip new lines to complete command */
 
 #define	SYNTAXERR	zzerr()
+
 static struct op *pipeline(int cf );
 static struct op *andor(void);
 static struct op *c_list(void);
@@ -354,15 +421,6 @@
 #define	EXPORT	02	/* variable is to be exported */
 #define	GETCELL	04	/* name & value space was got with getcell */
 
-static	struct	var	*vlist;		/* dictionary */
-
-static	struct	var	*homedir;	/* home directory */
-static	struct	var	*prompt;	/* main prompt */
-static	struct	var	*cprompt;	/* continuation prompt */
-static	struct	var	*path;		/* search path for commands */
-static	struct	var	*shell;		/* shell to interpret command files */
-static	struct	var	*ifs;		/* field separators */
-
 static int yyparse (void);
 static struct var *lookup (char *n );
 static void setval (struct var *vp, char *val );
@@ -377,20 +435,21 @@
 
 static int execute (struct op *t, int *pin, int *pout, int act );
 
+
 /* -------- io.h -------- */
 /* io buffer */
 struct iobuf {
-  unsigned id;				/* buffer id */
-  char buf[512];			/* buffer */
-  char *bufp;				/* pointer into buffer */
-  char *ebufp;				/* pointer to end of buffer */
+	unsigned id;				/* buffer id */
+	char buf[512];			/* buffer */
+	char *bufp;				/* pointer into buffer */
+	char *ebufp;				/* pointer to end of buffer */
 };
 
 /* possible arguments to an IO function */
 struct ioarg {
 	char	*aword;
 	char	**awordlist;
-	int	afile;		/* file descriptor */
+	int		afile;		/* file descriptor */
 	unsigned afid;		/* buffer id */
 	long	afpos;		/* file position */
 	struct iobuf *afbuf;	/* buffer for this file */
@@ -403,7 +462,7 @@
 struct	io {
 	int	(*iofn)(struct  ioarg *, struct io *);
 	struct	ioarg	*argp;
-	int	peekc;
+	int		peekc;
 	char	prev;		/* previous character read by readc() */
 	char	nlcount;	/* for `'s */
 	char	xchar;		/* for `'s */
@@ -413,11 +472,12 @@
 #define	XOTHER	0	/* none of the below */
 #define	XDOLL	1	/* expanding ${} */
 #define	XGRAVE	2	/* expanding `'s */
-#define	XIO	3	/* file IO */
+#define	XIO	3		/* file IO */
 
 /* in substitution */
 #define	INSUB()	(e.iop->task == XGRAVE || e.iop->task == XDOLL)
 
+
 /*
  * input generators for IO structure
  */
@@ -438,6 +498,7 @@
 static int herein (char *hname, int xdoll );
 static int run (struct ioarg *argp, int (*f)(struct ioarg *));
 
+
 /*
  * IO functions
  */
@@ -450,6 +511,7 @@
 static void closef (int i );
 static void closeall (void);
 
+
 /*
  * IO control
  */
@@ -459,7 +521,6 @@
 static void closepipe (int *pv );
 static struct io *setbase (struct io *ip );
 
-static	struct	ioarg	temparg;	/* temporary for PUSHIO */
 #define	PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen)))
 #define	RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
 
@@ -486,18 +547,18 @@
 static char *getcell (unsigned nbytes );
 static void garbage (void);
 static void setarea (char *cp, int a );
-static int getarea (char *cp );
+static int  getarea (char *cp );
 static void freearea (int a );
 static void freecell (char *cp );
-static	int	areanum;	/* current allocation area */
+static int	areanum;	/* current allocation area */
 
-#define	NEW(type) (type *)getcell(sizeof(type))
+#define	NEW(type)   (type *)getcell(sizeof(type))
 #define	DELETE(obj)	freecell((char *)obj)
 
 
 /* -------- misc stuff -------- */
 
-static int forkexec (struct op *t, int *pin, int *pout, int act, char **wp, int \
*pforked ); +static int forkexec (struct op *t, int *pin, int *pout, int act, char \
**wp);  static int iosetup (struct ioword *iop, int pipein, int pipeout );
 static void echo(char **wp );
 static struct op **find1case (struct op *t, char *w );
@@ -573,7 +634,7 @@
 #define	NSIGNAL (sizeof(signame)/sizeof(signame[0]))
 
 struct res {
-	char *r_name;
+	char  *r_name;
 	int	  r_val;
 };
 static struct res restab[] = {
@@ -590,13 +651,13 @@
     {"elif",	ELIF},
     {"until",	UNTIL},
     {"fi",		FI},
-
     {";;",		BREAK},
     {"||",		LOGOR},
     {"&&",		LOGAND},
     {"{",		'{'},
     {"}",		'}'},
-    {0,		0},
+    {".",		DOT},
+    {0,	0},
 };
 
 
@@ -625,66 +686,116 @@
     {"trap",	dotrap},
     {"umask",	doumask},
     {"wait",	dowait},
-    {0,0}
+    {0, 0}
 };
 
+static int expand_dotnode(struct op*);
+struct op* scantree(struct op*);
+static struct op * dowholefile(int, int);
+
 /* Globals */
-extern	char	**environ;	/* environment pointer */
+extern char	**environ;	/* environment pointer */
+
 static char	**dolv;
 static int	dolc;
 static int	exstat;
 static char	gflg;
-static int	interactive;	/* Is this an interactive shell */
+static int	interactive = 0;	/* Is this an interactive shell */
 static int	execflg;
 static int	multiline;	/* \n changed to ; */
-static struct	op	*outtree;	/* result from parser */
+static struct op	*outtree;	/* result from parser */
 static xint	*failpt;
 static xint	*errpt;
-static struct	brkcon	*brklist;
+static struct brkcon	*brklist;
 static int	isbreak;
-static struct	wdblock	*wdlist;
-static struct	wdblock	*iolist;
+static struct wdblock	*wdlist;
+static struct wdblock	*iolist;
 static char	*trap[_NSIG+1];
 static char	ourtrap[_NSIG+1];
 static int	trapset;	/* trap pending */
 static int	yynerrs;	/* yacc */
 static char	line[LINELIM];
-static struct	var	*vlist;		/* dictionary */
-static struct	var	*homedir;	/* home directory */
-static struct	var	*prompt;	/* main prompt */
-static struct	var	*cprompt;	/* continuation prompt */
-static struct	var	*path;		/* search path for commands */
-static struct	var	*shell;		/* shell to interpret command files */
-static struct	var	*ifs;		/* field separators */
-static struct	ioarg ioargstack[NPUSH];
-static struct	io	iostack[NPUSH];
+#ifdef MSHDEBUG
+static struct var	*mshdbg_var;
+#endif
+static struct var	*vlist;		/* dictionary */
+static struct var	*homedir;	/* home directory */
+static struct var	*prompt;	/* main prompt */
+static struct var	*cprompt;	/* continuation prompt */
+static struct var	*path;		/* search path for commands */
+static struct var	*shell;		/* shell to interpret command files */
+static struct var	*ifs;		/* field separators */
+
 static int	areanum;	/* current allocation area */
 static int	intr;
 static int	inparse;
 static char	flags['z'-'a'+1];
 static char	*flag = flags-'a';
-static char	*elinep = line+sizeof(line)-5;
 static char	*null	= "";
 static int	heedint =1;
-static struct env e ={line, iostack, iostack-1, (xint *)NULL, FDBASE, (struct env \
*)NULL};  static void (*qflag)(int) = SIG_IGN;
-static	int	startl;
-static	int	peeksym;
-static	int	nlseen;
-static	int	iounit = IODEFAULT;
-static	YYSTYPE	yylval;
-static struct iobuf sharedbuf = {AFID_NOBUF};
-static struct iobuf mainbuf = {AFID_NOBUF};
-static unsigned bufid = AFID_ID;	/* buffer id counter */
-static struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};
-static	struct here *inhere;		/* list of hear docs while parsing */
-static	struct here *acthere;		/* list of active here documents */
-static	struct region *areabot;		/* bottom of area */
-static	struct region *areatop;		/* top of area */
-static	struct region *areanxt;		/* starting point of scan */
+static int	startl;
+static int	peeksym;
+static int	nlseen;
+static int	iounit = IODEFAULT;
+static YYSTYPE	yylval;
+static char	*elinep = line+sizeof(line)-5;
+
+static struct ioarg  temparg = {0, 0, 0, AFID_NOBUF, 0};  /* temporary for PUSHIO */
+static struct ioarg  ioargstack[NPUSH];
+static struct io	 iostack[NPUSH];
+static struct iobuf  sharedbuf = {AFID_NOBUF};
+static struct iobuf  mainbuf = {AFID_NOBUF};
+static unsigned      bufid = AFID_ID;	/* buffer id counter */
+
+static struct here    *inhere;		/* list of hear docs while parsing */
+static struct here    *acthere;		/* list of active here documents */
+static struct region  *areabot;		/* bottom of area */
+static struct region  *areatop;		/* top of area */
+static struct region  *areanxt;		/* starting point of scan */
 static void * brktop;
 static void * brkaddr;
 
+static struct env e ={ 
+	line, 		/* 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 */
+};
+
+#ifdef MSHDEBUG
+void print_t(struct op *t)
+{
+	DBGPRINTF(("T: t=0x%x, type %s, words=0x%x, IOword=0x%x\n", t, \
T_CMD_NAMES[t->type], t->words, t->ioact)); +
+	if (t->words) {
+		DBGPRINTF(("T: W1: %s", t->words[0]));
+	}
+
+	return;
+}
+
+void print_tree(struct op *head)
+{
+	if (head == NULL) {
+		DBGPRINTF(("PRINT_TREE: no tree\n"));
+		return;
+	}
+
+	DBGPRINTF(("NODE: 0x%x,  left 0x%x, right 0x%x\n", head, head->left, head->right));
+
+	if (head->left)
+		print_tree(head->left);
+
+	if (head->right)
+		print_tree(head->right);
+
+	return;	
+}
+#endif  /* MSHDEBUG */
+
 
 #ifdef CONFIG_FEATURE_COMMAND_EDITING
 static char * current_prompt;
@@ -698,12 +809,14 @@
 
 extern int msh_main(int argc, char **argv)
 {
-	register int f;
-	register char *s;
+	REGISTER int f;
+	REGISTER char *s;
 	int cflag;
 	char *name, **ap;
 	int (*iof)(struct ioarg *);
 
+	DBGPRINTF(("MSH_MAIN: argc %d, environ 0x%x\n", argc, environ));
+
 	initarea();
 	if ((ap = environ) != NULL) {
 		while (*ap)
@@ -739,6 +852,13 @@
 	if (ifs->value == null)
 		setval(ifs, " \t\n");
 
+#ifdef MSHDEBUG
+	mshdbg_var = lookup("MSHDEBUG");
+	if (mshdbg_var->value == null)
+		setval(mshdbg_var, "0");
+#endif
+
+
 	prompt = lookup("PS1");
 #ifdef CONFIG_FEATURE_SH_FANCY_PROMPT
 	if (prompt->value == null)
@@ -795,26 +915,44 @@
 			argv--;
 			argc++;
 		}
+
 		if (iof == filechar && --argc > 0) {
 			setval(prompt, "");
 			setval(cprompt, "");
 			prompt->status &= ~EXPORT;
 			cprompt->status &= ~EXPORT;
+
+/* Shell is non-interactive, activate printf-based debug */
+#ifdef MSHDEBUG
+mshdbg = (int)(((char)(mshdbg_var->value[0])) - '0');
+if (mshdbg < 0)
+	mshdbg = 0;
+#endif
+			DBGPRINTF(("MSH_MAIN: calling newfile()\n"));
+
 			if (newfile(name = *++argv))
-				exit(1);
+				exit(1);	/* Exit on error */
 		}
 	}
+
 	setdash();
+
+	/* This won't be true if PUSHIO has been called, say from newfile() above */
 	if (e.iop < iostack) {
 		PUSHIO(afile, 0, iof);
 		if (isatty(0) && isatty(1) && !cflag) {
 			interactive++;
 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
+#ifdef MSHDEBUG
+			printf( "\n\n" BB_BANNER " Built-in shell (msh with debug)\n");
+#else
 			printf( "\n\n" BB_BANNER " Built-in shell (msh)\n");
+#endif
 			printf( "Enter 'help' for a list of built-in commands.\n\n");
 #endif
 		}
 	}
+
 	signal(SIGQUIT, qflag);
 	if (name && name[0] == '-') {
 		interactive++;
@@ -825,6 +963,7 @@
 	}
 	if (interactive)
 		signal(SIGTERM, sig);
+
 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
 		signal(SIGINT, onintr);
 	dolv = argv;
@@ -841,6 +980,8 @@
 	}
 	setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc));
 
+	DBGPRINTF(("MSH_MAIN: begin FOR loop, interactive %d, e.iop 0x%x, iostack 0x%x\n", \
interactive, e.iop, iostack)); +
 	for (;;) {
 		if (interactive && e.iop <= iostack) {
 #ifdef CONFIG_FEATURE_COMMAND_EDITING
@@ -853,13 +994,15 @@
 		/* Ensure that getenv("PATH") stays current */
 		setenv("PATH", path->value, 1);
 	}
+
+	DBGPRINTF(("MSH_MAIN: returning.\n"));
 }
 
 static void
 setdash()
 {
-	register char *cp;
-	register int c;
+	REGISTER char *cp;
+	REGISTER int c;
 	char m['z'-'a'+1];
 
 	cp = m;
@@ -872,11 +1015,14 @@
 
 static int
 newfile(s)
-register char *s;
+REGISTER char *s;
 {
-	register int f;
+	REGISTER int f;
+
+	DBGPRINTF7(("NEWFILE: opening %s\n", s));
 
 	if (strcmp(s, "-") != 0) {
+		DBGPRINTF(("NEWFILE: s is %s\n", s));
 		f = open(s, 0);
 		if (f < 0) {
 			prs(s);
@@ -885,18 +1031,76 @@
 		}
 	} else
 		f = 0;
+
 	next(remap(f));
 	return(0);
 }
 
+
+static int
+expand_dotnode(node)
+struct op	*node;
+{
+	struct op	*outtree_save=outtree;
+
+	node->type = TDOT;
+	newfile(node->words[1]);
+
+	node->left = dowholefile(TDOT, 0);
+
+	node->right = NULL;
+
+	outtree = outtree_save;
+
+	return (1);
+}
+
+struct op*
+scantree(head)
+struct op	*head;
+{
+	struct op	*dotnode;
+
+	if (head == NULL)
+		return (NULL);
+
+	if (head->left != NULL) {
+		dotnode = scantree(head->left);
+		if (dotnode)
+			return (dotnode);
+	}
+
+	if (head->right != NULL) {
+		dotnode = scantree(head->right);
+		if (dotnode)
+			return (dotnode);
+	}
+
+	if (head->words == NULL)
+		return (NULL);
+
+	DBGPRINTF5(("SCANTREE: checking node 0x%x\n", head));
+
+	if ((head->type != TDOT) && (strcmp(".", head->words[0]) == 0)) {
+		DBGPRINTF5(("SCANTREE: dot found in node 0x%x\n", head));
+		return (head);
+	}
+
+	return (NULL);	
+}
+
+
 static void
 onecommand()
 {
-	register int i;
+	REGISTER int i;
 	jmp_buf m1;
 
+	DBGPRINTF(("ONECOMMAND: enter, outtree=0x%x\n", outtree));
+
 	while (e.oenv)
 		quitenv();
+
 	areanum = 1;
 	freehere(areanum);
 	freearea(areanum);
@@ -910,8 +1114,12 @@
 	inparse = 1;
 	intr = 0;
 	execflg = 0;
+
 	setjmp(failpt = m1);	/* Bruce Evans' fix */
 	if (setjmp(failpt = m1) || yyparse() || intr) {
+
+		DBGPRINTF(("ONECOMMAND: this is not good.\n"));
+
 		while (e.oenv)
 			quitenv();
 		scraphere();
@@ -921,16 +1129,22 @@
 		intr = 0;
 		return;
 	}
+
 	inparse = 0;
 	brklist = 0;
 	intr = 0;
 	execflg = 0;
-	if (!flag['n'])
+
+	if (!flag['n']) {
+		DBGPRINTF(("ONECOMMAND: calling execute, t=outtree=0x%x\n", outtree));
 		execute(outtree, NOPIPE, NOPIPE, 0);
+	}
+
 	if (!interactive && intr) {
 		execflg = 0;
 		leave();
 	}
+
 	if ((i = trapset) != 0) {
 		trapset = 0;
 		runtrap(i);
@@ -947,18 +1161,20 @@
 static void
 leave()
 {
+	DBGPRINTF(("LEAVE: leave called!\n"));
+
 	if (execflg)
 		fail();
 	scraphere();
 	freehere(1);
 	runtrap(0);
-	exit(exstat);
+	_exit(exstat);
 	/* NOTREACHED */
 }
 
 static void
 warn(s)
-register char *s;
+REGISTER char *s;
 {
 	if(*s) {
 		prs(s);
@@ -988,12 +1204,15 @@
 newenv(f)
 int f;
 {
-	register struct env *ep;
+	REGISTER struct env *ep;
+
+	DBGPRINTF(("NEWENV: f=%d (indicates quitenv and return)\n", f));
 
 	if (f) {
 		quitenv();
 		return(1);
 	}
+
 	ep = (struct env *) space(sizeof(*ep));
 	if (ep == NULL) {
 		while (e.oenv)
@@ -1003,14 +1222,17 @@
 	*ep = e;
 	e.oenv = ep;
 	e.errpt = errpt;
+
 	return(0);
 }
 
 static void
 quitenv()
 {
-	register struct env *ep;
-	register int fd;
+	REGISTER struct env *ep;
+	REGISTER int fd;
+
+	DBGPRINTF(("QUITENV: e.oenv=0x%x\n", e.oenv));
 
 	if ((ep = e.oenv) != NULL) {
 		fd = e.iofd;
@@ -1027,7 +1249,7 @@
  */
 static int
 anys(s1, s2)
-register char *s1, *s2;
+REGISTER char *s1, *s2;
 {
 	while (*s1)
 		if (any(*s1++, s2))
@@ -1040,8 +1262,8 @@
  */
 static int
 any(c, s)
-register int c;
-register char *s;
+REGISTER int c;
+REGISTER char *s;
 {
 	while (*s)
 		if (*s++ == c)
@@ -1051,20 +1273,21 @@
 
 static char *
 putn(n)
-register int n;
+REGISTER int n;
 {
 	return(itoa(n));
 }
 
 static char *
 itoa(n)
-register int n;
+REGISTER int n;
 {
 	static char s[20];
 	snprintf(s, sizeof(s), "%u", n);
 	return(s);
 }
 
+
 static void
 next(int f)
 {
@@ -1093,7 +1316,7 @@
 space(n)
 int n;
 {
-	register char *cp;
+	REGISTER char *cp;
 
 	if ((cp = getcell(n)) == 0)
 		err("out of string space");
@@ -1102,10 +1325,10 @@
 
 static char *
 strsave(s, a)
-register char *s;
+REGISTER char *s;
 int a;
 {
-	register char *cp, *xp;
+	REGISTER char *cp, *xp;
 
 	if ((cp = space(strlen(s)+1)) != NULL) {
 		setarea((char *)cp, a);
@@ -1121,7 +1344,7 @@
  */
 static void
 sig(i)
-register int i;
+REGISTER int i;
 {
 	trapset = i;
 	signal(i, sig);
@@ -1134,8 +1357,10 @@
 
 	if ((trapstr = trap[i]) == NULL)
 		return;
+
 	if (i == 0)
 		trap[i] = 0;
+
 	RUN(aword, trapstr, nlchar);
 }
 
@@ -1149,11 +1374,11 @@
  */
 static struct var *
 lookup(n)
-register char *n;
+REGISTER char *n;
 {
-	register struct var *vp;
-	register char *cp;
-	register int c;
+	REGISTER struct var *vp;
+	REGISTER char *cp;
+	REGISTER int c;
 	static struct var dummy;
 
 	if (isdigit(*n)) {
@@ -1207,10 +1432,10 @@
  */
 static void
 nameval(vp, val, name)
-register struct var *vp;
+REGISTER struct var *vp;
 char *val, *name;
 {
-	register char *cp, *xp;
+	REGISTER char *cp, *xp;
 	char *nv;
 	int fl;
 
@@ -1262,24 +1487,29 @@
 
 static int
 isassign(s)
-register char *s;
+REGISTER char *s;
 {
+	DBGPRINTF7(("ISASSIGN: enter, s=%s\n", s));
+
 	if (!isalpha((int)*s) && *s != '_')
 		return(0);
 	for (; *s != '='; s++)
 		if (*s == 0 || (!isalnum(*s) && *s != '_'))
 			return(0);
+
 	return(1);
 }
 
 static int
 assign(s, cf)
-register char *s;
+REGISTER char *s;
 int cf;
 {
-	register char *cp;
+	REGISTER char *cp;
 	struct var *vp;
 
+	DBGPRINTF7(("ASSIGN: enter, s=%s, cf=%d\n", s, cf));
+
 	if (!isalpha(*s) && *s != '_')
 		return(0);
 	for (cp = s; *cp != '='; cp++)
@@ -1294,8 +1524,10 @@
 
 static int
 checkname(cp)
-register char *cp;
+REGISTER char *cp;
 {
+	DBGPRINTF7(("CHECKNAME: enter, cp=%s\n", cp));
+
 	if (!isalpha(*cp++) && *(cp-1) != '_')
 		return(0);
 	while (*cp)
@@ -1306,9 +1538,9 @@
 
 static void
 putvlist(f, out)
-register int f, out;
+REGISTER int f, out;
 {
-	register struct var *vp;
+	REGISTER struct var *vp;
 
 	for (vp = vlist; vp; vp = vp->next)
 		if (vp->status & f && (isalpha(*vp->name) || *vp->name == '_')) {
@@ -1323,7 +1555,7 @@
 
 static int
 eqname(n1, n2)
-register char *n1, *n2;
+REGISTER char *n1, *n2;
 {
 	for (; *n1 != '=' && *n1 != 0; n1++)
 		if (*n2++ != *n1)
@@ -1333,7 +1565,7 @@
 
 static char *
 findeq(cp)
-register char *cp;
+REGISTER char *cp;
 {
 	while (*cp != '\0' && *cp != '=')
 		cp++;
@@ -1355,9 +1587,9 @@
 
 static int
 gmatch(s, p)
-register char *s, *p;
+REGISTER char *s, *p;
 {
-	register int sc, pc;
+	REGISTER int sc, pc;
 
 	if (s == NULL || p == NULL)
 		return(0);
@@ -1392,10 +1624,10 @@
 
 static char *
 cclass(p, sub)
-register char *p;
-register int sub;
+REGISTER char *p;
+REGISTER int sub;
 {
-	register int c, d, not, found;
+	REGISTER int c, d, not, found;
 
 	if ((not = *p == NOT) != 0)
 		p++;
@@ -1429,8 +1661,8 @@
 static void
 initarea()
 {
-	brkaddr = malloc(65000);
-	brktop = brkaddr + 65000;
+	brkaddr = malloc(AREASIZE);
+	brktop = brkaddr + AREASIZE;
 
 	while ((int)sbrk(0) & ALIGN)
 		sbrk(1);
@@ -1446,9 +1678,9 @@
 getcell(nbytes)
 unsigned nbytes;
 {
-	register int nregio;
-	register struct region *p, *q;
-	register int i;
+	REGISTER int nregio;
+	REGISTER struct region *p, *q;
+	REGISTER int i;
 
 	if (nbytes == 0) {
 		puts("getcell(0)");
@@ -1515,7 +1747,7 @@
 freecell(cp)
 char *cp;
 {
-	register struct region *p;
+	REGISTER struct region *p;
 
 	if ((p = (struct region *)cp) != NULL) {
 		p--;
@@ -1527,9 +1759,9 @@
 
 static void
 freearea(a)
-register int a;
+REGISTER int a;
 {
-	register struct region *p, *top;
+	REGISTER struct region *p, *top;
 
 	top = areatop;
 	for (p = areabot; p != top; p = p->next)
@@ -1542,7 +1774,7 @@
 char *cp;
 int a;
 {
-	register struct region *p;
+	REGISTER struct region *p;
 
 	if ((p = (struct region *)cp) != NULL)
 		(p-1)->area = a;
@@ -1558,7 +1790,7 @@
 static void
 garbage()
 {
-	register struct region *p, *q, *top;
+	REGISTER struct region *p, *q, *top;
 
 	top = areatop;
 	for (p = areabot; p != top; p = p->next) {
@@ -1583,10 +1815,11 @@
  * shell: syntax (C version)
  */
 
-
 int
 yyparse()
 {
+	DBGPRINTF7(("YYPARSE: enter...\n"));
+
 	startl  = 1;
 	peeksym = 0;
 	yynerrs = 0;
@@ -1599,84 +1832,121 @@
 pipeline(cf)
 int cf;
 {
-	register struct op *t, *p;
-	register int c;
+	REGISTER struct op *t, *p;
+	REGISTER int c;
+
+	DBGPRINTF7(("PIPELINE: enter, cf=%d\n", cf));
 
 	t = command(cf);
+
+	DBGPRINTF9(("PIPELINE: t=0x%x\n", t));
+
 	if (t != NULL) {
 		while ((c = yylex(0)) == '|') {
-			if ((p = command(CONTIN)) == NULL)
+			if ((p = command(CONTIN)) == NULL) {
+				DBGPRINTF8(("PIPELINE: error!\n"));
 				SYNTAXERR;
+			}
+
 			if (t->type != TPAREN && t->type != TCOM) {
 				/* shell statement */
 				t = block(TPAREN, t, NOBLOCK, NOWORDS);
 			}
+
 			t = block(TPIPE, t, p, NOWORDS);
 		}
 		peeksym = c;
 	}
+
+	DBGPRINTF7(("PIPELINE: returning t=0x%x\n", t));
 	return(t);
 }
 
 static struct op *
 andor()
 {
-	register struct op *t, *p;
-	register int c;
+	REGISTER struct op *t, *p;
+	REGISTER int c;
+
+	DBGPRINTF7(("ANDOR: enter...\n"));
 
 	t = pipeline(0);
+
+	DBGPRINTF9(("ANDOR: t=0x%x\n", t));
+
 	if (t != NULL) {
 		while ((c = yylex(0)) == LOGAND || c == LOGOR) {
-			if ((p = pipeline(CONTIN)) == NULL)
+			if ((p = pipeline(CONTIN)) == NULL) {
+				DBGPRINTF8(("ANDOR: error!\n"));
 				SYNTAXERR;
+			}
+
 			t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS);
-		}
+		}  /* WHILE */
+
 		peeksym = c;
 	}
+
+	DBGPRINTF7(("ANDOR: returning t=0x%x\n", t));
 	return(t);
 }
 
 static struct op *
 c_list()
 {
-	register struct op *t, *p;
-	register int c;
+	REGISTER struct op *t, *p;
+	REGISTER int c;
+
+	DBGPRINTF7(("C_LIST: enter...\n"));
 
 	t = andor();
+
 	if (t != NULL) {
 		if((peeksym = yylex(0)) == '&')
 			t = block(TASYNC, t, NOBLOCK, NOWORDS);
+
 		while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) {
+
 			if ((p = andor()) == NULL)
 				return(t);
+
 			if((peeksym = yylex(0)) == '&')
 				p = block(TASYNC, p, NOBLOCK, NOWORDS);
+
 			t = list(t, p);
-		}
+		}  /* WHILE */
+
 		peeksym = c;
-	}
+	}  /* IF */
+
+	DBGPRINTF7(("C_LIST: returning t=0x%x\n", t));
 	return(t);
 }
 
-
 static int
 synio(cf)
 int cf;
 {
-	register struct ioword *iop;
-	register int i;
-	register int c;
+	REGISTER struct ioword *iop;
+	REGISTER int i;
+	REGISTER int c;
+
+	DBGPRINTF7(("SYNIO: enter, cf=%d\n", cf));
 
 	if ((c = yylex(cf)) != '<' && c != '>') {
 		peeksym = c;
 		return(0);
 	}
+
 	i = yylval.i;
 	musthave(WORD, 0);
 	iop = io(iounit, i, yylval.cp);
 	iounit = IODEFAULT;
+
 	if (i & IOHERE)
 		markhere(yylval.cp, iop);
+
+	DBGPRINTF7(("SYNIO: returning 1\n"));
 	return(1);
 }
 
@@ -1684,15 +1954,18 @@
 musthave(c, cf)
 int c, cf;
 {
-	if ((peeksym = yylex(cf)) != c)
+	if ((peeksym = yylex(cf)) != c) {
+		DBGPRINTF7(("MUSTHAVE: error!\n"));
 		SYNTAXERR;
+	}
+
 	peeksym = 0;
 }
 
 static struct op *
 simple()
 {
-	register struct op *t;
+	REGISTER struct op *t;
 
 	t = NULL;
 	for (;;) {
@@ -1721,7 +1994,9 @@
 nested(type, mark)
 int type, mark;
 {
-	register struct op *t;
+	REGISTER struct op *t;
+
+	DBGPRINTF3(("NESTED: enter, type=%d, mark=%d\n", type, mark));
 
 	multiline++;
 	t = c_list();
@@ -1734,17 +2009,24 @@
 command(cf)
 int cf;
 {
-	register struct op *t;
+	REGISTER struct op *t;
 	struct wdblock *iosave;
-	register int c;
+	REGISTER int c;
+
+	DBGPRINTF(("COMMAND: enter, cf=%d\n", cf));
 
 	iosave = iolist;
 	iolist = NULL;
+
 	if (multiline)
 		cf |= CONTIN;
+
 	while (synio(cf))
 		cf = 0;
-	switch (c = yylex(cf)) {
+
+	c = yylex(cf);
+
+	switch (c) {
 	default:
 		peeksym = c;
 		if ((t = simple()) == NULL) {
@@ -1797,7 +2079,9 @@
 		multiline++;
 		musthave(IN, CONTIN);
 		startl++;
+
 		t->left = caselist();
+
 		musthave(ESAC, 0);
 		multiline--;
 		break;
@@ -1811,11 +2095,45 @@
 		musthave(FI, 0);
 		multiline--;
 		break;
+
+	case DOT:
+		t = newtp();
+		t->type = TDOT;
+
+		musthave(WORD, 0);	/* gets name of file */
+		DBGPRINTF7(("COMMAND: DOT clause, yylval.cp is %s\n", yylval.cp));
+
+		word(yylval.cp);  /* add word to wdlist */
+		word(NOWORD);  /* terminate  wdlist */
+		t->words = copyw(); /* dup wdlist */
+		break;
+
 	}
+
 	while (synio(0))
 		;
+
 	t = namelist(t);
 	iolist = iosave;
+
+	DBGPRINTF(("COMMAND: returning 0x%x\n", t));
+
+	return(t);
+}
+
+static struct op *
+dowholefile(type, mark)
+int type;
+int mark;
+{
+	REGISTER struct op *t;
+	DBGPRINTF(("DOWHOLEFILE: enter, type=%d, mark=%d\n", type, mark));
+
+	multiline++;
+	t = c_list();
+	multiline--;
+	t = block(type, t, NOBLOCK, NOWORDS);
+	DBGPRINTF(("DOWHOLEFILE: return t=0x%x\n", t));
 	return(t);
 }
 
@@ -1823,8 +2141,8 @@
 dogroup(onlydone)
 int onlydone;
 {
-	register int c;
-	register struct op *mylist;
+	REGISTER int c;
+	REGISTER struct op *mylist;
 
 	c = yylex(CONTIN);
 	if (c == DONE && onlydone)
@@ -1839,8 +2157,8 @@
 static struct op *
 thenpart()
 {
-	register int c;
-	register struct op *t;
+	REGISTER int c;
+	REGISTER struct op *t;
 
 	if ((c = yylex(0)) != THEN) {
 		peeksym = c;
@@ -1858,8 +2176,8 @@
 static struct op *
 elsepart()
 {
-	register int c;
-	register struct op *t;
+	REGISTER int c;
+	REGISTER struct op *t;
 
 	switch (c = yylex(0)) {
 	case ELSE:
@@ -1883,18 +2201,24 @@
 static struct op *
 caselist()
 {
-	register struct op *t;
+	REGISTER struct op *t;
 
 	t = NULL;
-	while ((peeksym = yylex(CONTIN)) != ESAC)
+	while ((peeksym = yylex(CONTIN)) != ESAC) {
+		DBGPRINTF(("CASELIST, doing yylex, peeksym=%d\n", peeksym));
 		t = list(t, casepart());
+	}
+
+	DBGPRINTF(("CASELIST, returning t=0x%x\n", t));
 	return(t);
 }
 
 static struct op *
 casepart()
 {
-	register struct op *t;
+	REGISTER struct op *t;
+
+	DBGPRINTF7(("CASEPART: enter...\n"));
 
 	t = newtp();
 	t->type = TPAT;
@@ -1903,13 +2227,16 @@
 	t->left = c_list();
 	if ((peeksym = yylex(CONTIN)) != ESAC)
 		musthave(BREAK, CONTIN);
+
+	DBGPRINTF7(("CASEPART: made newtp(TPAT, t=0x%x)\n", t));
+
 	return(t);
 }
 
 static char **
 pattern()
 {
-	register int c, cf;
+	REGISTER int c, cf;
 
 	cf = CONTIN;
 	do {
@@ -1919,13 +2246,14 @@
 	} while ((c = yylex(0)) == '|');
 	peeksym = c;
 	word(NOWORD);
+
 	return(copyw());
 }
 
 static char **
 wordlist()
 {
-	register int c;
+	REGISTER int c;
 
 	if ((c = yylex(0)) != IN) {
 		peeksym = c;
@@ -1944,12 +2272,15 @@
  */
 static struct op *
 list(t1, t2)
-register struct op *t1, *t2;
+REGISTER struct op *t1, *t2;
 {
+	DBGPRINTF7(("LIST: enter, t1=0x%x, t2=0x%x\n", t1, t2));
+
 	if (t1 == NULL)
 		return(t2);
 	if (t2 == NULL)
 		return(t1);
+
 	return(block(TLIST, t1, t2, NOWORDS));
 }
 
@@ -1959,32 +2290,44 @@
 struct op *t1, *t2;
 char **wp;
 {
-	register struct op *t;
+	REGISTER struct op *t;
+
+	DBGPRINTF7(("BLOCK: enter, type=%d (%s)\n", type, T_CMD_NAMES[type]));
 
 	t = newtp();
 	t->type = type;
 	t->left = t1;
 	t->right = t2;
 	t->words = wp;
+
+	DBGPRINTF7(("BLOCK: inserted 0x%x between 0x%x and 0x%x\n", t, t1, t2));
+
 	return(t);
 }
 
+/* See if given string is a shell multiline (FOR, IF, etc) */
 static int
 rlookup(n)
-register char *n;
+REGISTER char *n;
 {
-	register struct res *rp;
+	REGISTER struct res *rp;
+
+	DBGPRINTF7(("RLOOKUP: enter, n is %s\n", n));
 
 	for (rp = restab; rp->r_name; rp++)
-		if (strcmp(rp->r_name, n) == 0)
-			return(rp->r_val);
-	return(0);
+		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 */
+		}
+
+	DBGPRINTF7(("RLOOKUP: NO match, returning 0\n"));
+	return(0);	/* Not a shell multiline */
 }
 
 static struct op *
 newtp()
 {
-	register struct op *t;
+	REGISTER struct op *t;
 
 	t = (struct op *)tree(sizeof(*t));
 	t->type = 0;
@@ -1993,18 +2336,25 @@
 	t->left = NULL;
 	t->right = NULL;
 	t->str = NULL;
+
+	DBGPRINTF3(("NEWTP: allocated 0x%x\n", t));
+
 	return(t);
 }
 
 static struct op *
 namelist(t)
-register struct op *t;
+REGISTER struct op *t;
 {
+
+	DBGPRINTF7(("NAMELIST: enter, t=0x%x, type %s, iolist=0x%x\n", t, \
T_CMD_NAMES[t->type], iolist)); +
 	if (iolist) {
 		iolist = addword((char *)NULL, iolist);
 		t->ioact = copyio();
 	} else
 		t->ioact = NULL;
+
 	if (t->type != TCOM) {
 		if (t->type != TPAREN && t->ioact != NULL) {
 			t = block(TPAREN, t, NOBLOCK, NOWORDS);
@@ -2013,15 +2363,18 @@
 		}
 		return(t);
 	}
+
 	word(NOWORD);
 	t->words = copyw();
+
+
 	return(t);
 }
 
 static char **
 copyw()
 {
-	register char **wd;
+	REGISTER char **wd;
 
 	wd = getwords(wdlist);
 	wdlist = 0;
@@ -2038,7 +2391,7 @@
 static struct ioword **
 copyio()
 {
-	register struct ioword **iop;
+	REGISTER struct ioword **iop;
 
 	iop = (struct ioword **) getwords(iolist);
 	iolist = 0;
@@ -2051,7 +2404,7 @@
 int f;
 char *cp;
 {
-	register struct ioword *iop;
+	REGISTER struct ioword *iop;
 
 	iop = (struct ioword *) tree(sizeof(*iop));
 	iop->io_unit = u;
@@ -2085,7 +2438,7 @@
 yylex(cf)
 int cf;
 {
-	register int c, c1;
+	REGISTER int c, c1;
 	int atstart;
 
 	if ((c = peeksym) > 0) {
@@ -2094,15 +2447,21 @@
 			startl = 1;
 		return(c);
 	}
+
+
 	nlseen = 0;
-	e.linep = line;
 	atstart = startl;
 	startl = 0;
 	yylval.i = 0;
+	e.linep = line;
+
+/* MALAMO */
+	line[LINELIM-1] = '\0';
 
 loop:
-	while ((c = my_getc(0)) == ' ' || c == '\t')
+	while ((c = my_getc(0)) == ' ' || c == '\t')	/* Skip whitespace */
 		;
+
 	switch (c) {
 	default:
 		if (any(c, "0123456789")) {
@@ -2116,16 +2475,18 @@
 		}
 		break;
 
-	case '#':
+	case '#':	/* Comment, skip to next newline or End-of-string */
 		while ((c = my_getc(0)) != 0 && c != '\n')
 			;
 		unget(c);
 		goto loop;
 
 	case 0:
+		DBGPRINTF5(("YYLEX: return 0, c=%d\n", c));
 		return(c);
-
+		
 	case '$':
+		DBGPRINTF9(("YYLEX: found $\n"));
 		*e.linep++ = c;
 		if ((c = my_getc(0)) == '{') {
 			if ((c = collect(c, '}')) != '\0')
@@ -2144,12 +2505,13 @@
 	case '|':
 	case '&':
 	case ';':
-		if ((c1 = dual(c)) != '\0') {
-			startl = 1;
-			return(c1);
-		}
 		startl = 1;
-		return(c);
+		/* If more chars process them, else return NULL char */		
+		if ((c1 = dual(c)) != '\0')
+			return(c1);
+		else
+			return(c); 
+
 	case '^':
 		startl = 1;
 		return('|');
@@ -2184,29 +2546,38 @@
 	unget(c);
 
 pack:
-	while ((c = my_getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n"))
+	while ((c = my_getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) {
 		if (e.linep >= elinep)
 			err("word too long");
 		else
 			*e.linep++ = c;
+	};
+
 	unget(c);
+
 	if(any(c, "\"'`$"))
 		goto loop;
+
 	*e.linep++ = '\0';
-	if (atstart && (c = rlookup(line))!=0) {
+
+	if (atstart && (c = rlookup(line)) != 0) {
 		startl = 1;
 		return(c);
 	}
+
 	yylval.cp = strsave(line, areanum);
 	return(WORD);
 }
 
+
 static int
 collect(c, c1)
-register int c, c1;
+REGISTER int c, c1;
 {
 	char s[2];
 
+	DBGPRINTF8(("COLLECT: enter, c=%d, c1=%d\n", c, c1));
+
 	*e.linep++ = c;
 	while ((c = my_getc(c1)) != c1) {
 		if (c == 0) {
@@ -2225,30 +2596,43 @@
 		}
 		*e.linep++ = c;
 	}
+
 	*e.linep++ = c;
+
+	DBGPRINTF8(("COLLECT: return 0, line is %s\n", line));
+
 	return(0);
 }
 
+/* "multiline commands" helper func */
+/* see if next 2 chars form a shell multiline */
 static int
 dual(c)
-register int c;
+REGISTER int c;
 {
 	char s[3];
-	register char *cp = s;
+	REGISTER char *cp = s;
 
-	*cp++ = c;
-	*cp++ = my_getc(0);
-	*cp = 0;
-	if ((c = rlookup(s)) == 0)
-		unget(*--cp);
-	return(c);
+	DBGPRINTF8(("DUAL: enter, c=%d\n", c));
+
+	*cp++ = c;			/* c is the given "peek" char */
+	*cp++ = my_getc(0); /* get next char of input */
+	*cp = 0;			/* add EOS marker */
+
+	c = rlookup(s);		/* see if 2 chars form a shell multiline */
+	if (c == 0)
+		unget(*--cp);	/* String is not a shell multiline, put peek char back */
+
+	return (c);			/* String is multiline, return numeric multiline (restab) code */
 }
 
 static void
 diag(ec)
-register int ec;
+REGISTER int ec;
 {
-	register int c;
+	REGISTER int c;
+
+	DBGPRINTF8(("DIAG: enter, ec=%d\n", ec));
 
 	c = my_getc(0);
 	if (c == '>' || c == '<') {
@@ -2268,9 +2652,10 @@
 tree(size)
 unsigned size;
 {
-	register char *t;
+	REGISTER char *t;
 
 	if ((t = getcell(size)) == NULL) {
+		DBGPRINTF2(("TREE: getcell(%d) failed!\n", size));
 		prs("command line too complicated\n");
 		fail();
 		/* NOTREACHED */
@@ -2290,14 +2675,15 @@
 
 static int
 execute(t, pin, pout, act)
-register struct op *t;
+REGISTER struct op *t;
 int *pin, *pout;
 int act;
 {
-	register struct op *t1;
+	REGISTER struct op *t1;
 	volatile int i, rv, a;
 	char *cp, **wp, **wp2;
 	struct var *vp;
+	struct op *outtree_save;
 	struct brkcon bc;
 
 #if __GNUC__
@@ -2305,28 +2691,53 @@
 	(void) &wp;
 #endif
 
-
-	if (t == NULL)
+	if (t == NULL) {
+		DBGPRINTF4(("EXECUTE: enter, t==null, returning.\n"));
 		return(0);
+	}
+
+	DBGPRINTF(("EXECUTE: t=0x%x, t->type=%d (%s), t->words is %s\n", t, t->type, \
T_CMD_NAMES[t->type], ((t->words==NULL)?"NULL":t->words[0]))); +
 	rv = 0;
 	a = areanum++;
 	wp = (wp2 = t->words) != NULL
 	     ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY)
 	     : NULL;
 
+/* Hard to know how many words there are, be careful of garbage pointer values */
+/* They are likely to cause "PCI bus fault" errors */
+#if 0
+	DBGPRINTF(("EXECUTE: t->left=0x%x, t->right=0x%x, t->words[1] is %s\n", t->left, \
t->right, ((t->words[1]==NULL)?"NULL":t->words[1]))); +	DBGPRINTF7(("EXECUTE: \
t->words[2] is %s, t->words[3] is %s\n", ((t->words[2]==NULL)?"NULL":t->words[2]), \
((t->words[3]==NULL)?"NULL":t->words[3]))); +#endif
+
+
 	switch(t->type) {
+	case TDOT:
+		DBGPRINTF3(("EXECUTE: TDOT\n"));
+
+		outtree_save = outtree;
+
+		newfile(evalstr(t->words[0], DOALL));
+
+		t->left = dowholefile(TLIST, 0);
+		t->right = NULL;
+
+		outtree = outtree_save;
+
+		if (t->left)
+			rv = execute(t->left, pin, pout, 0);
+		if (t->right)
+			rv = execute(t->right, pin, pout, 0);
+		break;
+
 	case TPAREN:
 		rv = execute(t->left, pin, pout, 0);
 		break;
 
 	case TCOM:
 		{
-			int child;
-			rv = forkexec(t, pin, pout, act, wp, &child);
-			if (child) {
-				exstat = rv;
-				leave();
-			}
+			rv = forkexec(t, pin, pout, act, wp);
 		}
 		break;
 
@@ -2351,6 +2762,8 @@
 	{
 		int hinteractive = interactive;
 
+		DBGPRINTF7(("EXECUTE: TASYNC clause, calling vfork()...\n"));
+
 		i = vfork();
 		if (i != 0) {
 			interactive = hinteractive;
@@ -2375,7 +2788,7 @@
 				close(0);
 				open("/dev/null", 0);
 			}
-			exit(execute(t->left, pin, pout, FEXEC));
+			_exit(execute(t->left, pin, pout, FEXEC));
 		}
 	}
 		break;
@@ -2433,8 +2846,14 @@
 	case TCASE:
 		if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0)
 			cp = "";
-		if ((t1 = findcase(t->left, cp)) != NULL)
+
+		DBGPRINTF7(("EXECUTE: TCASE, t->str is %s, cp is %s\n", \
((t->str==NULL)?"NULL":t->str), ((cp==NULL)?"NULL":cp))); +
+		if ((t1 = findcase(t->left, cp)) != NULL) {
+			DBGPRINTF7(("EXECUTE: TCASE, calling execute(t=0x%x, t1=0x%x)...\n", t, t1));
 			rv = execute(t1, pin, pout, 0);
+			DBGPRINTF7(("EXECUTE: TCASE, back from execute(t=0x%x, t1=0x%x)...\n", t, t1));
+		}
 		break;
 
 	case TBRACE:
@@ -2449,7 +2868,8 @@
 		if (rv >= 0 && (t1 = t->left))
 			rv = execute(t1, pin, pout, 0);
 		break;
-	}
+
+	};
 
 broken:
 	t->words = wp2;
@@ -2461,27 +2881,31 @@
 		closeall();
 		fail();
 	}
+
 	if ((i = trapset) != 0) {
 		trapset = 0;
 		runtrap(i);
 	}
+
+	DBGPRINTF(("EXECUTE: returning from t=0x%x, rv=%d\n", t, rv));
 	return(rv);
 }
 
 static int
-forkexec( register struct op *t, int *pin, int *pout, int act, char **wp, int \
*pforked) +forkexec(REGISTER struct op *t, int *pin, int *pout, int act, char **wp)
 {
+	pid_t newpid;
 	int i, rv;
 	int (*shcom)(struct op *) = NULL;
-	register int f;
+	REGISTER int f;
 	char *cp = NULL;
 	struct ioword **iopp;
 	int resetsig;
 	char **owp;
+	int forked=0;
 
 	int *hpin = pin;
 	int *hpout = pout;
-	int hforked;
 	char *hwp;
 	int hinteractive;
 	int hintr;
@@ -2499,9 +2923,20 @@
 	(void) &owp;
 #endif
 
+	DBGPRINTF(("FORKEXEC: t=0x%x, pin 0x%x, pout 0x%x, act %d\n", t, pin, pout, act));
+	DBGPRINTF7(("FORKEXEC: t->words is %s\n", ((t->words==NULL)?"NULL":t->words[0])));
+
+/* Hard to know how many words there are, be careful of garbage pointer values */
+/* They are likely to cause "PCI bus fault" errors */
+#if 0
+	DBGPRINTF7(("FORKEXEC: t->words is %s, t->words[1] is %s\n", \
((t->words==NULL)?"NULL":t->words[0]), ((t->words==NULL)?"NULL":t->words[1]))); \
+	DBGPRINTF7(("FORKEXEC: wp is %s, wp[1] is %s\n", ((wp==NULL)?"NULL":wp[0]), \
((wp[1]==NULL)?"NULL":wp[1]))); +	DBGPRINTF7(("FORKEXEC: wp2 is %s, wp[3] is %s\n", \
((wp[2]==NULL)?"NULL":wp[2]), ((wp[3]==NULL)?"NULL":wp[3]))); +#endif
+
+
 	owp = wp;
 	resetsig = 0;
-	*pforked = 0;
 	rv = -1;	/* system-detected error */
 	if (t->type == TCOM) {
 		while ((cp = *wp++) != NULL)
@@ -2510,49 +2945,81 @@
 
 		/* strip all initial assignments */
 		/* not correct wrt PATH=yyy command  etc */
-		if (flag['x'])
+		if (flag['x']) {
+			DBGPRINTF9(("FORKEXEC: echo'ing, cp=0x%x, wp=0x%x, owp=0x%x\n", cp, wp, owp));
 			echo (cp ? wp: owp);
+		}
+
+#if 0 
+		DBGPRINTF9(("FORKEXEC: t->words is %s, t->words[1] is %s\n", \
((t->words==NULL)?"NULL":t->words[0]), ((t->words==NULL)?"NULL":t->words[1]))); \
+		DBGPRINTF9(("FORKEXEC: wp is %s, wp[1] is %s\n", ((wp==NULL)?"NULL":wp[0]), \
((wp==NULL)?"NULL":wp[1]))); +#endif
+
 		if (cp == NULL && t->ioact == NULL) {
 			while ((cp = *owp++) != NULL && assign(cp, COPYV))
 				;
+			DBGPRINTF(("FORKEXEC: returning setstatus()\n"));
 			return(setstatus(0));
 		}
-		else if (cp != NULL)
+		else if (cp != NULL) {
 			shcom = inbuilt(cp);
+		}
 	}
+
 	t->words = wp;
 	f = act;
-	if (shcom == NULL && (f & FEXEC) == 0) {
 
+#if 0
+	DBGPRINTF3(("FORKEXEC: t->words is %s, t->words[1] is %s\n", \
((t->words==NULL)?"NULL":t->words[0]), ((t->words==NULL)?"NULL":t->words[1]))); \
+#endif +	DBGPRINTF(("FORKEXEC: shcom 0x%x, f&FEXEC 0x%x, owp 0x%x\n", shcom, \
f&FEXEC, owp)); +
+	if (shcom == NULL && (f & FEXEC) == 0) 
+	{
+		/* Save values in case the child process alters them */
 		hpin = pin;
 		hpout = pout;
-		hforked = *pforked;
 		hwp = *wp;
 		hinteractive = interactive;
 		hintr = intr;
 		hbrklist = brklist;
 		hexecflg = execflg;
 
-		i = vfork();
-		if (i != 0) {
-                	/* who wrote this crappy non vfork safe shit? */
+		DBGPRINTF3(("FORKEXEC: calling vfork()...\n"));
+
+		newpid = vfork();
+
+		if (newpid == -1) {
+			DBGPRINTF(("FORKEXEC: ERROR, unable to vfork()!\n"));
+			return (-1);
+		}
+
+
+		if (newpid > 0) {	/* Parent */
+
+		/* Restore values */
 			pin = hpin;
 			pout = hpout;
-			*pforked = hforked;
 			*wp = hwp;
 			interactive = hinteractive;
 			intr = hintr;
 			brklist = hbrklist;
 			execflg = hexecflg;
 
-			*pforked = 0;
+/* moved up
 			if (i == -1)
 				return(rv);
+*/
+
 			if (pin != NULL)
 				closepipe(pin);
-			return(pout==NULL? setstatus(waitfor(i,0)): 0);
+
+			return(pout==NULL? setstatus(waitfor(newpid,0)): 0);
 		}
 
+		/* Must be the child process, pid should be 0 */
+		DBGPRINTF(("FORKEXEC: child process, shcom=0x%x\n", shcom));
+
 		if (interactive) {
 			signal(SIGINT, SIG_IGN);
 			signal(SIGQUIT, SIG_IGN);
@@ -2560,20 +3027,25 @@
 		}
 		interactive = 0;
 		intr = 0;
-		(*pforked)++;
+		forked = 1;
 		brklist = 0;
 		execflg = 0;
 	}
+
+
 	if (owp != NULL)
 		while ((cp = *owp++) != NULL && assign(cp, COPYV))
 			if (shcom == NULL)
 				export(lookup(cp));
+
 #ifdef COMPIPE
 	if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) {
 		err("piping to/from shell builtins not yet done");
+		if (forked) _exit(-1);
 		return(-1);
 	}
 #endif
+
 	if (pin != NULL) {
 		dup2(pin[0], 0);
 		closepipe(pin);
@@ -2582,18 +3054,28 @@
 		dup2(pout[1], 1);
 		closepipe(pout);
 	}
+
 	if ((iopp = t->ioact) != NULL) {
 		if (shcom != NULL && shcom != doexec) {
 			prs(cp);
 			err(": cannot redirect shell command");
+			if (forked) _exit(-1);
 			return(-1);
 		}
 		while (*iopp)
-			if (iosetup(*iopp++, pin!=NULL, pout!=NULL))
+			if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) {
+				if (forked) _exit(rv);
 				return(rv);
+			}
 	}
-	if (shcom)
-		return(setstatus((*shcom)(t)));
+
+	if (shcom) {
+		i = setstatus((*shcom)(t));
+		if (forked) _exit(i);
+		DBGPRINTF(("FORKEXEC: returning i=%d\n", i));
+		return(i);
+	}
+
 	/* should use FIOCEXCL */
 	for (i=FDBASE; i<NOFILE; i++)
 		close(i);
@@ -2601,18 +3083,22 @@
 		signal(SIGINT, SIG_DFL);
 		signal(SIGQUIT, SIG_DFL);
 	}
+
 	if (t->type == TPAREN)
-		exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));
+		_exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));
 	if (wp[0] == NULL)
-		exit(0);
+		_exit(0);
 
-	cp = rexecve(wp[0], wp, makenv());
-	prs(wp[0]); prs(": "); warn(cp);
+	cp = rexecve(wp[0], wp, makenv(0));
+	prs(wp[0]); prs(": "); err(cp);
 	if (!execflg)
 		trap[0] = NULL;
+
+	DBGPRINTF(("FORKEXEC: calling leave(), pid=%d\n", newpid));
+
 	leave();
 	/* NOTREACHED */
-	exit(1);
+	_exit(1);
 }
 
 /*
@@ -2621,24 +3107,30 @@
  */
 static int
 iosetup(iop, pipein, pipeout)
-register struct ioword *iop;
+REGISTER struct ioword *iop;
 int pipein, pipeout;
 {
-	register int u = -1;
+	REGISTER int u = -1;
 	char *cp=NULL, *msg;
 
+	DBGPRINTF(("IOSETUP: iop 0x%x, pipein 0x%x, pipeout 0x%x\n", iop, pipein, \
pipeout)); +
 	if (iop->io_unit == IODEFAULT)	/* take default */
 		iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1;
+
 	if (pipein && iop->io_unit == 0)
 		return(0);
+
 	if (pipeout && iop->io_unit == 1)
 		return(0);
+
 	msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create";
 	if ((iop->io_flag & IOHERE) == 0) {
 		cp = iop->io_name;
 		if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL)
 			return(1);
 	}
+
 	if (iop->io_flag & IODUP) {
 		if (cp[1] || (!isdigit(*cp) && *cp != '-')) {
 			prs(cp);
@@ -2693,9 +3185,9 @@
 
 static void
 echo(wp)
-register char **wp;
+REGISTER char **wp;
 {
-	register int i;
+	REGISTER int i;
 
 	prs("+");
 	for (i=0; wp[i]; i++) {
@@ -2711,21 +3203,34 @@
 struct op *t;
 char *w;
 {
-	register struct op *t1;
+	REGISTER struct op *t1;
 	struct op **tp;
-	register char **wp, *cp;
+	REGISTER char **wp, *cp;
 
-	if (t == NULL)
+
+	if (t == NULL) {
+		DBGPRINTF3(("FIND1CASE: enter, t==NULL, returning.\n"));
 		return((struct op **)NULL);
+	}
+
+	DBGPRINTF3(("FIND1CASE: enter, t->type=%d (%s)\n", t->type, T_CMD_NAMES[t->type]));
+
 	if (t->type == TLIST) {
-		if ((tp = find1case(t->left, w)) != NULL)
+		if ((tp = find1case(t->left, w)) != NULL) {
+			DBGPRINTF3(("FIND1CASE: found one to the left, returning tp=0x%x\n", tp));
 			return(tp);
+		}
 		t1 = t->right;	/* TPAT */
 	} else
 		t1 = t;
+
 	for (wp = t1->words; *wp;)
-		if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp))
+		if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) {
+			DBGPRINTF3(("FIND1CASE: returning &t1->left= 0x%x.\n", &t1->left));
 			return(&t1->left);
+		}
+
+	DBGPRINTF(("FIND1CASE: returning NULL\n"));
 	return((struct op **)NULL);
 }
 
@@ -2734,7 +3239,7 @@
 struct op *t;
 char *w;
 {
-	register struct op **tp;
+	REGISTER struct op **tp;
 
 	return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL);
 }
@@ -2759,10 +3264,10 @@
  */
 static int
 waitfor(lastpid, canintr)
-register int lastpid;
+REGISTER int lastpid;
 int canintr;
 {
-	register int pid, rv;
+	REGISTER int pid, rv;
 	int s;
 	int oheedint = heedint;
 
@@ -2814,7 +3319,7 @@
 
 static int
 setstatus(s)
-register int s;
+REGISTER int s;
 {
 	exstat = s;
 	setval(lookup("?"), putn(s));
@@ -2830,8 +3335,8 @@
 rexecve(c, v, envp)
 char *c, **v, **envp;
 {
-	register int i;
-	register char *sp, *tp;
+	REGISTER int i;
+	REGISTER char *sp, *tp;
 	int eacces = 0, asis = 0;
 
 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
@@ -2846,6 +3351,8 @@
 	}
 #endif
 
+	DBGPRINTF(("REXECVE: c=0x%x, v=0x%x, envp=0x%x\n", c,v,envp));
+
 	sp = any('/', c)? "": path->value;
 	asis = *sp == '\0';
 	while (asis || *sp != '\0') {
@@ -2861,7 +3368,10 @@
 		for (i = 0; (*tp++ = c[i++]) != '\0';)
 			;
 
+		DBGPRINTF3(("REXECVE: e.linep is %s\n", e.linep));
+
 		execve(e.linep, v, envp);
+
 		switch (errno) {
 		case ENOEXEC:
 			*v = e.linep;
@@ -2904,12 +3414,15 @@
 	(void) &rv;
 #endif
 
+	DBGPRINTF(("RUN: enter, areanum %d, outtree 0x%x, failpt 0x%x\n", areanum, outtree, \
failpt)); +
 	areanum++;
 	swdlist = wdlist;
 	siolist = iolist;
 	otree = outtree;
 	ofail = failpt;
 	rv = -1;
+
 	if (newenv(setjmp(errpt = ev)) == 0) {
 		wdlist = 0;
 		iolist = 0;
@@ -2919,12 +3432,16 @@
 		if (setjmp(failpt = rt) == 0 && yyparse() == 0)
 			rv = execute(outtree, NOPIPE, NOPIPE, 0);
 		quitenv();
+	} else {
+		DBGPRINTF(("RUN: error from newenv()!\n"));
 	}
+
 	wdlist = swdlist;
 	iolist = siolist;
 	failpt = ofail;
 	outtree = otree;
 	freearea(areanum--);
+
 	return(rv);
 }
 
@@ -2984,9 +3501,9 @@
 
 static int
 dochdir(t)
-register struct op *t;
+REGISTER struct op *t;
 {
-	register char *cp, *er;
+	REGISTER char *cp, *er;
 
 	if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL)
 		er = ": no home directory";
@@ -3001,9 +3518,9 @@
 
 static int
 doshift(t)
-register struct op *t;
+REGISTER struct op *t;
 {
-	register int n;
+	REGISTER int n;
 
 	n = t->words[1]? getn(t->words[1]): 1;
 	if(dolc < n) {
@@ -3024,23 +3541,23 @@
 dologin(t)
 struct op *t;
 {
-	register char *cp;
+	REGISTER char *cp;
 
 	if (interactive) {
 		signal(SIGINT, SIG_DFL);
 		signal(SIGQUIT, SIG_DFL);
 	}
-	cp = rexecve(t->words[0], t->words, makenv());
+	cp = rexecve(t->words[0], t->words, makenv(0));
 	prs(t->words[0]); prs(": "); err(cp);
 	return(1);
 }
 
 static int
 doumask(t)
-register struct op *t;
+REGISTER struct op *t;
 {
-	register int i, n;
-	register char *cp;
+	REGISTER int i, n;
+	REGISTER char *cp;
 
 	if ((cp = t->words[1]) == NULL) {
 		i = umask(0);
@@ -3058,9 +3575,9 @@
 
 static int
 doexec(t)
-register struct op *t;
+REGISTER struct op *t;
 {
-	register int i;
+	REGISTER int i;
 	jmp_buf ex;
 	xint *ofail;
 
@@ -3082,29 +3599,53 @@
 dodot(t)
 struct op *t;
 {
-	register int i;
-	register char *sp, *tp;
+	REGISTER int i;
+	REGISTER char *sp, *tp;
 	char *cp;
+	int maltmp;
+
+	DBGPRINTF(("DODOT: enter, t=0x%x, tleft 0x%x, tright 0x%x, e.linep is %s\n", t, \
t->left, t->right, ((e.linep==NULL)?"NULL":e.linep)));  
-	if ((cp = t->words[1]) == NULL)
+	if ((cp = t->words[1]) == NULL) {
+		DBGPRINTF(("DODOT: bad args, ret 0\n"));
 		return(0);
+	}
+	else {
+		DBGPRINTF(("DODOT: cp is %s\n", cp));
+	}
+
 	sp = any('/', cp)? ":": path->value;
+
+	DBGPRINTF(("DODOT: sp is %s,  e.linep is %s\n",((sp==NULL)?"NULL":sp) \
,((e.linep==NULL)?"NULL":e.linep))); +
 	while (*sp) {
 		tp = e.linep;
 		while (*sp && (*tp = *sp++) != ':')
 			tp++;
 		if (tp != e.linep)
 			*tp++ = '/';
+
 		for (i = 0; (*tp++ = cp[i++]) != '\0';)
 			;
+
+		/* Original code */
 		if ((i = open(e.linep, 0)) >= 0) {
 			exstat = 0;
-			next(remap(i));
+			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)); +
+			next(maltmp);	/* Basically a PUSHIO */
+
+			DBGPRINTF(("DODOT: returning exstat=%d\n", exstat));
+
 			return(exstat);
 		}
-	}
+
+	}	/* While */
+
 	prs(cp);
 	err(": not found");
+
 	return(-1);
 }
 
@@ -3112,8 +3653,8 @@
 dowait(t)
 struct op *t;
 {
-	register int i;
-	register char *cp;
+	REGISTER int i;
+	REGISTER char *cp;
 
 	if ((cp = t->words[1]) != NULL) {
 		i = getn(cp);
@@ -3129,9 +3670,9 @@
 doread(t)
 struct op *t;
 {
-	register char *cp, **wp;
-	register int nb = 0;
-	register int  nl = 0;
+	REGISTER char *cp, **wp;
+	REGISTER int nb = 0;
+	REGISTER int  nl = 0;
 
 	if (t->words[1] == NULL) {
 		err("Usage: read name ...");
@@ -3153,17 +3694,17 @@
 
 static int
 doeval(t)
-register struct op *t;
+REGISTER struct op *t;
 {
 	return(RUN(awordlist, t->words+1, wdchar));
 }
 
 static int
 dotrap(t)
-register struct op *t;
+REGISTER struct op *t;
 {
-	register int  n, i;
-	register int  resetsig;
+	REGISTER int  n, i;
+	REGISTER int  resetsig;
 
 	if (t->words[1] == NULL) {
 		for (i=0; i<=_NSIG; i++)
@@ -3204,7 +3745,7 @@
 getsig(s)
 char *s;
 {
-	register int n;
+	REGISTER int n;
 
 	if ((n = getn(s)) < 0 || n > _NSIG) {
 		err("trap: bad signal number");
@@ -3214,7 +3755,7 @@
 }
 
 static void
-setsig( register int n, sighandler_t f)
+setsig( REGISTER int n, sighandler_t f)
 {
 	if (n == 0)
 		return;
@@ -3228,8 +3769,8 @@
 getn(as)
 char *as;
 {
-	register char *s;
-	register int n, m;
+	REGISTER char *s;
+	REGISTER int n, m;
 
 	s = as;
 	m = 1;
@@ -3262,11 +3803,11 @@
 
 static int
 brkcontin(cp, val)
-register char *cp;
+REGISTER char *cp;
 int val;
 {
-	register struct brkcon *bc;
-	register int nl;
+	REGISTER struct brkcon *bc;
+	REGISTER int nl;
 
 	nl = cp == NULL? 1: getn(cp);
 	if (nl <= 0)
@@ -3289,11 +3830,14 @@
 doexit(t)
 struct op *t;
 {
-	register char *cp;
+	REGISTER char *cp;
 
 	execflg = 0;
 	if ((cp = t->words[1]) != NULL)
 		setstatus(getn(cp));
+
+	DBGPRINTF(("DOEXIT: calling leave(), t=0x%x\n", t));
+
 	leave();
 	/* NOTREACHED */
 	return(0);
@@ -3317,6 +3861,9 @@
 
 static void rdexp (char **wp, void (*f)(struct var *), int key)
 {
+	DBGPRINTF6(("RDEXP: enter, wp=0x%x, func=0x%x, key=%d\n", wp, f, key));
+	DBGPRINTF6(("RDEXP: *wp=%s\n", *wp));
+
 	if (*wp != NULL) {
 		for (; *wp != NULL; wp++) {
 			if (isassign(*wp)) {
@@ -3337,7 +3884,7 @@
 
 static void
 badid(s)
-register char *s;
+REGISTER char *s;
 {
 	prs(s);
 	err(": bad identifier");
@@ -3345,11 +3892,11 @@
 
 static int
 doset(t)
-register struct op *t;
+REGISTER struct op *t;
 {
-	register struct var *vp;
-	register char *cp;
-	register int n;
+	REGISTER struct var *vp;
+	REGISTER char *cp;
+	REGISTER int n;
 
 	if ((cp = t->words[1]) == NULL) {
 		for (vp = vlist; vp; vp = vp->next)
@@ -3391,7 +3938,7 @@
 
 static void
 varput(s, out)
-register char *s;
+REGISTER char *s;
 int out;
 {
 	if (isalnum(*s) || *s == '_') {
@@ -3457,6 +4004,9 @@
 	(void) &wp;
 	(void) &ap;
 #endif
+
+	DBGPRINTF4(("EVAL: enter, f=%d\n", f));
+
 	wp = NULL;
 	wb = NULL;
 	wf = NULL;
@@ -3478,6 +4028,7 @@
 		quitenv();
 	} else
 		gflg = 1;
+
 	return(gflg? (char **)NULL: wp);
 }
 
@@ -3487,15 +4038,17 @@
  * will already have been done.
  */
 static char **
-makenv()
+makenv(int all)
 
 {
-	register struct wdblock *wb;
-	register struct var *vp;
+	REGISTER struct wdblock *wb;
+	REGISTER struct var *vp;
+
+	DBGPRINTF5(("MAKENV: enter, all=%d\n", all));
 
 	wb = NULL;
 	for (vp = vlist; vp; vp = vp->next)
-		if (vp->status & EXPORT)
+		if (all || vp->status & EXPORT)
 			wb = addword(vp->name, wb);
 	wb = addword((char *)0, wb);
 	return(getwords(wb));
@@ -3503,11 +4056,13 @@
 
 static char *
 evalstr(cp, f)
-register char *cp;
+REGISTER char *cp;
 int f;
 {
 	struct wdblock *wb;
 
+	DBGPRINTF6(("EVALSTR: enter, cp=0x%x, f=%d\n", cp, f));
+
 	wb = NULL;
 	if (expand(cp, &wb, f)) {
 		if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL)
@@ -3519,7 +4074,7 @@
 }
 
 static int
-expand( char *cp, register struct wdblock **wbp, int f)
+expand( char *cp, REGISTER struct wdblock **wbp, int f)
 {
 	jmp_buf ev;
 
@@ -3527,9 +4082,14 @@
 	/* Avoid longjmp clobbering */
 	(void) &cp;
 #endif
+
+	DBGPRINTF3(("EXPAND: enter, f=%d\n", f));
+
 	gflg = 0;
+
 	if (cp == NULL)
 		return(0);
+
 	if (!anys("$`'\"", cp) &&
 	    !anys(ifs->value, cp) &&
 	    ((f&DOGLOB)==0 || !anys("[*?", cp))) {
@@ -3565,10 +4125,12 @@
 blank(f)
 int f;
 {
-	register int c, c1;
-	register char *sp;
+	REGISTER int c, c1;
+	REGISTER char *sp;
 	int scanequals, foundequals;
 
+	DBGPRINTF3(("BLANK: enter, f=%d\n", f));
+
 	sp = e.linep;
 	scanequals = f & DOKEY;
 	foundequals = 0;
@@ -3633,10 +4195,12 @@
  */
 static int
 subgetc(ec, quoted)
-register char ec;
+REGISTER char ec;
 int quoted;
 {
-	register char c;
+	REGISTER char c;
+
+	DBGPRINTF3(("SUBGETC: enter, quoted=%d\n", quoted));
 
 again:
 	c = my_getc(ec);
@@ -3665,9 +4229,11 @@
 	int otask;
 	struct io *oiop;
 	char *dolp;
-	register char *s, c, *cp=NULL;
+	REGISTER char *s, c, *cp=NULL;
 	struct var *vp;
 
+	DBGPRINTF3(("DOLLAR: enter, quoted=%d\n", quoted));
+
 	c = readc();
 	s = e.linep;
 	if (c != '{') {
@@ -3682,6 +4248,7 @@
 	} else {
 		oiop = e.iop;
 		otask = e.iop->task;
+
 		e.iop->task = XOTHER;
 		while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n')
 			if (e.linep < elinep)
@@ -3766,7 +4333,7 @@
 int quoted;
 {
 	char *cp;
-	register int i;
+	REGISTER int i;
 	int j;
 	int pf[2];
 	static char child_cmd[LINELIM];
@@ -3875,8 +4442,12 @@
 
 	if (openpipe(pf) < 0)
 		return(0);
+
 	while ((i = vfork()) == -1 && errno == EAGAIN)
 		;
+
+	DBGPRINTF3(("GRAVE: i is %d\n", io));
+
 	if (i < 0) {
 		closepipe(pf);
 		err((char*)bb_msg_memory_exhausted);
@@ -3903,16 +4474,17 @@
 	argument_list[2] = child_cmd;
 	argument_list[3] = 0;
 
-	prs(rexecve(argument_list[0], argument_list, makenv()));
+	cp = rexecve(argument_list[0], argument_list, makenv(1));
+	prs(argument_list[0]); prs(": "); err(cp);
 	_exit(1);
 }
 
 
 static char *
 unquote(as)
-register char *as;
+REGISTER char *as;
 {
-	register char *s;
+	REGISTER char *s;
 
 	if ((s = as) != NULL)
 		while (*s)
@@ -3938,8 +4510,8 @@
 char *cp;
 struct wdblock *wb;
 {
-	register int i;
-	register char *pp;
+	REGISTER int i;
+	REGISTER char *pp;
 
 	if (cp == 0)
 		return(wb);
@@ -3982,9 +4554,9 @@
 static void
 globname(we, pp)
 char *we;
-register char *pp;
+REGISTER char *pp;
 {
-	register char *np, *cp;
+	REGISTER char *np, *cp;
 	char *name, *gp, *dp;
 	int k;
 	DIR *dirp;
@@ -4046,11 +4618,11 @@
 static char *
 generate(start1, end1, middle, end)
 char *start1;
-register char *end1;
+REGISTER char *end1;
 char *middle, *end;
 {
 	char *p;
-	register char *op, *xp;
+	REGISTER char *op, *xp;
 
 	p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2);
 	for (xp = start1; xp != end1;)
@@ -4065,10 +4637,10 @@
 
 static int
 anyspcl(wb)
-register struct wdblock *wb;
+REGISTER struct wdblock *wb;
 {
-	register int i;
-	register char **wd;
+	REGISTER int i;
+	REGISTER char **wd;
 
 	wd = wb->w_words;
 	for (i=0; i<wb->w_nword; i++)
@@ -4088,9 +4660,9 @@
 
 static struct wdblock *
 newword(nw)
-register int nw;
+REGISTER int nw;
 {
-	register struct wdblock *wb;
+	REGISTER struct wdblock *wb;
 
 	wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *));
 	wb->w_bsize = nw;
@@ -4101,10 +4673,10 @@
 static struct wdblock *
 addword(wd, wb)
 char *wd;
-register struct wdblock *wb;
+REGISTER struct wdblock *wb;
 {
-	register struct wdblock *wb2;
-	register int nw;
+	REGISTER struct wdblock *wb2;
+	REGISTER int nw;
 
 	if (wb == NULL)
 		wb = newword(NSTART);
@@ -4118,13 +4690,14 @@
 	wb->w_words[wb->w_nword++] = wd;
 	return(wb);
 }
+
 static
 char **
 getwords(wb)
-register struct wdblock *wb;
+REGISTER struct wdblock *wb;
 {
-	register char **wd;
-	register int nb;
+	REGISTER char **wd;
+	REGISTER int nb;
 
 	if (wb == NULL)
 		return((char **)NULL);
@@ -4157,7 +4730,7 @@
 glob1(base, lim)
 char *base, *lim;
 {
-	register char *i, *j;
+	REGISTER char *i, *j;
 	int v2;
 	char *lptr, *hptr;
 	int c;
@@ -4228,7 +4801,7 @@
 glob2(i, j)
 char *i, *j;
 {
-	register char *index1, *index2, c;
+	REGISTER char *index1, *index2, c;
 	int m;
 
 	m = globv;
@@ -4245,7 +4818,7 @@
 glob3(i, j, k)
 char *i, *j, *k;
 {
-	register char *index1, *index2, *index3;
+	REGISTER char *index1, *index2, *index3;
 	int c;
 	int m;
 
@@ -4269,7 +4842,7 @@
 
 static int my_getc( int ec)
 {
-	register int c;
+	REGISTER int c;
 
 	if(e.linep > elinep) {
 		while((c=readc()) != '\n' && c)
@@ -4308,9 +4881,12 @@
 static int
 readc()
 {
-	register int c;
+	REGISTER int c;
 
-	for (; e.iop >= e.iobase; e.iop--)
+	RCPRINTF(("READC: e.iop 0x%x, e.iobase 0x%x\n", e.iop, e.iobase));
+
+	for (; e.iop >= e.iobase; e.iop--) {
+		RCPRINTF(("READC: e.iop 0x%x, peekc 0x%x\n", e.iop, e.iop->peekc));
 		if ((c = e.iop->peekc) != '\0') {
 			e.iop->peekc = 0;
 			return(c);
@@ -4326,28 +4902,38 @@
 				        ioecho(c);
 			        return(e.iop->prev = c);
 		        }
-		        else if (e.iop->task == XIO && e.iop->prev != '\n') {
-			        e.iop->prev = 0;
-				if (e.iop == iostack)
-					ioecho('\n');
-			        return '\n';
-		        }
+		        else 
+					if (e.iop->task == XIO && e.iop->prev != '\n') {
+			        	e.iop->prev = 0;
+						if (e.iop == iostack)
+							ioecho('\n');
+			        	return '\n';
+		        	}
 		    }
 		    if (e.iop->task == XIO) {
-			if (multiline)
-			    return e.iop->prev = 0;
-			if (interactive && e.iop == iostack+1) {
+				if (multiline) {
+			    	return e.iop->prev = 0;
+				}
+				if (interactive && e.iop == iostack+1) {
 #ifdef CONFIG_FEATURE_COMMAND_EDITING
-			    current_prompt=prompt->value;
+			    	current_prompt=prompt->value;
 #else
-			    prs(prompt->value);
+			    	prs(prompt->value);
 #endif
-			}
+				}
 		    }
 		}
-	if (e.iop >= iostack)
+
+	} /* FOR */
+
+	if (e.iop >= iostack) {
+		RCPRINTF(("READC: return 0, e.iop 0x%x\n", e.iop));
 		return(0);
+	}
+
+	DBGPRINTF(("READC: leave()...\n"));
 	leave();
+
 	/* NOTREACHED */
 	return(0);
 }
@@ -4360,49 +4946,73 @@
 		write(2, &c, sizeof c);
 }
 
+
 static void
 pushio(struct ioarg *argp, int (*fn)(struct ioarg *))
 {
+	DBGPRINTF(("PUSHIO: argp 0x%x, argp->afid 0x%x, e.iop 0x%x\n", argp, argp->afid, \
e.iop)); +
+	/* Set env ptr for io source to next array spot and check for array overflow */
 	if (++e.iop >= &iostack[NPUSH]) {
 		e.iop--;
 		err("Shell input nested too deeply");
 		gflg++;
 		return;
 	}
-	e.iop->iofn = (int (*)(struct  ioarg *, struct io *))fn;
+
+	/* 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 */  
 	if (argp->afid != AFID_NOBUF)
 	  e.iop->argp = argp;
 	else {
-	  e.iop->argp  = ioargstack + (e.iop - iostack);
-	  *e.iop->argp = *argp;
-	  e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;
-	  if (isatty(e.iop->argp->afile) == 0 &&
-	      (e.iop == &iostack[0] ||
-	       lseek(e.iop->argp->afile, 0L, 1) != -1)) {
-	    if (++bufid == AFID_NOBUF)
-	      bufid = AFID_ID;
-	    e.iop->argp->afid  = bufid;
+
+	  e.iop->argp  = ioargstack + (e.iop - iostack);	/* MAL - index into stack */
+	  *e.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;
+	  else
+	  	e.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, 1) != -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 */
 	  }
+
+	DBGPRINTF(("PUSHIO: iostack 0x%x,  e.iop 0x%x, afbuf 0x%x\n", iostack, e.iop, \
e.iop->argp->afbuf)); +	DBGPRINTF(("PUSHIO: mbuf 0x%x, sbuf 0x%x, bid %d, e.iop \
0x%x\n", &mainbuf, &sharedbuf, bufid, e.iop)); +
 	}
 
 	e.iop->prev  = ~'\n';
 	e.iop->peekc = 0;
 	e.iop->xchar = 0;
 	e.iop->nlcount = 0;
+
 	if (fn == filechar || fn == linechar)
 		e.iop->task = XIO;
 	else if (fn == (int(*)(struct ioarg *))gravechar || fn == (int(*)(struct ioarg \
*))qgravechar)  e.iop->task = XGRAVE;
 	else
 		e.iop->task = XOTHER;
+
+	return;
 }
 
 static struct io *
 setbase(ip)
 struct io *ip;
 {
-	register struct io *xp;
+	REGISTER struct io *xp;
 
 	xp = e.iobase;
 	e.iobase = ip;
@@ -4418,9 +5028,9 @@
  */
 static int
 nlchar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register int c;
+	REGISTER int c;
 
 	if (ap->aword == NULL)
 		return(0);
@@ -4437,10 +5047,10 @@
  */
 static int
 wdchar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register char c;
-	register char **wl;
+	REGISTER char c;
+	REGISTER char **wl;
 
 	if ((wl = ap->awordlist) == NULL)
 		return(0);
@@ -4460,9 +5070,9 @@
  */
 static int
 dolchar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register char *wp;
+	REGISTER char *wp;
 
 	if ((wp = *ap->awordlist++) != NULL) {
 		PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);
@@ -4473,9 +5083,9 @@
 
 static int
 xxchar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register int c;
+	REGISTER int c;
 
 	if (ap->aword == NULL)
 		return(0);
@@ -4491,9 +5101,9 @@
  */
 static int
 strchar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register int c;
+	REGISTER int c;
 
 	if (ap->aword == NULL || (c = *ap->aword++) == 0)
 		return(0);
@@ -4505,9 +5115,9 @@
  */
 static int
 qstrchar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register int c;
+	REGISTER int c;
 
 	if (ap->aword == NULL || (c = *ap->aword++) == 0)
 		return(0);
@@ -4519,26 +5129,31 @@
  */
 static int
 filechar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register int i;
+	REGISTER int i;
 	char c;
 	struct iobuf *bp = ap->afbuf;
 
 	if (ap->afid != AFID_NOBUF) {
-	  if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
-	    if (i)
-	      lseek(ap->afile, ap->afpos, 0);
-	    i = safe_read(ap->afile, bp->buf, sizeof(bp->buf));
-	    if (i <= 0) {
-	      closef(ap->afile);
-	      return 0;
+		if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
+
+	    	if (i)
+	      		lseek(ap->afile, ap->afpos, 0);
+
+	    	i = safe_read(ap->afile, bp->buf, sizeof(bp->buf));
+
+	    	if (i <= 0) {
+	      		closef(ap->afile);
+	      		return 0;
+	    	}
+
+	    	bp->id = ap->afid;
+	    	bp->ebufp = (bp->bufp  = bp->buf) + i;
 	    }
-	    bp->id = ap->afid;
-	    bp->ebufp = (bp->bufp  = bp->buf) + i;
-	  }
-	  ap->afpos++;
-	  return *bp->bufp++ & 0177;
+
+	    ap->afpos++;
+	    return *bp->bufp++ & 0177;
 	}
 
 #ifdef CONFIG_FEATURE_COMMAND_EDITING
@@ -4556,9 +5171,10 @@
 	    return(c);
 	} else
 #endif
+
 	{
 		i = safe_read(ap->afile, &c, sizeof(c));
-		return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
+		return(i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0));
 	}
 }
 
@@ -4567,7 +5183,7 @@
  */
 static int
 herechar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
 	char c;
 
@@ -4589,7 +5205,7 @@
 struct ioarg *ap;
 struct io *iop;
 {
-	register int c;
+	REGISTER int c;
 
 	if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')
 		c = ' ';
@@ -4598,10 +5214,12 @@
 
 static int
 qgravechar(ap, iop)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 struct io *iop;
 {
-	register int c;
+	REGISTER int c;
+
+	DBGPRINTF3(("QGRAVECHAR: enter, ap=0x%x, iop=0x%x\n", ap, iop));
 
 	if (iop->xchar) {
 		if (iop->nlcount) {
@@ -4628,9 +5246,9 @@
  */
 static int
 linechar(ap)
-register struct ioarg *ap;
+REGISTER struct ioarg *ap;
 {
-	register int c;
+	REGISTER int c;
 
 	if ((c = filechar(ap)) == '\n') {
 		if (!multiline) {
@@ -4643,7 +5261,7 @@
 
 static void
 prs(s)
-register char *s;
+REGISTER char *s;
 {
 	if (*s)
 		write(2, s, strlen(s));
@@ -4658,7 +5276,7 @@
 
 static void
 closef(i)
-register int i;
+REGISTER int i;
 {
 	if (i > 2)
 		close(i);
@@ -4667,43 +5285,53 @@
 static void
 closeall()
 {
-	register int u;
+	REGISTER int u;
 
 	for (u=NUFILE; u<NOFILE;)
 		close(u++);
 }
 
+
 /*
  * remap fd into Shell's fd space
  */
 static int
 remap(fd)
-register int fd;
+REGISTER int fd;
 {
-	register int i;
+	REGISTER int i;
 	int map[NOFILE];
+	int newfd;
+
+
+	DBGPRINTF(("REMAP: fd=%d, e.iofd=%d\n", fd, e.iofd));
 
 	if (fd < e.iofd) {
 		for (i=0; i<NOFILE; i++)
 			map[i] = 0;
+
 		do {
 			map[fd] = 1;
-			fd = dup(fd);
+			newfd = dup(fd);
+			fd = newfd;
 		} while (fd >= 0 && fd < e.iofd);
+
 		for (i=0; i<NOFILE; i++)
 			if (map[i])
 				close(i);
+
 		if (fd < 0)
 			err("too many files open in shell");
 	}
+
 	return(fd);
 }
 
 static int
 openpipe(pv)
-register int *pv;
+REGISTER int *pv;
 {
-	register int i;
+	REGISTER int i;
 
 	if ((i = pipe(pv)) < 0)
 		err("can't create pipe - try again");
@@ -4712,7 +5340,7 @@
 
 static void
 closepipe(pv)
-register int *pv;
+REGISTER int *pv;
 {
 	if (pv != NULL) {
 		close(*pv++);
@@ -4728,17 +5356,21 @@
 
 static void
 markhere(s, iop)
-register char *s;
+REGISTER char *s;
 struct ioword *iop;
 {
-	register struct here *h, *lh;
+	REGISTER struct here *h, *lh;
+
+	DBGPRINTF7(("MARKHERE: enter, s=0x%x\n", s));
 
 	h = (struct here *) space(sizeof(struct here));
 	if (h == 0)
 		return;
+
 	h->h_tag = evalstr(s, DOSUB);
 	if (h->h_tag == 0)
 		return;
+
 	h->h_iop = iop;
 	iop->io_name = 0;
 	h->h_next = NULL;
@@ -4762,7 +5394,9 @@
 static void
 gethere()
 {
-	register struct here *h, *hp;
+	REGISTER struct here *h, *hp;
+
+	DBGPRINTF7(("GETHERE: enter...\n"));
 
 	/* Scan here files first leaving inhere list in place */
 	for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
@@ -4779,19 +5413,22 @@
 static void
 readhere(name, s, ec)
 char **name;
-register char *s;
+REGISTER char *s;
 int ec;
 {
 	int tf;
 	char tname[30] = ".msh_XXXXXX";
-	register int c;
+	REGISTER int c;
 	jmp_buf ev;
 	char myline [LINELIM+1];
 	char *thenext;
 
+	DBGPRINTF7(("READHERE: enter, name=0x%x, s=0x%x\n", name, s));
+
 	tf = mkstemp(tname);
 	if (tf < 0)
 		return;
+
 	*name = strsave(tname, areanum);
 	if (newenv(setjmp(errpt = ev)) != 0)
 		unlink(tname);
@@ -4839,18 +5476,22 @@
 char *hname;
 int xdoll;
 {
-	register int hf;
+	REGISTER int hf;
 	int tf;
 
 #if __GNUC__
 	/* Avoid longjmp clobbering */
 	(void) &tf;
 #endif
-	if (hname == 0)
+	if (hname == NULL)
 		return(-1);
+
+	DBGPRINTF7(("HEREIN: hname is %s, xdoll=%d\n", hname, xdoll));
+
 	hf = open(hname, 0);
 	if (hf < 0)
 		return (-1);
+
 	if (xdoll) {
 		char c;
 		char tname[30] = ".msh_XXXXXX";
@@ -4880,7 +5521,9 @@
 static void
 scraphere()
 {
-	register struct here *h;
+	REGISTER struct here *h;
+
+	DBGPRINTF7(("SCRAPHERE: enter...\n"));
 
 	for (h = inhere; h != NULL; h = h->h_next) {
 		if (h->h_iop && h->h_iop->io_name)
@@ -4894,7 +5537,9 @@
 freehere(area)
 int area;
 {
-	register struct here *h, *hl;
+	REGISTER struct here *h, *hl;
+
+	DBGPRINTF6(("FREEHERE: enter, area=%d\n", area));
 
 	hl = NULL;
 	for (h = acthere; h != NULL; h = h->h_next)



_______________________________________________
busybox mailing list
busybox@mail.busybox.net
http://codepoet.org/mailman/listinfo/busybox


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic