This is vodz' latest ash update.
diff --git a/ash.c b/ash.c
index e7f3516..99460d3 100644
--- a/ash.c
+++ b/ash.c
@@ -42,7 +42,7 @@
 
 /* Enable job control.  This allows you to run jobs in the background,
  * which is great when ash is being  used as an interactive shell, but
- * it completely useless for is all you are doing is running scripts.  
+ * it completely useless for is all you are doing is running scripts.
  * This adds about 2.5k on an x86 system. */
 #define JOBS
 
@@ -79,6 +79,9 @@
  * a little bit faster, but leaving this disabled will save you 2k. */
 #undef ASH_BBAPPS_AS_BUILTINS
 
+/* Optimize size vs speed as size */
+#define ASH_OPTIMIZE_FOR_SIZE
+
 /* Enable this to compile in extra debugging noise.  When debugging is
  * on, debugging info will be written to $HOME/trace and a quit signal
  * will generate a core dump. */
@@ -133,12 +136,6 @@
 #include "busybox.h"
 #include "cmdedit.h"
 
-/* if BB_PWD is defined, then disable ASH_PWD to save space */
-#ifdef BB_PWD
-#undef ASH_PWD
-#endif
-
-
 /*
  * This file was generated by the mksyntax program.
  */
@@ -230,7 +227,7 @@
 
 #define _DIAGASSERT(x)
 
-#define ATABSIZE 39
+
 
 #define S_DFL 1                 /* default signal handling (SIG_DFL) */
 #define S_CATCH 2               /* signal is caught */
@@ -258,7 +255,7 @@
 
 /* flags passed to redirect */
 #define REDIR_PUSH 01           /* save previous values of file descriptors */
-#define REDIR_BACKQ 02          /* save the command output in memory */
+#define REDIR_BACKQ 02          /* save the command output to pipe */
 
 /*
  * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
@@ -302,13 +299,16 @@
 static volatile int intpending;
 
 #define INTOFF suppressint++
-#ifdef ASH_BBAPPS_AS_BUILTINS
+#ifndef ASH_OPTIMIZE_FOR_SIZE
 #define INTON { if (--suppressint == 0 && intpending) onint(); }
+#define FORCEINTON {suppressint = 0; if (intpending) onint();}
 #else
 static void __inton (void);
+static void forceinton (void);
 #define INTON __inton()
+#define FORCEINTON forceinton()
 #endif
-#define FORCEINTON {suppressint = 0; if (intpending) onint();}
+
 #define CLEAR_PENDING_INT intpending = 0
 #define int_pending() intpending
 
@@ -326,6 +326,7 @@
 static void stunalloc (pointer);
 static void ungrabstackstr (char *, char *);
 static char * growstackstr(void);
+static char * makestrspace(size_t newlen);
 static char *sstrdup (const char *);
 
 /*
@@ -357,10 +358,13 @@
 #define stackblock() stacknxt
 #define stackblocksize() stacknleft
 #define STARTSTACKSTR(p)        p = stackblock(), sstrnleft = stackblocksize()
+
 #define STPUTC(c, p)    (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
 #define CHECKSTRSPACE(n, p)     { if (sstrnleft < n) p = makestrspace(n); }
-#define USTPUTC(c, p)   (--sstrnleft, *p++ = (c))
 #define STACKSTRNUL(p)  (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
+
+
+#define USTPUTC(c, p)   (--sstrnleft, *p++ = (c))
 #define STUNPUTC(p)     (++sstrnleft, --p)
 #define STTOPC(p)       p[-1]
 #define STADJUST(amount, p)     (p += (amount), sstrnleft -= (amount))
@@ -368,7 +372,6 @@
 
 #define ckfree(p)       free((pointer)(p))
 
-static char * makestrspace(size_t newlen);
 
 #ifdef DEBUG
 #define TRACE(param)    trace param
@@ -659,71 +662,18 @@
 	int optoff;             /* used by getopts */
 };
 
-struct output {
-#ifdef USE_GLIBC_STDIO
-	FILE *stream;
-#endif
-	char *nextc;
-	int nleft;
-	char *buf;
-	int bufsize;
-	int fd;
-	short flags;
-};
-
-#define OUTBUFSIZ BUFSIZ
-#define MEM_OUT -3              /* output to dynamically allocated memory */
-
-
-#ifdef USE_GLIBC_STDIO
-static struct output output = {NULL, NULL, 0, NULL, 0, 1, 0};
-static struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0};
-static struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0};
-#else
-static struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};
-static struct output errout = {NULL, 0, NULL, 0, 2, 0};
-static struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};
-#endif
-static struct output *out1 = &output;
-static struct output *out2 = &errout;
-
-#ifndef USE_GLIBC_STDIO
-static void outcslow (char, struct output *);
-#endif
 static void flushall (void);
-static void flushout (struct output *);
-static void freestdout (void);
-static void outfmt (struct output *, const char *, ...)
-    __attribute__((__format__(__printf__,2,3)));
+static void out2fmt (const char *, ...)
+    __attribute__((__format__(__printf__,1,2)));
 static void out1fmt (const char *, ...)
     __attribute__((__format__(__printf__,1,2)));
-static void fmtstr (char *, size_t, const char *, ...)
-    __attribute__((__format__(__printf__,3,4)));
-#ifndef USE_GLIBC_STDIO
-static void doformat (struct output *, const char *, va_list);
-#endif
 static int xwrite (int, const char *, int);
-#ifdef USE_GLIBC_STDIO
-static void initstreams (void);
-static void openmemout (void);
-static int __closememout (void);
-#endif
 
-static void outstr(const char *p, struct output *file);
+static void outstr (const char *p, FILE *file) { fputs(p, file); }
+static void out1str(const char *p) { outstr(p, stdout); }
+static void out2str(const char *p) { outstr(p, stderr); }
 
-#define OUTPUT_ERR 01           /* error occurred on output */
-
-#ifdef USE_GLIBC_STDIO
-#define outc(c, o)      putc((c), (o)->stream)
-#define doformat(d, f, a)       vfprintf((d)->stream, (f), (a))
-#else
-#define outc(c, file)   (--(file)->nleft < 0? outcslow((c), (file)) : (*(file)->nextc = (c), (file)->nextc++))
-#endif
-#define out1c(c)        outc((c), out1)
-#define out2c(c)        outc((c), out2)
-#define out1str(s)      outstr((s), out1)
-#define out2str(s)      outstr((s), out2)
-#define outerr(f)       ((f)->flags & OUTPUT_ERR)
+#define out2c(c)        putc((c), stderr)
 
 /* syntax table used when not in quotes */
 static const char basesyntax[257] = {
@@ -1389,6 +1339,8 @@
 #define ALIASINUSE      1
 #define ALIASDEAD       2
 
+#define ATABSIZE 39
+
 struct alias {
 	struct alias *next;
 	char *name;
@@ -1508,7 +1460,7 @@
 	while ((n = *++argv) != NULL) {
 		if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
 			if ((ap = *__lookupalias(n)) == NULL) {
-				outfmt(out2, "%s: %s not found\n", "alias", n);
+				out2fmt("%s: %s not found\n", "alias", n);
 				ret = 1;
 			} else
 				printalias(ap);
@@ -1535,7 +1487,7 @@
 	}
 	for (i = 0; *argptr; argptr++) {
 		if (unalias(*argptr)) {
-			outfmt(out2, "%s: %s not found\n", "unalias", *argptr);
+			out2fmt("%s: %s not found\n", "unalias", *argptr);
 			i = 1;
 		}
 	}
@@ -1653,7 +1605,7 @@
 static int hashcmd (int, char **);
 static int jobscmd (int, char **);
 static int localcmd (int, char **);
-#ifdef ASH_PWD
+#ifndef BB_PWD
 static int pwdcmd (int, char **);
 #endif
 static int readcmd (int, char **);
@@ -1725,7 +1677,7 @@
 	{ BUILTIN_REGULAR   "bg", bgcmd },
 #endif
 	{ BUILTIN_SPECIAL   "break", breakcmd },
-	{ BUILTIN_SPECIAL   "builtin", bltincmd },	/* Do not disable this builtin ever or bad things happen */
+	{ BUILTIN_SPECIAL   "builtin", bltincmd },
 	{ BUILTIN_REGULAR   "cd", cdcmd },
 #ifdef ASH_BBAPPS_AS_BUILTINS
 	{ BUILTIN_NOSPEC    "chdir", cdcmd },
@@ -1760,7 +1712,7 @@
 	{ BUILTIN_NOSPEC    "let", expcmd },
 #endif
 	{ BUILTIN_ASSIGN    "local", localcmd },
-#ifdef ASH_PWD
+#ifndef BB_PWD
 	{ BUILTIN_NOSPEC    "pwd", pwdcmd },
 #endif
 	{ BUILTIN_REGULAR   "read", readcmd },
@@ -2049,7 +2001,7 @@
 }
 
 
-#ifdef ASH_PWD
+#ifndef BB_PWD
 static int
 pwdcmd(argc, argv)
 	int argc;
@@ -2198,13 +2150,9 @@
 #endif
 	if (msg) {
 		if (commandname)
-			outfmt(&errout, "%s: ", commandname);
-		doformat(&errout, msg, ap);
-#if FLUSHERR
-		outc('\n', &errout);
-#else
-		outcslow('\n', &errout);
-#endif
+			out2fmt("%s: ", commandname);
+		vfprintf(stderr, msg, ap);
+		out2c('\n');
 	}
 	flushall();
 	exraise(cond);
@@ -2357,18 +2305,23 @@
 			return strerror(e);
 	}
 
-	fmtstr(buf, sizeof buf, "error %d", e);
+	snprintf(buf, sizeof buf, "error %d", e);
 	return buf;
 }
 
 
-#ifndef ASH_BBAPPS_AS_BUILTINS
+#ifdef ASH_OPTIMIZE_FOR_SIZE
 static void
 __inton() {
 	if (--suppressint == 0 && intpending) {
 		onint();
 	}
 }
+static void forceinton (void) {
+	suppressint = 0;
+	if (intpending)
+		onint();
+}
 #endif
 
 /* flags in argument to evaltree */
@@ -2394,11 +2347,7 @@
 static void evalsubshell (union node *, int);
 static void expredir (union node *);
 static void evalpipe (union node *);
-#ifdef notyet
-static void evalcommand (union node *, int, struct backcmd *);
-#else
 static void evalcommand (union node *, int);
-#endif
 static void prehash (union node *);
 static void eprintlist (struct strlist *);
 
@@ -2545,7 +2494,7 @@
 			(bcmd = find_builtin(n->narg.text)) &&
 			IS_BUILTIN_SPECIAL(bcmd)
 		) {
-			outfmt(out2, "%s is a special built-in\n", n->narg.text);
+			out2fmt("%s is a special built-in\n", n->narg.text);
 			exitstatus = 1;
 			break;
 		}
@@ -2563,19 +2512,12 @@
 		checkexit = 1;
 		break;
 	case NCMD:
-#ifdef notyet
-		evalcommand(n, flags, (struct backcmd *)NULL);
-#else
 		evalcommand(n, flags);
-#endif
 		checkexit = 1;
 		break;
 #ifdef DEBUG
 	default:
 		out1fmt("Node type = %d\n", n->type);
-#ifndef USE_GLIBC_STDIO
-		flushout(out1);
-#endif
 		break;
 #endif
 	}
@@ -2726,7 +2668,6 @@
 }
 
 
-
 /*
  * Compute the names of the files in a redirection list.
  */
@@ -2855,38 +2796,24 @@
 		exitstatus = 0;
 		goto out;
 	}
-#ifdef notyet
-	/*
-	 * For now we disable executing builtins in the same
-	 * context as the shell, because we are not keeping
-	 * enough state to recover from changes that are
-	 * supposed only to affect subshells. eg. echo "`cd /`"
-	 */
-	if (n->type == NCMD) {
-		exitstatus = oexitstatus;
-		evalcommand(n, EV_BACKCMD, result);
-	} else
-#endif
-	{
-		exitstatus = 0;
-		if (pipe(pip) < 0)
-			error("Pipe call failed");
-		jp = makejob(n, 1);
-		if (forkshell(jp, n, FORK_NOJOB) == 0) {
-			FORCEINTON;
-			close(pip[0]);
-			if (pip[1] != 1) {
-				close(1);
-				dup_as_newfd(pip[1], 1);
-				close(pip[1]);
-			}
-			eflag = 0;
-			evaltree(n, EV_EXIT);
+	exitstatus = 0;
+	if (pipe(pip) < 0)
+		error("Pipe call failed");
+	jp = makejob(n, 1);
+	if (forkshell(jp, n, FORK_NOJOB) == 0) {
+		FORCEINTON;
+		close(pip[0]);
+		if (pip[1] != 1) {
+			close(1);
+			dup_as_newfd(pip[1], 1);
+			close(pip[1]);
 		}
-		close(pip[1]);
-		result->fd = pip[0];
-		result->jp = jp;
+		eflag = 0;
+		evaltree(n, EV_EXIT);
 	}
+	close(pip[1]);
+	result->fd = pip[0];
+	result->jp = jp;
 out:
 	popstackmark(&smark);
 	TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
@@ -2913,16 +2840,7 @@
 }
 
 static void
-#ifdef notyet
-evalcommand(cmd, flags, backcmd)
-	union node *cmd;
-	int flags;
-	struct backcmd *backcmd;
-#else
-evalcommand(cmd, flags)
-	union node *cmd;
-	int flags;
-#endif
+evalcommand(union node *cmd, int flags)
 {
 	struct stackmark smark;
 	union node *argp;
@@ -2933,9 +2851,6 @@
 	char **envp;
 	struct strlist *sp;
 	int mode;
-#ifdef notyet
-	int pip[2];
-#endif
 	struct cmdentry cmdentry;
 	struct job *jp;
 	char *volatile savecmdname;
@@ -3006,19 +2921,10 @@
 
 	/* Print the command if xflag is set. */
 	if (xflag) {
-#ifdef FLUSHERR
-		outc('+', &errout);
-#else
-		outcslow('+', &errout);
-#endif
+		out2c('+');
 		eprintlist(varlist.list);
 		eprintlist(arglist.list);
-#ifdef FLUSHERR
-		outc('\n', &errout);
-		flushout(&errout);
-#else
-		outcslow('\n', &errout);
-#endif
+		out2c('\n');
 	}
 
 	/* Now locate the command. */
@@ -3046,9 +2952,6 @@
 			find_command(argv[0], &cmdentry, findflag, path);
 			if (cmdentry.cmdtype == CMDUNKNOWN) {   /* command not found */
 				exitstatus = 127;
-#ifdef FLUSHERR
-				flushout(&errout);
-#endif
 				goto out;
 			}
 			/* implement bltin and command here */
@@ -3066,11 +2969,8 @@
 					if (--argc == 0)
 						goto found;
 					if (!(bcmd = find_builtin(*argv))) {
-						outfmt(&errout, "%s: not found\n", *argv);
+						out2fmt("%s: not found\n", *argv);
 						exitstatus = 127;
-#ifdef FLUSHERR
-						flushout(&errout);
-#endif
 						goto out;
 					}
 					cmdentry.u.cmd = bcmd;
@@ -3110,35 +3010,11 @@
 	/* Fork off a child process if necessary. */
 	if (cmd->ncmd.backgnd
 	 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
-#ifdef notyet
-	 || ((flags & EV_BACKCMD) != 0
-	    && (cmdentry.cmdtype != CMDBUILTIN
-		 || cmdentry.u.bcmd == DOTCMD
-		 || cmdentry.u.bcmd == EVALCMD))
-#endif
 	) {
 		jp = makejob(cmd, 1);
 		mode = cmd->ncmd.backgnd;
-#ifdef notyet
-		if (flags & EV_BACKCMD) {
-			mode = FORK_NOJOB;
-			if (pipe(pip) < 0)
-				error("Pipe call failed");
-		}
-#endif
 		if (forkshell(jp, cmd, mode) != 0)
 			goto parent;    /* at end of routine */
-#ifdef notyet
-		if (flags & EV_BACKCMD) {
-			FORCEINTON;
-			close(pip[0]);
-			if (pip[1] != 1) {
-				close(1);
-				dup_as_newfd(pip[1], 1);
-				close(pip[1]);
-			}
-		}
-#endif
 		flags |= EV_EXIT;
 	}
 
@@ -3201,18 +3077,6 @@
 		trputs("builtin command:  ");  trargs(argv);
 #endif
 		mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
-#ifdef notyet
-		if (flags == EV_BACKCMD) {
-#ifdef USE_GLIBC_STDIO
-			openmemout();
-#else
-			memout.nleft = 0;
-			memout.nextc = memout.buf;
-			memout.bufsize = 64;
-#endif
-			mode |= REDIR_BACKQ;
-		}
-#endif
 		redirect(cmd->ncmd.redirect, mode);
 		savecmdname = commandname;
 		if (IS_BUILTIN_SPECIAL(firstbltin)) {
@@ -3234,10 +3098,6 @@
 		exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
 		flushall();
 cmddone:
-		exitstatus |= outerr(out1);
-		out1 = &output;
-		out2 = &errout;
-		freestdout();
 		cmdenviron = NULL;
 		if (e != EXSHELLPROC) {
 			commandname = savecmdname;
@@ -3256,23 +3116,6 @@
 		}
 		if (cmdentry.u.cmd != EXECCMD)
 			popredir();
-#ifdef notyet
-		if (flags == EV_BACKCMD) {
-			INTOFF;
-#ifdef USE_GLIBC_STDIO
-			if (__closememout())
-				error("__closememout() failed: %m");
-#endif
-			backcmd->buf = memout.buf;
-#ifdef USE_GLIBC_STDIO
-			backcmd->nleft = memout.bufsize;
-#else
-			backcmd->nleft = memout.nextc - memout.buf;
-#endif
-			memout.buf = NULL;
-			INTON;
-		}
-#endif
 	} else {
 #ifdef DEBUG
 		trputs("normal command:  ");  trargs(argv);
@@ -3291,12 +3134,6 @@
 		INTOFF;
 		exitstatus = waitforjob(jp);
 		INTON;
-#ifdef notyet
-	} else if (mode == 2) {
-		backcmd->fd = pip[0];
-		close(pip[1]);
-		backcmd->jp = jp;
-#endif
 	}
 
 out:
@@ -3477,7 +3314,7 @@
 eprintlist(struct strlist *sp)
 {
 	for (; sp; sp = sp->next) {
-		outfmt(&errout, " %s",sp->text);
+		out2fmt(" %s",sp->text);
 	}
 }
 /*
@@ -3653,7 +3490,7 @@
  * Nul characters in the input are silently discarded.
  */
 
-#ifdef ASH_BBAPPS_AS_BUILTINS
+#ifndef ASH_OPTIMIZE_FOR_SIZE
 #define pgetc_macro()   (--parsenleft >= 0? *parsenextc++ : preadbuffer())
 static int
 pgetc(void)
@@ -3793,6 +3630,21 @@
 	{
 	int e;
 
+#ifdef BB_FEATURE_SH_STANDALONE_SHELL
+	char *name = cmd;
+	char** argv_l=argv;
+	int argc_l;
+#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
+	name = get_last_path_component(name);
+#endif
+	argv_l=envp;
+	for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
+		putenv(*argv_l);
+	argv_l=argv;
+	for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
+	optind = 1;
+	run_applet_by_name(name, argc_l, argv);
+#endif
 	execve(cmd, argv, envp);
 	e = errno;
 	if (e == ENOEXEC) {
@@ -4126,7 +3978,7 @@
 	if (cmdp && updatetbl)
 		delete_cmd_entry();
 	if (act & DO_ERR)
-		outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
+		out2fmt("%s: %s\n", name, errmsg(e, E_EXEC));
 	entry->cmdtype = CMDUNKNOWN;
 	return;
 
@@ -4515,7 +4367,7 @@
 	}
 
 out:
-	out1c('\n');
+	putchar('\n');
 	return 0;
 }
 #endif
@@ -4543,16 +4395,16 @@
 			verbose_verify_only = 1;
 			break;
 		default:
-			outfmt(out2,
+			out2fmt(
 "command: nextopt returned character code 0%o\n", c);
 			return EX_SOFTWARE;
 		}
 
 	if (default_path + verify_only + verbose_verify_only > 1 ||
 	    !*argptr) {
-			outfmt(out2,
+			out2fmt(
 "command [-p] command [arg ...]\n");
-			outfmt(out2,
+			out2fmt(
 "command {-v|-V} command\n");
 			return EX_USAGE;
 	}
@@ -4940,7 +4792,7 @@
 	if (quotes)
 		rmescapes(p+2);
 	result = arith(p+2);
-	fmtstr(p, 12, "%d", result);
+	snprintf(p, 12, "%d", result);
 
 	while (*p++)
 		;
@@ -5099,7 +4951,7 @@
 
 	case VSQUESTION:
 		if (*p != CTLENDVAR) {
-			outfmt(&errout, snlfmt, startp);
+			out2fmt(snlfmt, startp);
 			error((char *)NULL);
 		}
 		error("%.*s: parameter %snot set", p - str - 1,
@@ -6260,13 +6112,6 @@
 	      basepf.nextc = basepf.buf = basebuf;
       }
 
-      /* from output.c: */
-      {
-#ifdef USE_GLIBC_STDIO
-	      initstreams();
-#endif
-      }
-
       /* from var.c: */
       {
 	      char **envp;
@@ -6279,7 +6124,7 @@
 		      }
 	      }
 
-	      fmtstr(ppid, sizeof(ppid), "%d", (int) getppid());
+	      snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
 	      setvar("PPID", ppid, 0);
       }
 }
@@ -6328,19 +6173,6 @@
 		      popredir();
       }
 
-      /* from output.c: */
-      {
-	      out1 = &output;
-	      out2 = &errout;
-#ifdef USE_GLIBC_STDIO
-	      if (memout.stream != NULL)
-		      __closememout();
-#endif
-	      if (memout.buf != NULL) {
-		      ckfree(memout.buf);
-		      memout.buf = NULL;
-	      }
-      }
 }
 
 
@@ -6513,10 +6345,7 @@
 	}
 	if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
 		return PEOF;
-	flushout(&output);
-#ifdef FLUSHERR
-	flushout(&errout);
-#endif
+	flushall();
 
 again:
 	if (parselleft <= 0) {
@@ -6557,9 +6386,6 @@
 
 	if (vflag) {
 		out2str(parsenextc);
-#ifdef FLUSHERR
-		flushout(out2);
-#endif
 	}
 
 	*q = savec;
@@ -6665,11 +6491,6 @@
 	return fd0_redirected != 0;
 }
 
-/*
- * We also keep track of where fileno2 goes.
- */
-static int fileno2 = 2;
-
 static int openredirect (union node *);
 static void dupredirect (union node *, int, char[10 ]);
 static int openhere (union node *);
@@ -6699,9 +6520,9 @@
 	if (enable) {
 		do { /* while we are in the background */
 #ifdef OLD_TTY_DRIVER
-			if (ioctl(fileno2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
+			if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
 #else
-			initialpgrp = tcgetpgrp(fileno2);
+			initialpgrp = tcgetpgrp(2);
 			if (initialpgrp < 0) {
 #endif
 				out2str("sh: can't access tty; job cenabletrol turned off\n");
@@ -6716,7 +6537,7 @@
 			}
 		} while (0);
 #ifdef OLD_TTY_DRIVER
-		if (ioctl(fileno2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
+		if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
 			out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n");
 			mflag = 0;
 			return;
@@ -6727,16 +6548,16 @@
 		setsignal(SIGTTIN);
 		setpgid(0, rootpid);
 #ifdef OLD_TTY_DRIVER
-		ioctl(fileno2, TIOCSPGRP, (char *)&rootpid);
+		ioctl(2, TIOCSPGRP, (char *)&rootpid);
 #else
-		tcsetpgrp(fileno2, rootpid);
+		tcsetpgrp(2, rootpid);
 #endif
 	} else { /* turning job cenabletrol off */
 		setpgid(0, initialpgrp);
 #ifdef OLD_TTY_DRIVER
-		ioctl(fileno2, TIOCSPGRP, (char *)&initialpgrp);
+		ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
 #else
-		tcsetpgrp(fileno2, initialpgrp);
+		tcsetpgrp(2, initialpgrp);
 #endif
 		setsignal(SIGTSTP);
 		setsignal(SIGTTOU);
@@ -6924,9 +6745,9 @@
 		error("job not created under job control");
 	pgrp = jp->ps[0].pid;
 #ifdef OLD_TTY_DRIVER
-	ioctl(fileno2, TIOCSPGRP, (char *)&pgrp);
+	ioctl(2, TIOCSPGRP, (char *)&pgrp);
 #else
-	tcsetpgrp(fileno2, pgrp);
+	tcsetpgrp(2, pgrp);
 #endif
 	restartjob(jp);
 	INTOFF;
@@ -7022,10 +6843,10 @@
 		procno = jp->nprocs;
 		for (ps = jp->ps ; ; ps++) {    /* for each process */
 			if (ps == jp->ps)
-				fmtstr(s, 64, "[%d] %ld ", jobno,
+				snprintf(s, 64, "[%d] %ld ", jobno,
 				    (long)ps->pid);
 			else
-				fmtstr(s, 64, "    %ld ",
+				snprintf(s, 64, "    %ld ",
 				    (long)ps->pid);
 			out1str(s);
 			col = strlen(s);
@@ -7033,7 +6854,7 @@
 			if (ps->status == -1) {
 				/* don't print anything */
 			} else if (WIFEXITED(ps->status)) {
-				fmtstr(s, 64, "Exit %d",
+				snprintf(s, 64, "Exit %d",
 				       WEXITSTATUS(ps->status));
 			} else {
 #ifdef JOBS
@@ -7045,7 +6866,7 @@
 				if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
 					strcpy(s, sys_siglist[i & 0x7F]);
 				else
-					fmtstr(s, 64, "Signal %d", i & 0x7F);
+					snprintf(s, 64, "Signal %d", i & 0x7F);
 				if (WCOREDUMP(ps->status))
 					strcat(s, " (core dumped)");
 			}
@@ -7315,10 +7136,10 @@
 			if (mode == FORK_FG) {
 				/*** this causes superfluous TIOCSPGRPS ***/
 #ifdef OLD_TTY_DRIVER
-				if (ioctl(fileno2, TIOCSPGRP, (char *)&pgrp) < 0)
+				if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
 					error("TIOCSPGRP failed, errno=%d", errno);
 #else
-				if (tcsetpgrp(fileno2, pgrp) < 0)
+				if (tcsetpgrp(2, pgrp) < 0)
 					error("tcsetpgrp failed, errno=%d", errno);
 #endif
 			}
@@ -7436,10 +7257,10 @@
 #ifdef JOBS
 	if (jp->jobctl) {
 #ifdef OLD_TTY_DRIVER
-		if (ioctl(fileno2, TIOCSPGRP, (char *)&mypgrp) < 0)
+		if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
 			error("TIOCSPGRP failed, errno=%d\n", errno);
 #else
-		if (tcsetpgrp(fileno2, mypgrp) < 0)
+		if (tcsetpgrp(2, mypgrp) < 0)
 			error("tcsetpgrp failed, errno=%d\n", errno);
 #endif
 	}
@@ -7549,22 +7370,19 @@
 
 		if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
 			if (thisjob != job)
-				outfmt(out2, "%d: ", pid);
+				out2fmt("%d: ", pid);
 #ifdef JOBS
 			if (sig == SIGTSTP && rootshell && iflag)
-				outfmt(out2, "%%%ld ",
+				out2fmt("%%%ld ",
 				    (long)(job - jobtab + 1));
 #endif
 			if (sig < NSIG && sys_siglist[sig])
 				out2str(sys_siglist[sig]);
 			else
-				outfmt(out2, "Signal %d", sig);
+				out2fmt("Signal %d", sig);
 			if (core)
 				out2str(" - core dumped");
 			out2c('\n');
-#ifdef FLUSHERR
-			flushout(&errout);
-#endif
 		} else {
 			TRACE(("Not printing status: status=%d, sig=%d\n",
 			       status, sig));
@@ -7889,10 +7707,8 @@
 		if (stat(p, &statb) < 0)
 			statb.st_size = 0;
 		if (statb.st_size > mailtime[i] && ! silent) {
-			outfmt(
-				&errout, snlfmt,
-				pathopt? pathopt : "you have mail"
-			);
+			out2fmt(snlfmt,
+				pathopt? pathopt : "you have mail");
 		}
 		mailtime[i] = statb.st_size;
 	}
@@ -7980,9 +7796,6 @@
 		reset();
 		if (exception == EXINT) {
 			out2c('\n');
-#ifdef FLUSHERR
-			flushout(out2);
-#endif
 		}
 		popstackmark(&smark);
 		FORCEINTON;                             /* enable interrupts */
@@ -8079,7 +7892,7 @@
 			inter++;
 			showjobs(1);
 			chkmail(0);
-			flushout(&output);
+			flushall();
 		}
 		n = parsecmd(inter);
 		/* showtree(n); DEBUG */
@@ -9607,7 +9420,7 @@
 				err |= setvarsafe("OPTARG", s, 0);
 			}
 			else {
-				outfmt(&errout, "Illegal option -%c\n", c);
+				out2fmt("Illegal option -%c\n", c);
 				(void) unsetvar("OPTARG");
 			}
 			c = '?';
@@ -9626,7 +9439,7 @@
 				c = ':';
 			}
 			else {
-				outfmt(&errout, "No arg for -%c option\n", c);
+				out2fmt("No arg for -%c option\n", c);
 				(void) unsetvar("OPTARG");
 				c = '?';
 			}
@@ -9648,7 +9461,7 @@
 	p = NULL;
 out:
 	*optoff = p ? p - *(optnext - 1) : -1;
-	fmtstr(s, sizeof(s), "%d", *myoptind);
+	snprintf(s, sizeof(s), "%d", *myoptind);
 	err |= setvarsafe("OPTIND", s, VNOFUNC);
 	s[0] = c;
 	s[1] = '\0';
@@ -9707,249 +9520,33 @@
 	return c;
 }
 
-
-/*
- * Shell output routines.  We use our own output routines because:
- *      When a builtin command is interrupted we have to discard
- *              any pending output.
- *      When a builtin command appears in back quotes, we want to
- *              save the output of the command in a region obtained
- *              via malloc, rather than doing a fork and reading the
- *              output of the command via a pipe.
- *      Our output routines may be smaller than the stdio routines.
- */
-
-
-
-#ifndef USE_GLIBC_STDIO
-static void __outstr (const char *, size_t, struct output*);
-#endif
-
-
-#ifndef USE_GLIBC_STDIO
-static void
-__outstr(const char *p, size_t len, struct output *dest) {
-	if (!dest->bufsize) {
-		dest->nleft = 0;
-	} else if (dest->buf == NULL) {
-		if (len > dest->bufsize && dest->fd == MEM_OUT) {
-			dest->bufsize = len;
-		}
-		INTOFF;
-		dest->buf = ckmalloc(dest->bufsize);
-		dest->nextc = dest->buf;
-		dest->nleft = dest->bufsize;
-		INTON;
-	} else if (dest->fd == MEM_OUT) {
-		int offset;
-
-		offset = dest->bufsize;
-		INTOFF;
-		if (dest->bufsize >= len) {
-			dest->bufsize <<= 1;
-		} else {
-			dest->bufsize += len;
-		}
-		dest->buf = ckrealloc(dest->buf, dest->bufsize);
-		dest->nleft = dest->bufsize - offset;
-		dest->nextc = dest->buf + offset;
-		INTON;
-	} else {
-		flushout(dest);
-	}
-
-	if (len < dest->nleft) {
-		dest->nleft -= len;
-		memcpy(dest->nextc, p, len);
-		dest->nextc += len;
-		return;
-	}
-
-	if (xwrite(dest->fd, p, len) < len)
-		dest->flags |= OUTPUT_ERR;
-}
-#endif
-
-
-static void
-outstr(const char *p, struct output *file)
-{
-#ifdef USE_GLIBC_STDIO
-	INTOFF;
-	fputs(p, file->stream);
-	INTON;
-#else
-	size_t len;
-
-	if (!*p) {
-		return;
-	}
-	len = strlen(p);
-	if ((file->nleft -= len) > 0) {
-		memcpy(file->nextc, p, len);
-		file->nextc += len;
-		return;
-	}
-	__outstr(p, len, file);
-#endif
-}
-
-
-#ifndef USE_GLIBC_STDIO
-
-
-static void
-outcslow(c, dest)
-	char c;
-	struct output *dest;
-	{
-	__outstr(&c, 1, dest);
-}
-#endif
-
-
 static void
 flushall() {
-	flushout(&output);
-#ifdef FLUSHERR
-	flushout(&errout);
-#endif
-}
-
-
-static void
-flushout(dest)
-	struct output *dest;
-	{
-#ifdef USE_GLIBC_STDIO
 	INTOFF;
-	fflush(dest->stream);
+	fflush(stdout);
 	INTON;
-#else
-	size_t len;
-
-	len = dest->nextc - dest->buf;
-	if (dest->buf == NULL || !len || dest->fd < 0)
-		return;
-	dest->nextc = dest->buf;
-	dest->nleft = dest->bufsize;
-	if (xwrite(dest->fd, dest->buf, len) < len)
-		dest->flags |= OUTPUT_ERR;
-#endif
 }
 
 
 static void
-freestdout() {
-	if (output.buf) {
-		INTOFF;
-		ckfree(output.buf);
-		output.buf = NULL;
-		output.nleft = 0;
-		INTON;
-	}
-	output.flags = 0;
-}
-
-
-static void
-#ifdef __STDC__
-outfmt(struct output *file, const char *fmt, ...)
-#else
-static void
-outfmt(va_alist)
-	va_dcl
-#endif
+out2fmt(const char *fmt, ...)
 {
 	va_list ap;
-#ifndef __STDC__
-	struct output *file;
-	const char *fmt;
-
-	va_start(ap);
-	file = va_arg(ap, struct output *);
-	fmt = va_arg(ap, const char *);
-#else
 	va_start(ap, fmt);
-#endif
-	doformat(file, fmt, ap);
+	vfprintf(stderr, fmt, ap);
 	va_end(ap);
 }
 
 
 static void
-#ifdef __STDC__
 out1fmt(const char *fmt, ...)
-#else
-out1fmt(va_alist)
-	va_dcl
-#endif
 {
 	va_list ap;
-#ifndef __STDC__
-	const char *fmt;
-
-	va_start(ap);
-	fmt = va_arg(ap, const char *);
-#else
 	va_start(ap, fmt);
-#endif
-	doformat(out1, fmt, ap);
+	vfprintf(stdout, fmt, ap);
 	va_end(ap);
 }
 
-static void
-#ifdef __STDC__
-fmtstr(char *outbuf, size_t length, const char *fmt, ...)
-#else
-fmtstr(va_alist)
-	va_dcl
-#endif
-{
-	va_list ap;
-#ifndef __STDC__
-	char *outbuf;
-	size_t length;
-	const char *fmt;
-
-	va_start(ap);
-	outbuf = va_arg(ap, char *);
-	length = va_arg(ap, size_t);
-	fmt = va_arg(ap, const char *);
-#else
-	va_start(ap, fmt);
-#endif
-	INTOFF;
-	vsnprintf(outbuf, length, fmt, ap);
-	INTON;
-}
-
-#ifndef USE_GLIBC_STDIO
-
-static void
-doformat(struct output *dest, const char *f, va_list ap)
-{
-	char *pm;
-	int size = BUFSIZ;
-
-	while(size) {
-		int nchars;
-
-		pm = xmalloc(size);
-		nchars = vsnprintf(pm, size, f, ap);
-		if(nchars > -1) {
-			outstr(pm, dest);
-			size = 0;
-			}
-		else
-			size *= 2;
-		free(pm);
-	}
-}
-#endif
-
-
-
 /*
  * Version of write which resumes after a signal is caught.
  */
@@ -9980,29 +9577,6 @@
 }
 
 
-#ifdef USE_GLIBC_STDIO
-static void initstreams() {
-	output.stream = stdout;
-	errout.stream = stderr;
-}
-
-
-static void
-openmemout() {
-	INTOFF;
-	memout.stream = open_memstream(&memout.buf, &memout.bufsize);
-	INTON;
-}
-
-
-static int
-__closememout() {
-	int error;
-	error = fclose(memout.stream);
-	memout.stream = NULL;
-	return error;
-}
-#endif
 /*
  * Shell command parser.
  */
@@ -10722,7 +10296,9 @@
 		c = pgetc_macro();
 		switch (c) {
 		case ' ': case '\t':
+#ifdef ASH_ALIAS
 		case PEOA:
+#endif
 			continue;
 		case '#':
 			while ((c = pgetc()) != '\n' && c != PEOF);
@@ -10969,9 +10545,11 @@
 			default:
 				if (varnest == 0)
 					goto endword;   /* exit outer loop */
-				if (c != PEOA) {
+#ifdef ASH_ALIAS
+				if (c != PEOA)
+#endif
 					USTPUTC(c, out);
-				}
+
 			}
 			c = pgetc_macro();
 		}
@@ -11459,10 +11037,10 @@
 	char msg[64];
 
 	if (token >= 0) {
-		fmtstr(msg, 64, "%s unexpected (expecting %s)",
+		snprintf(msg, 64, "%s unexpected (expecting %s)",
 			tokname[lasttoken], tokname[token]);
 	} else {
-		fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]);
+		snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
 	}
 	synerror(msg);
 	/* NOTREACHED */
@@ -11473,8 +11051,8 @@
 synerror(const char *msg)
 {
 	if (commandname)
-		outfmt(&errout, "%s: %d: ", commandname, startlinno);
-	outfmt(&errout, "Syntax error: %s\n", msg);
+		out2fmt("%s: %d: ", commandname, startlinno);
+	out2fmt("Syntax error: %s\n", msg);
 	error((char *)NULL);
 	/* NOTREACHED */
 }
@@ -11484,7 +11062,7 @@
  * called by editline -- any expansions to the prompt
  *    should be added here.
  */
-static const char *
+static inline const char *
 getprompt(void *unused)
 {
 	switch (whichprompt) {
@@ -11525,7 +11103,7 @@
  * old file descriptors are stashed away so that the redirection can be
  * undone by calling popredir.  If the REDIR_BACKQ flag is set, then the
  * standard output, and the standard error if it becomes a duplicate of
- * stdout, is saved in memory.
+ * stdout.
  */
 
 static void
@@ -11560,8 +11138,7 @@
 
 		INTOFF;
 		newfd = openredirect(n);
-		if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) ||
-		    (fd == fileno2)) {
+		if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
 			if (newfd == fd) {
 				try++;
 			} else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
@@ -11587,9 +11164,6 @@
 				if (flags & REDIR_PUSH) {
 					sv->renamed[fd] = i;
 				}
-				if (fd == fileno2) {
-					fileno2 = i;
-				}
 			}
 		} else if (fd != newfd) {
 			close(fd);
@@ -11600,10 +11174,6 @@
 			dupredirect(n, newfd, memory);
 		INTON;
 	}
-	if (memory[1])
-		out1 = &memout;
-	if (memory[2])
-		out2 = &memout;
 }
 
 
@@ -11765,9 +11335,6 @@
 				dup_as_newfd(rp->renamed[i], i);
 				close(rp->renamed[i]);
 			}
-			if (rp->renamed[i] == fileno2) {
-				fileno2 = i;
-			}
 		}
 	}
 	redirlist = rp->next;
@@ -11788,17 +11355,10 @@
 		for (i = 0 ; i < 10 ; i++) {
 			if (rp->renamed[i] >= 0) {
 				close(rp->renamed[i]);
-				if (rp->renamed[i] == fileno2) {
-					fileno2 = -1;
-				}
 			}
 			rp->renamed[i] = EMPTY;
 		}
 	}
-	if (fileno2 != 2 && fileno2 >= 0) {
-		close(fileno2);
-		fileno2 = -1;
-	}
 }
 
 
@@ -13528,7 +13088,7 @@
 /*
  * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
  * This file contains code for the times builtin.
- * $Id: ash.c,v 1.5 2001/07/05 05:24:12 andersen Exp $
+ * $Id: ash.c,v 1.6 2001/07/06 04:26:23 andersen Exp $
  */
 static int timescmd (int argc, char **argv)
 {