aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-07-06 04:26:23 +0000
committerEric Andersen <andersen@codepoet.org>2001-07-06 04:26:23 +0000
commit3102ac4b582b144ad0e04c7cbe511c25c1175ee2 (patch)
tree4f6d1fa7ff379817afc74301bac06baf9d0d6bd7
parent5009f90ea24224638af6945552012ce60efb3cea (diff)
downloadbusybox-w32-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.tar.gz
busybox-w32-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.tar.bz2
busybox-w32-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.zip
This is vodz' latest ash update.
-rw-r--r--ash.c702
-rw-r--r--shell/ash.c702
2 files changed, 262 insertions, 1142 deletions
diff --git a/ash.c b/ash.c
index e7f351608..99460d3d6 100644
--- a/ash.c
+++ b/ash.c
@@ -42,7 +42,7 @@
42 42
43/* Enable job control. This allows you to run jobs in the background, 43/* Enable job control. This allows you to run jobs in the background,
44 * which is great when ash is being used as an interactive shell, but 44 * which is great when ash is being used as an interactive shell, but
45 * it completely useless for is all you are doing is running scripts. 45 * it completely useless for is all you are doing is running scripts.
46 * This adds about 2.5k on an x86 system. */ 46 * This adds about 2.5k on an x86 system. */
47#define JOBS 47#define JOBS
48 48
@@ -79,6 +79,9 @@
79 * a little bit faster, but leaving this disabled will save you 2k. */ 79 * a little bit faster, but leaving this disabled will save you 2k. */
80#undef ASH_BBAPPS_AS_BUILTINS 80#undef ASH_BBAPPS_AS_BUILTINS
81 81
82/* Optimize size vs speed as size */
83#define ASH_OPTIMIZE_FOR_SIZE
84
82/* Enable this to compile in extra debugging noise. When debugging is 85/* Enable this to compile in extra debugging noise. When debugging is
83 * on, debugging info will be written to $HOME/trace and a quit signal 86 * on, debugging info will be written to $HOME/trace and a quit signal
84 * will generate a core dump. */ 87 * will generate a core dump. */
@@ -133,12 +136,6 @@
133#include "busybox.h" 136#include "busybox.h"
134#include "cmdedit.h" 137#include "cmdedit.h"
135 138
136/* if BB_PWD is defined, then disable ASH_PWD to save space */
137#ifdef BB_PWD
138#undef ASH_PWD
139#endif
140
141
142/* 139/*
143 * This file was generated by the mksyntax program. 140 * This file was generated by the mksyntax program.
144 */ 141 */
@@ -230,7 +227,7 @@
230 227
231#define _DIAGASSERT(x) 228#define _DIAGASSERT(x)
232 229
233#define ATABSIZE 39 230
234 231
235#define S_DFL 1 /* default signal handling (SIG_DFL) */ 232#define S_DFL 1 /* default signal handling (SIG_DFL) */
236#define S_CATCH 2 /* signal is caught */ 233#define S_CATCH 2 /* signal is caught */
@@ -258,7 +255,7 @@
258 255
259/* flags passed to redirect */ 256/* flags passed to redirect */
260#define REDIR_PUSH 01 /* save previous values of file descriptors */ 257#define REDIR_PUSH 01 /* save previous values of file descriptors */
261#define REDIR_BACKQ 02 /* save the command output in memory */ 258#define REDIR_BACKQ 02 /* save the command output to pipe */
262 259
263/* 260/*
264 * BSD setjmp saves the signal mask, which violates ANSI C and takes time, 261 * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
@@ -302,13 +299,16 @@ static volatile int suppressint;
302static volatile int intpending; 299static volatile int intpending;
303 300
304#define INTOFF suppressint++ 301#define INTOFF suppressint++
305#ifdef ASH_BBAPPS_AS_BUILTINS 302#ifndef ASH_OPTIMIZE_FOR_SIZE
306#define INTON { if (--suppressint == 0 && intpending) onint(); } 303#define INTON { if (--suppressint == 0 && intpending) onint(); }
304#define FORCEINTON {suppressint = 0; if (intpending) onint();}
307#else 305#else
308static void __inton (void); 306static void __inton (void);
307static void forceinton (void);
309#define INTON __inton() 308#define INTON __inton()
309#define FORCEINTON forceinton()
310#endif 310#endif
311#define FORCEINTON {suppressint = 0; if (intpending) onint();} 311
312#define CLEAR_PENDING_INT intpending = 0 312#define CLEAR_PENDING_INT intpending = 0
313#define int_pending() intpending 313#define int_pending() intpending
314 314
@@ -326,6 +326,7 @@ static pointer stalloc (int);
326static void stunalloc (pointer); 326static void stunalloc (pointer);
327static void ungrabstackstr (char *, char *); 327static void ungrabstackstr (char *, char *);
328static char * growstackstr(void); 328static char * growstackstr(void);
329static char * makestrspace(size_t newlen);
329static char *sstrdup (const char *); 330static char *sstrdup (const char *);
330 331
331/* 332/*
@@ -357,10 +358,13 @@ static int stacknleft = MINSIZE;
357#define stackblock() stacknxt 358#define stackblock() stacknxt
358#define stackblocksize() stacknleft 359#define stackblocksize() stacknleft
359#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize() 360#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
361
360#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c))) 362#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
361#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); } 363#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); }
362#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
363#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0')) 364#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
365
366
367#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
364#define STUNPUTC(p) (++sstrnleft, --p) 368#define STUNPUTC(p) (++sstrnleft, --p)
365#define STTOPC(p) p[-1] 369#define STTOPC(p) p[-1]
366#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount)) 370#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
@@ -368,7 +372,6 @@ static int stacknleft = MINSIZE;
368 372
369#define ckfree(p) free((pointer)(p)) 373#define ckfree(p) free((pointer)(p))
370 374
371static char * makestrspace(size_t newlen);
372 375
373#ifdef DEBUG 376#ifdef DEBUG
374#define TRACE(param) trace param 377#define TRACE(param) trace param
@@ -659,71 +662,18 @@ struct shparam {
659 int optoff; /* used by getopts */ 662 int optoff; /* used by getopts */
660}; 663};
661 664
662struct output {
663#ifdef USE_GLIBC_STDIO
664 FILE *stream;
665#endif
666 char *nextc;
667 int nleft;
668 char *buf;
669 int bufsize;
670 int fd;
671 short flags;
672};
673
674#define OUTBUFSIZ BUFSIZ
675#define MEM_OUT -3 /* output to dynamically allocated memory */
676
677
678#ifdef USE_GLIBC_STDIO
679static struct output output = {NULL, NULL, 0, NULL, 0, 1, 0};
680static struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0};
681static struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0};
682#else
683static struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};
684static struct output errout = {NULL, 0, NULL, 0, 2, 0};
685static struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};
686#endif
687static struct output *out1 = &output;
688static struct output *out2 = &errout;
689
690#ifndef USE_GLIBC_STDIO
691static void outcslow (char, struct output *);
692#endif
693static void flushall (void); 665static void flushall (void);
694static void flushout (struct output *); 666static void out2fmt (const char *, ...)
695static void freestdout (void); 667 __attribute__((__format__(__printf__,1,2)));
696static void outfmt (struct output *, const char *, ...)
697 __attribute__((__format__(__printf__,2,3)));
698static void out1fmt (const char *, ...) 668static void out1fmt (const char *, ...)
699 __attribute__((__format__(__printf__,1,2))); 669 __attribute__((__format__(__printf__,1,2)));
700static void fmtstr (char *, size_t, const char *, ...)
701 __attribute__((__format__(__printf__,3,4)));
702#ifndef USE_GLIBC_STDIO
703static void doformat (struct output *, const char *, va_list);
704#endif
705static int xwrite (int, const char *, int); 670static int xwrite (int, const char *, int);
706#ifdef USE_GLIBC_STDIO
707static void initstreams (void);
708static void openmemout (void);
709static int __closememout (void);
710#endif
711 671
712static void outstr(const char *p, struct output *file); 672static void outstr (const char *p, FILE *file) { fputs(p, file); }
673static void out1str(const char *p) { outstr(p, stdout); }
674static void out2str(const char *p) { outstr(p, stderr); }
713 675
714#define OUTPUT_ERR 01 /* error occurred on output */ 676#define out2c(c) putc((c), stderr)
715
716#ifdef USE_GLIBC_STDIO
717#define outc(c, o) putc((c), (o)->stream)
718#define doformat(d, f, a) vfprintf((d)->stream, (f), (a))
719#else
720#define outc(c, file) (--(file)->nleft < 0? outcslow((c), (file)) : (*(file)->nextc = (c), (file)->nextc++))
721#endif
722#define out1c(c) outc((c), out1)
723#define out2c(c) outc((c), out2)
724#define out1str(s) outstr((s), out1)
725#define out2str(s) outstr((s), out2)
726#define outerr(f) ((f)->flags & OUTPUT_ERR)
727 677
728/* syntax table used when not in quotes */ 678/* syntax table used when not in quotes */
729static const char basesyntax[257] = { 679static const char basesyntax[257] = {
@@ -1389,6 +1339,8 @@ static char *minusc; /* argument to -c option */
1389#define ALIASINUSE 1 1339#define ALIASINUSE 1
1390#define ALIASDEAD 2 1340#define ALIASDEAD 2
1391 1341
1342#define ATABSIZE 39
1343
1392struct alias { 1344struct alias {
1393 struct alias *next; 1345 struct alias *next;
1394 char *name; 1346 char *name;
@@ -1508,7 +1460,7 @@ aliascmd(int argc, char **argv)
1508 while ((n = *++argv) != NULL) { 1460 while ((n = *++argv) != NULL) {
1509 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ 1461 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
1510 if ((ap = *__lookupalias(n)) == NULL) { 1462 if ((ap = *__lookupalias(n)) == NULL) {
1511 outfmt(out2, "%s: %s not found\n", "alias", n); 1463 out2fmt("%s: %s not found\n", "alias", n);
1512 ret = 1; 1464 ret = 1;
1513 } else 1465 } else
1514 printalias(ap); 1466 printalias(ap);
@@ -1535,7 +1487,7 @@ unaliascmd(int argc, char **argv)
1535 } 1487 }
1536 for (i = 0; *argptr; argptr++) { 1488 for (i = 0; *argptr; argptr++) {
1537 if (unalias(*argptr)) { 1489 if (unalias(*argptr)) {
1538 outfmt(out2, "%s: %s not found\n", "unalias", *argptr); 1490 out2fmt("%s: %s not found\n", "unalias", *argptr);
1539 i = 1; 1491 i = 1;
1540 } 1492 }
1541 } 1493 }
@@ -1653,7 +1605,7 @@ static int histcmd (int, char **);
1653static int hashcmd (int, char **); 1605static int hashcmd (int, char **);
1654static int jobscmd (int, char **); 1606static int jobscmd (int, char **);
1655static int localcmd (int, char **); 1607static int localcmd (int, char **);
1656#ifdef ASH_PWD 1608#ifndef BB_PWD
1657static int pwdcmd (int, char **); 1609static int pwdcmd (int, char **);
1658#endif 1610#endif
1659static int readcmd (int, char **); 1611static int readcmd (int, char **);
@@ -1725,7 +1677,7 @@ static const struct builtincmd builtincmds[] = {
1725 { BUILTIN_REGULAR "bg", bgcmd }, 1677 { BUILTIN_REGULAR "bg", bgcmd },
1726#endif 1678#endif
1727 { BUILTIN_SPECIAL "break", breakcmd }, 1679 { BUILTIN_SPECIAL "break", breakcmd },
1728 { BUILTIN_SPECIAL "builtin", bltincmd }, /* Do not disable this builtin ever or bad things happen */ 1680 { BUILTIN_SPECIAL "builtin", bltincmd },
1729 { BUILTIN_REGULAR "cd", cdcmd }, 1681 { BUILTIN_REGULAR "cd", cdcmd },
1730#ifdef ASH_BBAPPS_AS_BUILTINS 1682#ifdef ASH_BBAPPS_AS_BUILTINS
1731 { BUILTIN_NOSPEC "chdir", cdcmd }, 1683 { BUILTIN_NOSPEC "chdir", cdcmd },
@@ -1760,7 +1712,7 @@ static const struct builtincmd builtincmds[] = {
1760 { BUILTIN_NOSPEC "let", expcmd }, 1712 { BUILTIN_NOSPEC "let", expcmd },
1761#endif 1713#endif
1762 { BUILTIN_ASSIGN "local", localcmd }, 1714 { BUILTIN_ASSIGN "local", localcmd },
1763#ifdef ASH_PWD 1715#ifndef BB_PWD
1764 { BUILTIN_NOSPEC "pwd", pwdcmd }, 1716 { BUILTIN_NOSPEC "pwd", pwdcmd },
1765#endif 1717#endif
1766 { BUILTIN_REGULAR "read", readcmd }, 1718 { BUILTIN_REGULAR "read", readcmd },
@@ -2049,7 +2001,7 @@ updatepwd(const char *dir)
2049} 2001}
2050 2002
2051 2003
2052#ifdef ASH_PWD 2004#ifndef BB_PWD
2053static int 2005static int
2054pwdcmd(argc, argv) 2006pwdcmd(argc, argv)
2055 int argc; 2007 int argc;
@@ -2198,13 +2150,9 @@ exverror(int cond, const char *msg, va_list ap)
2198#endif 2150#endif
2199 if (msg) { 2151 if (msg) {
2200 if (commandname) 2152 if (commandname)
2201 outfmt(&errout, "%s: ", commandname); 2153 out2fmt("%s: ", commandname);
2202 doformat(&errout, msg, ap); 2154 vfprintf(stderr, msg, ap);
2203#if FLUSHERR 2155 out2c('\n');
2204 outc('\n', &errout);
2205#else
2206 outcslow('\n', &errout);
2207#endif
2208 } 2156 }
2209 flushall(); 2157 flushall();
2210 exraise(cond); 2158 exraise(cond);
@@ -2357,18 +2305,23 @@ errmsg(int e, int action)
2357 return strerror(e); 2305 return strerror(e);
2358 } 2306 }
2359 2307
2360 fmtstr(buf, sizeof buf, "error %d", e); 2308 snprintf(buf, sizeof buf, "error %d", e);
2361 return buf; 2309 return buf;
2362} 2310}
2363 2311
2364 2312
2365#ifndef ASH_BBAPPS_AS_BUILTINS 2313#ifdef ASH_OPTIMIZE_FOR_SIZE
2366static void 2314static void
2367__inton() { 2315__inton() {
2368 if (--suppressint == 0 && intpending) { 2316 if (--suppressint == 0 && intpending) {
2369 onint(); 2317 onint();
2370 } 2318 }
2371} 2319}
2320static void forceinton (void) {
2321 suppressint = 0;
2322 if (intpending)
2323 onint();
2324}
2372#endif 2325#endif
2373 2326
2374/* flags in argument to evaltree */ 2327/* flags in argument to evaltree */
@@ -2394,11 +2347,7 @@ static void evalcase (union node *, int);
2394static void evalsubshell (union node *, int); 2347static void evalsubshell (union node *, int);
2395static void expredir (union node *); 2348static void expredir (union node *);
2396static void evalpipe (union node *); 2349static void evalpipe (union node *);
2397#ifdef notyet
2398static void evalcommand (union node *, int, struct backcmd *);
2399#else
2400static void evalcommand (union node *, int); 2350static void evalcommand (union node *, int);
2401#endif
2402static void prehash (union node *); 2351static void prehash (union node *);
2403static void eprintlist (struct strlist *); 2352static void eprintlist (struct strlist *);
2404 2353
@@ -2545,7 +2494,7 @@ evaltree(n, flags)
2545 (bcmd = find_builtin(n->narg.text)) && 2494 (bcmd = find_builtin(n->narg.text)) &&
2546 IS_BUILTIN_SPECIAL(bcmd) 2495 IS_BUILTIN_SPECIAL(bcmd)
2547 ) { 2496 ) {
2548 outfmt(out2, "%s is a special built-in\n", n->narg.text); 2497 out2fmt("%s is a special built-in\n", n->narg.text);
2549 exitstatus = 1; 2498 exitstatus = 1;
2550 break; 2499 break;
2551 } 2500 }
@@ -2563,19 +2512,12 @@ evaltree(n, flags)
2563 checkexit = 1; 2512 checkexit = 1;
2564 break; 2513 break;
2565 case NCMD: 2514 case NCMD:
2566#ifdef notyet
2567 evalcommand(n, flags, (struct backcmd *)NULL);
2568#else
2569 evalcommand(n, flags); 2515 evalcommand(n, flags);
2570#endif
2571 checkexit = 1; 2516 checkexit = 1;
2572 break; 2517 break;
2573#ifdef DEBUG 2518#ifdef DEBUG
2574 default: 2519 default:
2575 out1fmt("Node type = %d\n", n->type); 2520 out1fmt("Node type = %d\n", n->type);
2576#ifndef USE_GLIBC_STDIO
2577 flushout(out1);
2578#endif
2579 break; 2521 break;
2580#endif 2522#endif
2581 } 2523 }
@@ -2726,7 +2668,6 @@ evalsubshell(n, flags)
2726} 2668}
2727 2669
2728 2670
2729
2730/* 2671/*
2731 * Compute the names of the files in a redirection list. 2672 * Compute the names of the files in a redirection list.
2732 */ 2673 */
@@ -2855,38 +2796,24 @@ evalbackcmd(union node *n, struct backcmd *result)
2855 exitstatus = 0; 2796 exitstatus = 0;
2856 goto out; 2797 goto out;
2857 } 2798 }
2858#ifdef notyet 2799 exitstatus = 0;
2859 /* 2800 if (pipe(pip) < 0)
2860 * For now we disable executing builtins in the same 2801 error("Pipe call failed");
2861 * context as the shell, because we are not keeping 2802 jp = makejob(n, 1);
2862 * enough state to recover from changes that are 2803 if (forkshell(jp, n, FORK_NOJOB) == 0) {
2863 * supposed only to affect subshells. eg. echo "`cd /`" 2804 FORCEINTON;
2864 */ 2805 close(pip[0]);
2865 if (n->type == NCMD) { 2806 if (pip[1] != 1) {
2866 exitstatus = oexitstatus; 2807 close(1);
2867 evalcommand(n, EV_BACKCMD, result); 2808 dup_as_newfd(pip[1], 1);
2868 } else 2809 close(pip[1]);
2869#endif
2870 {
2871 exitstatus = 0;
2872 if (pipe(pip) < 0)
2873 error("Pipe call failed");
2874 jp = makejob(n, 1);
2875 if (forkshell(jp, n, FORK_NOJOB) == 0) {
2876 FORCEINTON;
2877 close(pip[0]);
2878 if (pip[1] != 1) {
2879 close(1);
2880 dup_as_newfd(pip[1], 1);
2881 close(pip[1]);
2882 }
2883 eflag = 0;
2884 evaltree(n, EV_EXIT);
2885 } 2810 }
2886 close(pip[1]); 2811 eflag = 0;
2887 result->fd = pip[0]; 2812 evaltree(n, EV_EXIT);
2888 result->jp = jp;
2889 } 2813 }
2814 close(pip[1]);
2815 result->fd = pip[0];
2816 result->jp = jp;
2890out: 2817out:
2891 popstackmark(&smark); 2818 popstackmark(&smark);
2892 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", 2819 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
@@ -2913,16 +2840,7 @@ isassignment(const char *word) {
2913} 2840}
2914 2841
2915static void 2842static void
2916#ifdef notyet 2843evalcommand(union node *cmd, int flags)
2917evalcommand(cmd, flags, backcmd)
2918 union node *cmd;
2919 int flags;
2920 struct backcmd *backcmd;
2921#else
2922evalcommand(cmd, flags)
2923 union node *cmd;
2924 int flags;
2925#endif
2926{ 2844{
2927 struct stackmark smark; 2845 struct stackmark smark;
2928 union node *argp; 2846 union node *argp;
@@ -2933,9 +2851,6 @@ evalcommand(cmd, flags)
2933 char **envp; 2851 char **envp;
2934 struct strlist *sp; 2852 struct strlist *sp;
2935 int mode; 2853 int mode;
2936#ifdef notyet
2937 int pip[2];
2938#endif
2939 struct cmdentry cmdentry; 2854 struct cmdentry cmdentry;
2940 struct job *jp; 2855 struct job *jp;
2941 char *volatile savecmdname; 2856 char *volatile savecmdname;
@@ -3006,19 +2921,10 @@ evalcommand(cmd, flags)
3006 2921
3007 /* Print the command if xflag is set. */ 2922 /* Print the command if xflag is set. */
3008 if (xflag) { 2923 if (xflag) {
3009#ifdef FLUSHERR 2924 out2c('+');
3010 outc('+', &errout);
3011#else
3012 outcslow('+', &errout);
3013#endif
3014 eprintlist(varlist.list); 2925 eprintlist(varlist.list);
3015 eprintlist(arglist.list); 2926 eprintlist(arglist.list);
3016#ifdef FLUSHERR 2927 out2c('\n');
3017 outc('\n', &errout);
3018 flushout(&errout);
3019#else
3020 outcslow('\n', &errout);
3021#endif
3022 } 2928 }
3023 2929
3024 /* Now locate the command. */ 2930 /* Now locate the command. */
@@ -3046,9 +2952,6 @@ evalcommand(cmd, flags)
3046 find_command(argv[0], &cmdentry, findflag, path); 2952 find_command(argv[0], &cmdentry, findflag, path);
3047 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ 2953 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
3048 exitstatus = 127; 2954 exitstatus = 127;
3049#ifdef FLUSHERR
3050 flushout(&errout);
3051#endif
3052 goto out; 2955 goto out;
3053 } 2956 }
3054 /* implement bltin and command here */ 2957 /* implement bltin and command here */
@@ -3066,11 +2969,8 @@ evalcommand(cmd, flags)
3066 if (--argc == 0) 2969 if (--argc == 0)
3067 goto found; 2970 goto found;
3068 if (!(bcmd = find_builtin(*argv))) { 2971 if (!(bcmd = find_builtin(*argv))) {
3069 outfmt(&errout, "%s: not found\n", *argv); 2972 out2fmt("%s: not found\n", *argv);
3070 exitstatus = 127; 2973 exitstatus = 127;
3071#ifdef FLUSHERR
3072 flushout(&errout);
3073#endif
3074 goto out; 2974 goto out;
3075 } 2975 }
3076 cmdentry.u.cmd = bcmd; 2976 cmdentry.u.cmd = bcmd;
@@ -3110,35 +3010,11 @@ found:
3110 /* Fork off a child process if necessary. */ 3010 /* Fork off a child process if necessary. */
3111 if (cmd->ncmd.backgnd 3011 if (cmd->ncmd.backgnd
3112 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) 3012 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
3113#ifdef notyet
3114 || ((flags & EV_BACKCMD) != 0
3115 && (cmdentry.cmdtype != CMDBUILTIN
3116 || cmdentry.u.bcmd == DOTCMD
3117 || cmdentry.u.bcmd == EVALCMD))
3118#endif
3119 ) { 3013 ) {
3120 jp = makejob(cmd, 1); 3014 jp = makejob(cmd, 1);
3121 mode = cmd->ncmd.backgnd; 3015 mode = cmd->ncmd.backgnd;
3122#ifdef notyet
3123 if (flags & EV_BACKCMD) {
3124 mode = FORK_NOJOB;
3125 if (pipe(pip) < 0)
3126 error("Pipe call failed");
3127 }
3128#endif
3129 if (forkshell(jp, cmd, mode) != 0) 3016 if (forkshell(jp, cmd, mode) != 0)
3130 goto parent; /* at end of routine */ 3017 goto parent; /* at end of routine */
3131#ifdef notyet
3132 if (flags & EV_BACKCMD) {
3133 FORCEINTON;
3134 close(pip[0]);
3135 if (pip[1] != 1) {
3136 close(1);
3137 dup_as_newfd(pip[1], 1);
3138 close(pip[1]);
3139 }
3140 }
3141#endif
3142 flags |= EV_EXIT; 3018 flags |= EV_EXIT;
3143 } 3019 }
3144 3020
@@ -3201,18 +3077,6 @@ found:
3201 trputs("builtin command: "); trargs(argv); 3077 trputs("builtin command: "); trargs(argv);
3202#endif 3078#endif
3203 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH; 3079 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
3204#ifdef notyet
3205 if (flags == EV_BACKCMD) {
3206#ifdef USE_GLIBC_STDIO
3207 openmemout();
3208#else
3209 memout.nleft = 0;
3210 memout.nextc = memout.buf;
3211 memout.bufsize = 64;
3212#endif
3213 mode |= REDIR_BACKQ;
3214 }
3215#endif
3216 redirect(cmd->ncmd.redirect, mode); 3080 redirect(cmd->ncmd.redirect, mode);
3217 savecmdname = commandname; 3081 savecmdname = commandname;
3218 if (IS_BUILTIN_SPECIAL(firstbltin)) { 3082 if (IS_BUILTIN_SPECIAL(firstbltin)) {
@@ -3234,10 +3098,6 @@ found:
3234 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv); 3098 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
3235 flushall(); 3099 flushall();
3236cmddone: 3100cmddone:
3237 exitstatus |= outerr(out1);
3238 out1 = &output;
3239 out2 = &errout;
3240 freestdout();
3241 cmdenviron = NULL; 3101 cmdenviron = NULL;
3242 if (e != EXSHELLPROC) { 3102 if (e != EXSHELLPROC) {
3243 commandname = savecmdname; 3103 commandname = savecmdname;
@@ -3256,23 +3116,6 @@ cmddone:
3256 } 3116 }
3257 if (cmdentry.u.cmd != EXECCMD) 3117 if (cmdentry.u.cmd != EXECCMD)
3258 popredir(); 3118 popredir();
3259#ifdef notyet
3260 if (flags == EV_BACKCMD) {
3261 INTOFF;
3262#ifdef USE_GLIBC_STDIO
3263 if (__closememout())
3264 error("__closememout() failed: %m");
3265#endif
3266 backcmd->buf = memout.buf;
3267#ifdef USE_GLIBC_STDIO
3268 backcmd->nleft = memout.bufsize;
3269#else
3270 backcmd->nleft = memout.nextc - memout.buf;
3271#endif
3272 memout.buf = NULL;
3273 INTON;
3274 }
3275#endif
3276 } else { 3119 } else {
3277#ifdef DEBUG 3120#ifdef DEBUG
3278 trputs("normal command: "); trargs(argv); 3121 trputs("normal command: "); trargs(argv);
@@ -3291,12 +3134,6 @@ parent: /* parent process gets here (if we forked) */
3291 INTOFF; 3134 INTOFF;
3292 exitstatus = waitforjob(jp); 3135 exitstatus = waitforjob(jp);
3293 INTON; 3136 INTON;
3294#ifdef notyet
3295 } else if (mode == 2) {
3296 backcmd->fd = pip[0];
3297 close(pip[1]);
3298 backcmd->jp = jp;
3299#endif
3300 } 3137 }
3301 3138
3302out: 3139out:
@@ -3477,7 +3314,7 @@ static void
3477eprintlist(struct strlist *sp) 3314eprintlist(struct strlist *sp)
3478{ 3315{
3479 for (; sp; sp = sp->next) { 3316 for (; sp; sp = sp->next) {
3480 outfmt(&errout, " %s",sp->text); 3317 out2fmt(" %s",sp->text);
3481 } 3318 }
3482} 3319}
3483/* 3320/*
@@ -3653,7 +3490,7 @@ static int preadfd (void);
3653 * Nul characters in the input are silently discarded. 3490 * Nul characters in the input are silently discarded.
3654 */ 3491 */
3655 3492
3656#ifdef ASH_BBAPPS_AS_BUILTINS 3493#ifndef ASH_OPTIMIZE_FOR_SIZE
3657#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) 3494#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3658static int 3495static int
3659pgetc(void) 3496pgetc(void)
@@ -3793,6 +3630,21 @@ tryexec(cmd, argv, envp)
3793 { 3630 {
3794 int e; 3631 int e;
3795 3632
3633#ifdef BB_FEATURE_SH_STANDALONE_SHELL
3634 char *name = cmd;
3635 char** argv_l=argv;
3636 int argc_l;
3637#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
3638 name = get_last_path_component(name);
3639#endif
3640 argv_l=envp;
3641 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3642 putenv(*argv_l);
3643 argv_l=argv;
3644 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
3645 optind = 1;
3646 run_applet_by_name(name, argc_l, argv);
3647#endif
3796 execve(cmd, argv, envp); 3648 execve(cmd, argv, envp);
3797 e = errno; 3649 e = errno;
3798 if (e == ENOEXEC) { 3650 if (e == ENOEXEC) {
@@ -4126,7 +3978,7 @@ loop:
4126 if (cmdp && updatetbl) 3978 if (cmdp && updatetbl)
4127 delete_cmd_entry(); 3979 delete_cmd_entry();
4128 if (act & DO_ERR) 3980 if (act & DO_ERR)
4129 outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC)); 3981 out2fmt("%s: %s\n", name, errmsg(e, E_EXEC));
4130 entry->cmdtype = CMDUNKNOWN; 3982 entry->cmdtype = CMDUNKNOWN;
4131 return; 3983 return;
4132 3984
@@ -4515,7 +4367,7 @@ describe_command(char *command, int verbose)
4515 } 4367 }
4516 4368
4517out: 4369out:
4518 out1c('\n'); 4370 putchar('\n');
4519 return 0; 4371 return 0;
4520} 4372}
4521#endif 4373#endif
@@ -4543,16 +4395,16 @@ commandcmd(argc, argv)
4543 verbose_verify_only = 1; 4395 verbose_verify_only = 1;
4544 break; 4396 break;
4545 default: 4397 default:
4546 outfmt(out2, 4398 out2fmt(
4547"command: nextopt returned character code 0%o\n", c); 4399"command: nextopt returned character code 0%o\n", c);
4548 return EX_SOFTWARE; 4400 return EX_SOFTWARE;
4549 } 4401 }
4550 4402
4551 if (default_path + verify_only + verbose_verify_only > 1 || 4403 if (default_path + verify_only + verbose_verify_only > 1 ||
4552 !*argptr) { 4404 !*argptr) {
4553 outfmt(out2, 4405 out2fmt(
4554"command [-p] command [arg ...]\n"); 4406"command [-p] command [arg ...]\n");
4555 outfmt(out2, 4407 out2fmt(
4556"command {-v|-V} command\n"); 4408"command {-v|-V} command\n");
4557 return EX_USAGE; 4409 return EX_USAGE;
4558 } 4410 }
@@ -4940,7 +4792,7 @@ expari(int flag)
4940 if (quotes) 4792 if (quotes)
4941 rmescapes(p+2); 4793 rmescapes(p+2);
4942 result = arith(p+2); 4794 result = arith(p+2);
4943 fmtstr(p, 12, "%d", result); 4795 snprintf(p, 12, "%d", result);
4944 4796
4945 while (*p++) 4797 while (*p++)
4946 ; 4798 ;
@@ -5099,7 +4951,7 @@ subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
5099 4951
5100 case VSQUESTION: 4952 case VSQUESTION:
5101 if (*p != CTLENDVAR) { 4953 if (*p != CTLENDVAR) {
5102 outfmt(&errout, snlfmt, startp); 4954 out2fmt(snlfmt, startp);
5103 error((char *)NULL); 4955 error((char *)NULL);
5104 } 4956 }
5105 error("%.*s: parameter %snot set", p - str - 1, 4957 error("%.*s: parameter %snot set", p - str - 1,
@@ -6260,13 +6112,6 @@ init(void) {
6260 basepf.nextc = basepf.buf = basebuf; 6112 basepf.nextc = basepf.buf = basebuf;
6261 } 6113 }
6262 6114
6263 /* from output.c: */
6264 {
6265#ifdef USE_GLIBC_STDIO
6266 initstreams();
6267#endif
6268 }
6269
6270 /* from var.c: */ 6115 /* from var.c: */
6271 { 6116 {
6272 char **envp; 6117 char **envp;
@@ -6279,7 +6124,7 @@ init(void) {
6279 } 6124 }
6280 } 6125 }
6281 6126
6282 fmtstr(ppid, sizeof(ppid), "%d", (int) getppid()); 6127 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
6283 setvar("PPID", ppid, 0); 6128 setvar("PPID", ppid, 0);
6284 } 6129 }
6285} 6130}
@@ -6328,19 +6173,6 @@ reset(void) {
6328 popredir(); 6173 popredir();
6329 } 6174 }
6330 6175
6331 /* from output.c: */
6332 {
6333 out1 = &output;
6334 out2 = &errout;
6335#ifdef USE_GLIBC_STDIO
6336 if (memout.stream != NULL)
6337 __closememout();
6338#endif
6339 if (memout.buf != NULL) {
6340 ckfree(memout.buf);
6341 memout.buf = NULL;
6342 }
6343 }
6344} 6176}
6345 6177
6346 6178
@@ -6513,10 +6345,7 @@ preadbuffer(void)
6513 } 6345 }
6514 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) 6346 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6515 return PEOF; 6347 return PEOF;
6516 flushout(&output); 6348 flushall();
6517#ifdef FLUSHERR
6518 flushout(&errout);
6519#endif
6520 6349
6521again: 6350again:
6522 if (parselleft <= 0) { 6351 if (parselleft <= 0) {
@@ -6557,9 +6386,6 @@ check:
6557 6386
6558 if (vflag) { 6387 if (vflag) {
6559 out2str(parsenextc); 6388 out2str(parsenextc);
6560#ifdef FLUSHERR
6561 flushout(out2);
6562#endif
6563 } 6389 }
6564 6390
6565 *q = savec; 6391 *q = savec;
@@ -6665,11 +6491,6 @@ fd0_redirected_p () {
6665 return fd0_redirected != 0; 6491 return fd0_redirected != 0;
6666} 6492}
6667 6493
6668/*
6669 * We also keep track of where fileno2 goes.
6670 */
6671static int fileno2 = 2;
6672
6673static int openredirect (union node *); 6494static int openredirect (union node *);
6674static void dupredirect (union node *, int, char[10 ]); 6495static void dupredirect (union node *, int, char[10 ]);
6675static int openhere (union node *); 6496static int openhere (union node *);
@@ -6699,9 +6520,9 @@ static void setjobctl(int enable)
6699 if (enable) { 6520 if (enable) {
6700 do { /* while we are in the background */ 6521 do { /* while we are in the background */
6701#ifdef OLD_TTY_DRIVER 6522#ifdef OLD_TTY_DRIVER
6702 if (ioctl(fileno2, TIOCGPGRP, (char *)&initialpgrp) < 0) { 6523 if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6703#else 6524#else
6704 initialpgrp = tcgetpgrp(fileno2); 6525 initialpgrp = tcgetpgrp(2);
6705 if (initialpgrp < 0) { 6526 if (initialpgrp < 0) {
6706#endif 6527#endif
6707 out2str("sh: can't access tty; job cenabletrol turned off\n"); 6528 out2str("sh: can't access tty; job cenabletrol turned off\n");
@@ -6716,7 +6537,7 @@ static void setjobctl(int enable)
6716 } 6537 }
6717 } while (0); 6538 } while (0);
6718#ifdef OLD_TTY_DRIVER 6539#ifdef OLD_TTY_DRIVER
6719 if (ioctl(fileno2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { 6540 if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6720 out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n"); 6541 out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n");
6721 mflag = 0; 6542 mflag = 0;
6722 return; 6543 return;
@@ -6727,16 +6548,16 @@ static void setjobctl(int enable)
6727 setsignal(SIGTTIN); 6548 setsignal(SIGTTIN);
6728 setpgid(0, rootpid); 6549 setpgid(0, rootpid);
6729#ifdef OLD_TTY_DRIVER 6550#ifdef OLD_TTY_DRIVER
6730 ioctl(fileno2, TIOCSPGRP, (char *)&rootpid); 6551 ioctl(2, TIOCSPGRP, (char *)&rootpid);
6731#else 6552#else
6732 tcsetpgrp(fileno2, rootpid); 6553 tcsetpgrp(2, rootpid);
6733#endif 6554#endif
6734 } else { /* turning job cenabletrol off */ 6555 } else { /* turning job cenabletrol off */
6735 setpgid(0, initialpgrp); 6556 setpgid(0, initialpgrp);
6736#ifdef OLD_TTY_DRIVER 6557#ifdef OLD_TTY_DRIVER
6737 ioctl(fileno2, TIOCSPGRP, (char *)&initialpgrp); 6558 ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
6738#else 6559#else
6739 tcsetpgrp(fileno2, initialpgrp); 6560 tcsetpgrp(2, initialpgrp);
6740#endif 6561#endif
6741 setsignal(SIGTSTP); 6562 setsignal(SIGTSTP);
6742 setsignal(SIGTTOU); 6563 setsignal(SIGTTOU);
@@ -6924,9 +6745,9 @@ fgcmd(argc, argv)
6924 error("job not created under job control"); 6745 error("job not created under job control");
6925 pgrp = jp->ps[0].pid; 6746 pgrp = jp->ps[0].pid;
6926#ifdef OLD_TTY_DRIVER 6747#ifdef OLD_TTY_DRIVER
6927 ioctl(fileno2, TIOCSPGRP, (char *)&pgrp); 6748 ioctl(2, TIOCSPGRP, (char *)&pgrp);
6928#else 6749#else
6929 tcsetpgrp(fileno2, pgrp); 6750 tcsetpgrp(2, pgrp);
6930#endif 6751#endif
6931 restartjob(jp); 6752 restartjob(jp);
6932 INTOFF; 6753 INTOFF;
@@ -7022,10 +6843,10 @@ showjobs(change)
7022 procno = jp->nprocs; 6843 procno = jp->nprocs;
7023 for (ps = jp->ps ; ; ps++) { /* for each process */ 6844 for (ps = jp->ps ; ; ps++) { /* for each process */
7024 if (ps == jp->ps) 6845 if (ps == jp->ps)
7025 fmtstr(s, 64, "[%d] %ld ", jobno, 6846 snprintf(s, 64, "[%d] %ld ", jobno,
7026 (long)ps->pid); 6847 (long)ps->pid);
7027 else 6848 else
7028 fmtstr(s, 64, " %ld ", 6849 snprintf(s, 64, " %ld ",
7029 (long)ps->pid); 6850 (long)ps->pid);
7030 out1str(s); 6851 out1str(s);
7031 col = strlen(s); 6852 col = strlen(s);
@@ -7033,7 +6854,7 @@ showjobs(change)
7033 if (ps->status == -1) { 6854 if (ps->status == -1) {
7034 /* don't print anything */ 6855 /* don't print anything */
7035 } else if (WIFEXITED(ps->status)) { 6856 } else if (WIFEXITED(ps->status)) {
7036 fmtstr(s, 64, "Exit %d", 6857 snprintf(s, 64, "Exit %d",
7037 WEXITSTATUS(ps->status)); 6858 WEXITSTATUS(ps->status));
7038 } else { 6859 } else {
7039#ifdef JOBS 6860#ifdef JOBS
@@ -7045,7 +6866,7 @@ showjobs(change)
7045 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) 6866 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
7046 strcpy(s, sys_siglist[i & 0x7F]); 6867 strcpy(s, sys_siglist[i & 0x7F]);
7047 else 6868 else
7048 fmtstr(s, 64, "Signal %d", i & 0x7F); 6869 snprintf(s, 64, "Signal %d", i & 0x7F);
7049 if (WCOREDUMP(ps->status)) 6870 if (WCOREDUMP(ps->status))
7050 strcat(s, " (core dumped)"); 6871 strcat(s, " (core dumped)");
7051 } 6872 }
@@ -7315,10 +7136,10 @@ forkshell(struct job *jp, union node *n, int mode)
7315 if (mode == FORK_FG) { 7136 if (mode == FORK_FG) {
7316 /*** this causes superfluous TIOCSPGRPS ***/ 7137 /*** this causes superfluous TIOCSPGRPS ***/
7317#ifdef OLD_TTY_DRIVER 7138#ifdef OLD_TTY_DRIVER
7318 if (ioctl(fileno2, TIOCSPGRP, (char *)&pgrp) < 0) 7139 if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
7319 error("TIOCSPGRP failed, errno=%d", errno); 7140 error("TIOCSPGRP failed, errno=%d", errno);
7320#else 7141#else
7321 if (tcsetpgrp(fileno2, pgrp) < 0) 7142 if (tcsetpgrp(2, pgrp) < 0)
7322 error("tcsetpgrp failed, errno=%d", errno); 7143 error("tcsetpgrp failed, errno=%d", errno);
7323#endif 7144#endif
7324 } 7145 }
@@ -7436,10 +7257,10 @@ waitforjob(jp)
7436#ifdef JOBS 7257#ifdef JOBS
7437 if (jp->jobctl) { 7258 if (jp->jobctl) {
7438#ifdef OLD_TTY_DRIVER 7259#ifdef OLD_TTY_DRIVER
7439 if (ioctl(fileno2, TIOCSPGRP, (char *)&mypgrp) < 0) 7260 if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
7440 error("TIOCSPGRP failed, errno=%d\n", errno); 7261 error("TIOCSPGRP failed, errno=%d\n", errno);
7441#else 7262#else
7442 if (tcsetpgrp(fileno2, mypgrp) < 0) 7263 if (tcsetpgrp(2, mypgrp) < 0)
7443 error("tcsetpgrp failed, errno=%d\n", errno); 7264 error("tcsetpgrp failed, errno=%d\n", errno);
7444#endif 7265#endif
7445 } 7266 }
@@ -7549,22 +7370,19 @@ dowait(block, job)
7549 7370
7550 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) { 7371 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7551 if (thisjob != job) 7372 if (thisjob != job)
7552 outfmt(out2, "%d: ", pid); 7373 out2fmt("%d: ", pid);
7553#ifdef JOBS 7374#ifdef JOBS
7554 if (sig == SIGTSTP && rootshell && iflag) 7375 if (sig == SIGTSTP && rootshell && iflag)
7555 outfmt(out2, "%%%ld ", 7376 out2fmt("%%%ld ",
7556 (long)(job - jobtab + 1)); 7377 (long)(job - jobtab + 1));
7557#endif 7378#endif
7558 if (sig < NSIG && sys_siglist[sig]) 7379 if (sig < NSIG && sys_siglist[sig])
7559 out2str(sys_siglist[sig]); 7380 out2str(sys_siglist[sig]);
7560 else 7381 else
7561 outfmt(out2, "Signal %d", sig); 7382 out2fmt("Signal %d", sig);
7562 if (core) 7383 if (core)
7563 out2str(" - core dumped"); 7384 out2str(" - core dumped");
7564 out2c('\n'); 7385 out2c('\n');
7565#ifdef FLUSHERR
7566 flushout(&errout);
7567#endif
7568 } else { 7386 } else {
7569 TRACE(("Not printing status: status=%d, sig=%d\n", 7387 TRACE(("Not printing status: status=%d, sig=%d\n",
7570 status, sig)); 7388 status, sig));
@@ -7889,10 +7707,8 @@ chkmail(int silent)
7889 if (stat(p, &statb) < 0) 7707 if (stat(p, &statb) < 0)
7890 statb.st_size = 0; 7708 statb.st_size = 0;
7891 if (statb.st_size > mailtime[i] && ! silent) { 7709 if (statb.st_size > mailtime[i] && ! silent) {
7892 outfmt( 7710 out2fmt(snlfmt,
7893 &errout, snlfmt, 7711 pathopt? pathopt : "you have mail");
7894 pathopt? pathopt : "you have mail"
7895 );
7896 } 7712 }
7897 mailtime[i] = statb.st_size; 7713 mailtime[i] = statb.st_size;
7898 } 7714 }
@@ -7980,9 +7796,6 @@ shell_main(argc, argv)
7980 reset(); 7796 reset();
7981 if (exception == EXINT) { 7797 if (exception == EXINT) {
7982 out2c('\n'); 7798 out2c('\n');
7983#ifdef FLUSHERR
7984 flushout(out2);
7985#endif
7986 } 7799 }
7987 popstackmark(&smark); 7800 popstackmark(&smark);
7988 FORCEINTON; /* enable interrupts */ 7801 FORCEINTON; /* enable interrupts */
@@ -8079,7 +7892,7 @@ cmdloop(int top)
8079 inter++; 7892 inter++;
8080 showjobs(1); 7893 showjobs(1);
8081 chkmail(0); 7894 chkmail(0);
8082 flushout(&output); 7895 flushall();
8083 } 7896 }
8084 n = parsecmd(inter); 7897 n = parsecmd(inter);
8085 /* showtree(n); DEBUG */ 7898 /* showtree(n); DEBUG */
@@ -9607,7 +9420,7 @@ atend:
9607 err |= setvarsafe("OPTARG", s, 0); 9420 err |= setvarsafe("OPTARG", s, 0);
9608 } 9421 }
9609 else { 9422 else {
9610 outfmt(&errout, "Illegal option -%c\n", c); 9423 out2fmt("Illegal option -%c\n", c);
9611 (void) unsetvar("OPTARG"); 9424 (void) unsetvar("OPTARG");
9612 } 9425 }
9613 c = '?'; 9426 c = '?';
@@ -9626,7 +9439,7 @@ atend:
9626 c = ':'; 9439 c = ':';
9627 } 9440 }
9628 else { 9441 else {
9629 outfmt(&errout, "No arg for -%c option\n", c); 9442 out2fmt("No arg for -%c option\n", c);
9630 (void) unsetvar("OPTARG"); 9443 (void) unsetvar("OPTARG");
9631 c = '?'; 9444 c = '?';
9632 } 9445 }
@@ -9648,7 +9461,7 @@ bad:
9648 p = NULL; 9461 p = NULL;
9649out: 9462out:
9650 *optoff = p ? p - *(optnext - 1) : -1; 9463 *optoff = p ? p - *(optnext - 1) : -1;
9651 fmtstr(s, sizeof(s), "%d", *myoptind); 9464 snprintf(s, sizeof(s), "%d", *myoptind);
9652 err |= setvarsafe("OPTIND", s, VNOFUNC); 9465 err |= setvarsafe("OPTIND", s, VNOFUNC);
9653 s[0] = c; 9466 s[0] = c;
9654 s[1] = '\0'; 9467 s[1] = '\0';
@@ -9707,249 +9520,33 @@ nextopt(optstring)
9707 return c; 9520 return c;
9708} 9521}
9709 9522
9710
9711/*
9712 * Shell output routines. We use our own output routines because:
9713 * When a builtin command is interrupted we have to discard
9714 * any pending output.
9715 * When a builtin command appears in back quotes, we want to
9716 * save the output of the command in a region obtained
9717 * via malloc, rather than doing a fork and reading the
9718 * output of the command via a pipe.
9719 * Our output routines may be smaller than the stdio routines.
9720 */
9721
9722
9723
9724#ifndef USE_GLIBC_STDIO
9725static void __outstr (const char *, size_t, struct output*);
9726#endif
9727
9728
9729#ifndef USE_GLIBC_STDIO
9730static void
9731__outstr(const char *p, size_t len, struct output *dest) {
9732 if (!dest->bufsize) {
9733 dest->nleft = 0;
9734 } else if (dest->buf == NULL) {
9735 if (len > dest->bufsize && dest->fd == MEM_OUT) {
9736 dest->bufsize = len;
9737 }
9738 INTOFF;
9739 dest->buf = ckmalloc(dest->bufsize);
9740 dest->nextc = dest->buf;
9741 dest->nleft = dest->bufsize;
9742 INTON;
9743 } else if (dest->fd == MEM_OUT) {
9744 int offset;
9745
9746 offset = dest->bufsize;
9747 INTOFF;
9748 if (dest->bufsize >= len) {
9749 dest->bufsize <<= 1;
9750 } else {
9751 dest->bufsize += len;
9752 }
9753 dest->buf = ckrealloc(dest->buf, dest->bufsize);
9754 dest->nleft = dest->bufsize - offset;
9755 dest->nextc = dest->buf + offset;
9756 INTON;
9757 } else {
9758 flushout(dest);
9759 }
9760
9761 if (len < dest->nleft) {
9762 dest->nleft -= len;
9763 memcpy(dest->nextc, p, len);
9764 dest->nextc += len;
9765 return;
9766 }
9767
9768 if (xwrite(dest->fd, p, len) < len)
9769 dest->flags |= OUTPUT_ERR;
9770}
9771#endif
9772
9773
9774static void
9775outstr(const char *p, struct output *file)
9776{
9777#ifdef USE_GLIBC_STDIO
9778 INTOFF;
9779 fputs(p, file->stream);
9780 INTON;
9781#else
9782 size_t len;
9783
9784 if (!*p) {
9785 return;
9786 }
9787 len = strlen(p);
9788 if ((file->nleft -= len) > 0) {
9789 memcpy(file->nextc, p, len);
9790 file->nextc += len;
9791 return;
9792 }
9793 __outstr(p, len, file);
9794#endif
9795}
9796
9797
9798#ifndef USE_GLIBC_STDIO
9799
9800
9801static void
9802outcslow(c, dest)
9803 char c;
9804 struct output *dest;
9805 {
9806 __outstr(&c, 1, dest);
9807}
9808#endif
9809
9810
9811static void 9523static void
9812flushall() { 9524flushall() {
9813 flushout(&output);
9814#ifdef FLUSHERR
9815 flushout(&errout);
9816#endif
9817}
9818
9819
9820static void
9821flushout(dest)
9822 struct output *dest;
9823 {
9824#ifdef USE_GLIBC_STDIO
9825 INTOFF; 9525 INTOFF;
9826 fflush(dest->stream); 9526 fflush(stdout);
9827 INTON; 9527 INTON;
9828#else
9829 size_t len;
9830
9831 len = dest->nextc - dest->buf;
9832 if (dest->buf == NULL || !len || dest->fd < 0)
9833 return;
9834 dest->nextc = dest->buf;
9835 dest->nleft = dest->bufsize;
9836 if (xwrite(dest->fd, dest->buf, len) < len)
9837 dest->flags |= OUTPUT_ERR;
9838#endif
9839}
9840
9841
9842static void
9843freestdout() {
9844 if (output.buf) {
9845 INTOFF;
9846 ckfree(output.buf);
9847 output.buf = NULL;
9848 output.nleft = 0;
9849 INTON;
9850 }
9851 output.flags = 0;
9852} 9528}
9853 9529
9854 9530
9855static void 9531static void
9856#ifdef __STDC__ 9532out2fmt(const char *fmt, ...)
9857outfmt(struct output *file, const char *fmt, ...)
9858#else
9859static void
9860outfmt(va_alist)
9861 va_dcl
9862#endif
9863{ 9533{
9864 va_list ap; 9534 va_list ap;
9865#ifndef __STDC__
9866 struct output *file;
9867 const char *fmt;
9868
9869 va_start(ap);
9870 file = va_arg(ap, struct output *);
9871 fmt = va_arg(ap, const char *);
9872#else
9873 va_start(ap, fmt); 9535 va_start(ap, fmt);
9874#endif 9536 vfprintf(stderr, fmt, ap);
9875 doformat(file, fmt, ap);
9876 va_end(ap); 9537 va_end(ap);
9877} 9538}
9878 9539
9879 9540
9880static void 9541static void
9881#ifdef __STDC__
9882out1fmt(const char *fmt, ...) 9542out1fmt(const char *fmt, ...)
9883#else
9884out1fmt(va_alist)
9885 va_dcl
9886#endif
9887{ 9543{
9888 va_list ap; 9544 va_list ap;
9889#ifndef __STDC__
9890 const char *fmt;
9891
9892 va_start(ap);
9893 fmt = va_arg(ap, const char *);
9894#else
9895 va_start(ap, fmt); 9545 va_start(ap, fmt);
9896#endif 9546 vfprintf(stdout, fmt, ap);
9897 doformat(out1, fmt, ap);
9898 va_end(ap); 9547 va_end(ap);
9899} 9548}
9900 9549
9901static void
9902#ifdef __STDC__
9903fmtstr(char *outbuf, size_t length, const char *fmt, ...)
9904#else
9905fmtstr(va_alist)
9906 va_dcl
9907#endif
9908{
9909 va_list ap;
9910#ifndef __STDC__
9911 char *outbuf;
9912 size_t length;
9913 const char *fmt;
9914
9915 va_start(ap);
9916 outbuf = va_arg(ap, char *);
9917 length = va_arg(ap, size_t);
9918 fmt = va_arg(ap, const char *);
9919#else
9920 va_start(ap, fmt);
9921#endif
9922 INTOFF;
9923 vsnprintf(outbuf, length, fmt, ap);
9924 INTON;
9925}
9926
9927#ifndef USE_GLIBC_STDIO
9928
9929static void
9930doformat(struct output *dest, const char *f, va_list ap)
9931{
9932 char *pm;
9933 int size = BUFSIZ;
9934
9935 while(size) {
9936 int nchars;
9937
9938 pm = xmalloc(size);
9939 nchars = vsnprintf(pm, size, f, ap);
9940 if(nchars > -1) {
9941 outstr(pm, dest);
9942 size = 0;
9943 }
9944 else
9945 size *= 2;
9946 free(pm);
9947 }
9948}
9949#endif
9950
9951
9952
9953/* 9550/*
9954 * Version of write which resumes after a signal is caught. 9551 * Version of write which resumes after a signal is caught.
9955 */ 9552 */
@@ -9980,29 +9577,6 @@ xwrite(int fd, const char *buf, int nbytes)
9980} 9577}
9981 9578
9982 9579
9983#ifdef USE_GLIBC_STDIO
9984static void initstreams() {
9985 output.stream = stdout;
9986 errout.stream = stderr;
9987}
9988
9989
9990static void
9991openmemout() {
9992 INTOFF;
9993 memout.stream = open_memstream(&memout.buf, &memout.bufsize);
9994 INTON;
9995}
9996
9997
9998static int
9999__closememout() {
10000 int error;
10001 error = fclose(memout.stream);
10002 memout.stream = NULL;
10003 return error;
10004}
10005#endif
10006/* 9580/*
10007 * Shell command parser. 9581 * Shell command parser.
10008 */ 9582 */
@@ -10722,7 +10296,9 @@ xxreadtoken() {
10722 c = pgetc_macro(); 10296 c = pgetc_macro();
10723 switch (c) { 10297 switch (c) {
10724 case ' ': case '\t': 10298 case ' ': case '\t':
10299#ifdef ASH_ALIAS
10725 case PEOA: 10300 case PEOA:
10301#endif
10726 continue; 10302 continue;
10727 case '#': 10303 case '#':
10728 while ((c = pgetc()) != '\n' && c != PEOF); 10304 while ((c = pgetc()) != '\n' && c != PEOF);
@@ -10969,9 +10545,11 @@ readtoken1(firstc, syntax, eofmark, striptabs)
10969 default: 10545 default:
10970 if (varnest == 0) 10546 if (varnest == 0)
10971 goto endword; /* exit outer loop */ 10547 goto endword; /* exit outer loop */
10972 if (c != PEOA) { 10548#ifdef ASH_ALIAS
10549 if (c != PEOA)
10550#endif
10973 USTPUTC(c, out); 10551 USTPUTC(c, out);
10974 } 10552
10975 } 10553 }
10976 c = pgetc_macro(); 10554 c = pgetc_macro();
10977 } 10555 }
@@ -11459,10 +11037,10 @@ synexpect(token)
11459 char msg[64]; 11037 char msg[64];
11460 11038
11461 if (token >= 0) { 11039 if (token >= 0) {
11462 fmtstr(msg, 64, "%s unexpected (expecting %s)", 11040 snprintf(msg, 64, "%s unexpected (expecting %s)",
11463 tokname[lasttoken], tokname[token]); 11041 tokname[lasttoken], tokname[token]);
11464 } else { 11042 } else {
11465 fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); 11043 snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
11466 } 11044 }
11467 synerror(msg); 11045 synerror(msg);
11468 /* NOTREACHED */ 11046 /* NOTREACHED */
@@ -11473,8 +11051,8 @@ static void
11473synerror(const char *msg) 11051synerror(const char *msg)
11474{ 11052{
11475 if (commandname) 11053 if (commandname)
11476 outfmt(&errout, "%s: %d: ", commandname, startlinno); 11054 out2fmt("%s: %d: ", commandname, startlinno);
11477 outfmt(&errout, "Syntax error: %s\n", msg); 11055 out2fmt("Syntax error: %s\n", msg);
11478 error((char *)NULL); 11056 error((char *)NULL);
11479 /* NOTREACHED */ 11057 /* NOTREACHED */
11480} 11058}
@@ -11484,7 +11062,7 @@ synerror(const char *msg)
11484 * called by editline -- any expansions to the prompt 11062 * called by editline -- any expansions to the prompt
11485 * should be added here. 11063 * should be added here.
11486 */ 11064 */
11487static const char * 11065static inline const char *
11488getprompt(void *unused) 11066getprompt(void *unused)
11489{ 11067{
11490 switch (whichprompt) { 11068 switch (whichprompt) {
@@ -11525,7 +11103,7 @@ setprompt(int which)
11525 * old file descriptors are stashed away so that the redirection can be 11103 * old file descriptors are stashed away so that the redirection can be
11526 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the 11104 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11527 * standard output, and the standard error if it becomes a duplicate of 11105 * standard output, and the standard error if it becomes a duplicate of
11528 * stdout, is saved in memory. 11106 * stdout.
11529 */ 11107 */
11530 11108
11531static void 11109static void
@@ -11560,8 +11138,7 @@ redirect(redir, flags)
11560 11138
11561 INTOFF; 11139 INTOFF;
11562 newfd = openredirect(n); 11140 newfd = openredirect(n);
11563 if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) || 11141 if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
11564 (fd == fileno2)) {
11565 if (newfd == fd) { 11142 if (newfd == fd) {
11566 try++; 11143 try++;
11567 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { 11144 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
@@ -11587,9 +11164,6 @@ redirect(redir, flags)
11587 if (flags & REDIR_PUSH) { 11164 if (flags & REDIR_PUSH) {
11588 sv->renamed[fd] = i; 11165 sv->renamed[fd] = i;
11589 } 11166 }
11590 if (fd == fileno2) {
11591 fileno2 = i;
11592 }
11593 } 11167 }
11594 } else if (fd != newfd) { 11168 } else if (fd != newfd) {
11595 close(fd); 11169 close(fd);
@@ -11600,10 +11174,6 @@ redirect(redir, flags)
11600 dupredirect(n, newfd, memory); 11174 dupredirect(n, newfd, memory);
11601 INTON; 11175 INTON;
11602 } 11176 }
11603 if (memory[1])
11604 out1 = &memout;
11605 if (memory[2])
11606 out2 = &memout;
11607} 11177}
11608 11178
11609 11179
@@ -11765,9 +11335,6 @@ popredir(void)
11765 dup_as_newfd(rp->renamed[i], i); 11335 dup_as_newfd(rp->renamed[i], i);
11766 close(rp->renamed[i]); 11336 close(rp->renamed[i]);
11767 } 11337 }
11768 if (rp->renamed[i] == fileno2) {
11769 fileno2 = i;
11770 }
11771 } 11338 }
11772 } 11339 }
11773 redirlist = rp->next; 11340 redirlist = rp->next;
@@ -11788,17 +11355,10 @@ clearredir(void) {
11788 for (i = 0 ; i < 10 ; i++) { 11355 for (i = 0 ; i < 10 ; i++) {
11789 if (rp->renamed[i] >= 0) { 11356 if (rp->renamed[i] >= 0) {
11790 close(rp->renamed[i]); 11357 close(rp->renamed[i]);
11791 if (rp->renamed[i] == fileno2) {
11792 fileno2 = -1;
11793 }
11794 } 11358 }
11795 rp->renamed[i] = EMPTY; 11359 rp->renamed[i] = EMPTY;
11796 } 11360 }
11797 } 11361 }
11798 if (fileno2 != 2 && fileno2 >= 0) {
11799 close(fileno2);
11800 fileno2 = -1;
11801 }
11802} 11362}
11803 11363
11804 11364
@@ -13528,7 +13088,7 @@ findvar(struct var **vpp, const char *name)
13528/* 13088/*
13529 * Copyright (c) 1999 Herbert Xu <herbert@debian.org> 13089 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
13530 * This file contains code for the times builtin. 13090 * This file contains code for the times builtin.
13531 * $Id: ash.c,v 1.5 2001/07/05 05:24:12 andersen Exp $ 13091 * $Id: ash.c,v 1.6 2001/07/06 04:26:23 andersen Exp $
13532 */ 13092 */
13533static int timescmd (int argc, char **argv) 13093static int timescmd (int argc, char **argv)
13534{ 13094{
diff --git a/shell/ash.c b/shell/ash.c
index e7f351608..99460d3d6 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -42,7 +42,7 @@
42 42
43/* Enable job control. This allows you to run jobs in the background, 43/* Enable job control. This allows you to run jobs in the background,
44 * which is great when ash is being used as an interactive shell, but 44 * which is great when ash is being used as an interactive shell, but
45 * it completely useless for is all you are doing is running scripts. 45 * it completely useless for is all you are doing is running scripts.
46 * This adds about 2.5k on an x86 system. */ 46 * This adds about 2.5k on an x86 system. */
47#define JOBS 47#define JOBS
48 48
@@ -79,6 +79,9 @@
79 * a little bit faster, but leaving this disabled will save you 2k. */ 79 * a little bit faster, but leaving this disabled will save you 2k. */
80#undef ASH_BBAPPS_AS_BUILTINS 80#undef ASH_BBAPPS_AS_BUILTINS
81 81
82/* Optimize size vs speed as size */
83#define ASH_OPTIMIZE_FOR_SIZE
84
82/* Enable this to compile in extra debugging noise. When debugging is 85/* Enable this to compile in extra debugging noise. When debugging is
83 * on, debugging info will be written to $HOME/trace and a quit signal 86 * on, debugging info will be written to $HOME/trace and a quit signal
84 * will generate a core dump. */ 87 * will generate a core dump. */
@@ -133,12 +136,6 @@
133#include "busybox.h" 136#include "busybox.h"
134#include "cmdedit.h" 137#include "cmdedit.h"
135 138
136/* if BB_PWD is defined, then disable ASH_PWD to save space */
137#ifdef BB_PWD
138#undef ASH_PWD
139#endif
140
141
142/* 139/*
143 * This file was generated by the mksyntax program. 140 * This file was generated by the mksyntax program.
144 */ 141 */
@@ -230,7 +227,7 @@
230 227
231#define _DIAGASSERT(x) 228#define _DIAGASSERT(x)
232 229
233#define ATABSIZE 39 230
234 231
235#define S_DFL 1 /* default signal handling (SIG_DFL) */ 232#define S_DFL 1 /* default signal handling (SIG_DFL) */
236#define S_CATCH 2 /* signal is caught */ 233#define S_CATCH 2 /* signal is caught */
@@ -258,7 +255,7 @@
258 255
259/* flags passed to redirect */ 256/* flags passed to redirect */
260#define REDIR_PUSH 01 /* save previous values of file descriptors */ 257#define REDIR_PUSH 01 /* save previous values of file descriptors */
261#define REDIR_BACKQ 02 /* save the command output in memory */ 258#define REDIR_BACKQ 02 /* save the command output to pipe */
262 259
263/* 260/*
264 * BSD setjmp saves the signal mask, which violates ANSI C and takes time, 261 * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
@@ -302,13 +299,16 @@ static volatile int suppressint;
302static volatile int intpending; 299static volatile int intpending;
303 300
304#define INTOFF suppressint++ 301#define INTOFF suppressint++
305#ifdef ASH_BBAPPS_AS_BUILTINS 302#ifndef ASH_OPTIMIZE_FOR_SIZE
306#define INTON { if (--suppressint == 0 && intpending) onint(); } 303#define INTON { if (--suppressint == 0 && intpending) onint(); }
304#define FORCEINTON {suppressint = 0; if (intpending) onint();}
307#else 305#else
308static void __inton (void); 306static void __inton (void);
307static void forceinton (void);
309#define INTON __inton() 308#define INTON __inton()
309#define FORCEINTON forceinton()
310#endif 310#endif
311#define FORCEINTON {suppressint = 0; if (intpending) onint();} 311
312#define CLEAR_PENDING_INT intpending = 0 312#define CLEAR_PENDING_INT intpending = 0
313#define int_pending() intpending 313#define int_pending() intpending
314 314
@@ -326,6 +326,7 @@ static pointer stalloc (int);
326static void stunalloc (pointer); 326static void stunalloc (pointer);
327static void ungrabstackstr (char *, char *); 327static void ungrabstackstr (char *, char *);
328static char * growstackstr(void); 328static char * growstackstr(void);
329static char * makestrspace(size_t newlen);
329static char *sstrdup (const char *); 330static char *sstrdup (const char *);
330 331
331/* 332/*
@@ -357,10 +358,13 @@ static int stacknleft = MINSIZE;
357#define stackblock() stacknxt 358#define stackblock() stacknxt
358#define stackblocksize() stacknleft 359#define stackblocksize() stacknleft
359#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize() 360#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
361
360#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c))) 362#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
361#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); } 363#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); }
362#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
363#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0')) 364#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
365
366
367#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
364#define STUNPUTC(p) (++sstrnleft, --p) 368#define STUNPUTC(p) (++sstrnleft, --p)
365#define STTOPC(p) p[-1] 369#define STTOPC(p) p[-1]
366#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount)) 370#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
@@ -368,7 +372,6 @@ static int stacknleft = MINSIZE;
368 372
369#define ckfree(p) free((pointer)(p)) 373#define ckfree(p) free((pointer)(p))
370 374
371static char * makestrspace(size_t newlen);
372 375
373#ifdef DEBUG 376#ifdef DEBUG
374#define TRACE(param) trace param 377#define TRACE(param) trace param
@@ -659,71 +662,18 @@ struct shparam {
659 int optoff; /* used by getopts */ 662 int optoff; /* used by getopts */
660}; 663};
661 664
662struct output {
663#ifdef USE_GLIBC_STDIO
664 FILE *stream;
665#endif
666 char *nextc;
667 int nleft;
668 char *buf;
669 int bufsize;
670 int fd;
671 short flags;
672};
673
674#define OUTBUFSIZ BUFSIZ
675#define MEM_OUT -3 /* output to dynamically allocated memory */
676
677
678#ifdef USE_GLIBC_STDIO
679static struct output output = {NULL, NULL, 0, NULL, 0, 1, 0};
680static struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0};
681static struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0};
682#else
683static struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};
684static struct output errout = {NULL, 0, NULL, 0, 2, 0};
685static struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};
686#endif
687static struct output *out1 = &output;
688static struct output *out2 = &errout;
689
690#ifndef USE_GLIBC_STDIO
691static void outcslow (char, struct output *);
692#endif
693static void flushall (void); 665static void flushall (void);
694static void flushout (struct output *); 666static void out2fmt (const char *, ...)
695static void freestdout (void); 667 __attribute__((__format__(__printf__,1,2)));
696static void outfmt (struct output *, const char *, ...)
697 __attribute__((__format__(__printf__,2,3)));
698static void out1fmt (const char *, ...) 668static void out1fmt (const char *, ...)
699 __attribute__((__format__(__printf__,1,2))); 669 __attribute__((__format__(__printf__,1,2)));
700static void fmtstr (char *, size_t, const char *, ...)
701 __attribute__((__format__(__printf__,3,4)));
702#ifndef USE_GLIBC_STDIO
703static void doformat (struct output *, const char *, va_list);
704#endif
705static int xwrite (int, const char *, int); 670static int xwrite (int, const char *, int);
706#ifdef USE_GLIBC_STDIO
707static void initstreams (void);
708static void openmemout (void);
709static int __closememout (void);
710#endif
711 671
712static void outstr(const char *p, struct output *file); 672static void outstr (const char *p, FILE *file) { fputs(p, file); }
673static void out1str(const char *p) { outstr(p, stdout); }
674static void out2str(const char *p) { outstr(p, stderr); }
713 675
714#define OUTPUT_ERR 01 /* error occurred on output */ 676#define out2c(c) putc((c), stderr)
715
716#ifdef USE_GLIBC_STDIO
717#define outc(c, o) putc((c), (o)->stream)
718#define doformat(d, f, a) vfprintf((d)->stream, (f), (a))
719#else
720#define outc(c, file) (--(file)->nleft < 0? outcslow((c), (file)) : (*(file)->nextc = (c), (file)->nextc++))
721#endif
722#define out1c(c) outc((c), out1)
723#define out2c(c) outc((c), out2)
724#define out1str(s) outstr((s), out1)
725#define out2str(s) outstr((s), out2)
726#define outerr(f) ((f)->flags & OUTPUT_ERR)
727 677
728/* syntax table used when not in quotes */ 678/* syntax table used when not in quotes */
729static const char basesyntax[257] = { 679static const char basesyntax[257] = {
@@ -1389,6 +1339,8 @@ static char *minusc; /* argument to -c option */
1389#define ALIASINUSE 1 1339#define ALIASINUSE 1
1390#define ALIASDEAD 2 1340#define ALIASDEAD 2
1391 1341
1342#define ATABSIZE 39
1343
1392struct alias { 1344struct alias {
1393 struct alias *next; 1345 struct alias *next;
1394 char *name; 1346 char *name;
@@ -1508,7 +1460,7 @@ aliascmd(int argc, char **argv)
1508 while ((n = *++argv) != NULL) { 1460 while ((n = *++argv) != NULL) {
1509 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ 1461 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
1510 if ((ap = *__lookupalias(n)) == NULL) { 1462 if ((ap = *__lookupalias(n)) == NULL) {
1511 outfmt(out2, "%s: %s not found\n", "alias", n); 1463 out2fmt("%s: %s not found\n", "alias", n);
1512 ret = 1; 1464 ret = 1;
1513 } else 1465 } else
1514 printalias(ap); 1466 printalias(ap);
@@ -1535,7 +1487,7 @@ unaliascmd(int argc, char **argv)
1535 } 1487 }
1536 for (i = 0; *argptr; argptr++) { 1488 for (i = 0; *argptr; argptr++) {
1537 if (unalias(*argptr)) { 1489 if (unalias(*argptr)) {
1538 outfmt(out2, "%s: %s not found\n", "unalias", *argptr); 1490 out2fmt("%s: %s not found\n", "unalias", *argptr);
1539 i = 1; 1491 i = 1;
1540 } 1492 }
1541 } 1493 }
@@ -1653,7 +1605,7 @@ static int histcmd (int, char **);
1653static int hashcmd (int, char **); 1605static int hashcmd (int, char **);
1654static int jobscmd (int, char **); 1606static int jobscmd (int, char **);
1655static int localcmd (int, char **); 1607static int localcmd (int, char **);
1656#ifdef ASH_PWD 1608#ifndef BB_PWD
1657static int pwdcmd (int, char **); 1609static int pwdcmd (int, char **);
1658#endif 1610#endif
1659static int readcmd (int, char **); 1611static int readcmd (int, char **);
@@ -1725,7 +1677,7 @@ static const struct builtincmd builtincmds[] = {
1725 { BUILTIN_REGULAR "bg", bgcmd }, 1677 { BUILTIN_REGULAR "bg", bgcmd },
1726#endif 1678#endif
1727 { BUILTIN_SPECIAL "break", breakcmd }, 1679 { BUILTIN_SPECIAL "break", breakcmd },
1728 { BUILTIN_SPECIAL "builtin", bltincmd }, /* Do not disable this builtin ever or bad things happen */ 1680 { BUILTIN_SPECIAL "builtin", bltincmd },
1729 { BUILTIN_REGULAR "cd", cdcmd }, 1681 { BUILTIN_REGULAR "cd", cdcmd },
1730#ifdef ASH_BBAPPS_AS_BUILTINS 1682#ifdef ASH_BBAPPS_AS_BUILTINS
1731 { BUILTIN_NOSPEC "chdir", cdcmd }, 1683 { BUILTIN_NOSPEC "chdir", cdcmd },
@@ -1760,7 +1712,7 @@ static const struct builtincmd builtincmds[] = {
1760 { BUILTIN_NOSPEC "let", expcmd }, 1712 { BUILTIN_NOSPEC "let", expcmd },
1761#endif 1713#endif
1762 { BUILTIN_ASSIGN "local", localcmd }, 1714 { BUILTIN_ASSIGN "local", localcmd },
1763#ifdef ASH_PWD 1715#ifndef BB_PWD
1764 { BUILTIN_NOSPEC "pwd", pwdcmd }, 1716 { BUILTIN_NOSPEC "pwd", pwdcmd },
1765#endif 1717#endif
1766 { BUILTIN_REGULAR "read", readcmd }, 1718 { BUILTIN_REGULAR "read", readcmd },
@@ -2049,7 +2001,7 @@ updatepwd(const char *dir)
2049} 2001}
2050 2002
2051 2003
2052#ifdef ASH_PWD 2004#ifndef BB_PWD
2053static int 2005static int
2054pwdcmd(argc, argv) 2006pwdcmd(argc, argv)
2055 int argc; 2007 int argc;
@@ -2198,13 +2150,9 @@ exverror(int cond, const char *msg, va_list ap)
2198#endif 2150#endif
2199 if (msg) { 2151 if (msg) {
2200 if (commandname) 2152 if (commandname)
2201 outfmt(&errout, "%s: ", commandname); 2153 out2fmt("%s: ", commandname);
2202 doformat(&errout, msg, ap); 2154 vfprintf(stderr, msg, ap);
2203#if FLUSHERR 2155 out2c('\n');
2204 outc('\n', &errout);
2205#else
2206 outcslow('\n', &errout);
2207#endif
2208 } 2156 }
2209 flushall(); 2157 flushall();
2210 exraise(cond); 2158 exraise(cond);
@@ -2357,18 +2305,23 @@ errmsg(int e, int action)
2357 return strerror(e); 2305 return strerror(e);
2358 } 2306 }
2359 2307
2360 fmtstr(buf, sizeof buf, "error %d", e); 2308 snprintf(buf, sizeof buf, "error %d", e);
2361 return buf; 2309 return buf;
2362} 2310}
2363 2311
2364 2312
2365#ifndef ASH_BBAPPS_AS_BUILTINS 2313#ifdef ASH_OPTIMIZE_FOR_SIZE
2366static void 2314static void
2367__inton() { 2315__inton() {
2368 if (--suppressint == 0 && intpending) { 2316 if (--suppressint == 0 && intpending) {
2369 onint(); 2317 onint();
2370 } 2318 }
2371} 2319}
2320static void forceinton (void) {
2321 suppressint = 0;
2322 if (intpending)
2323 onint();
2324}
2372#endif 2325#endif
2373 2326
2374/* flags in argument to evaltree */ 2327/* flags in argument to evaltree */
@@ -2394,11 +2347,7 @@ static void evalcase (union node *, int);
2394static void evalsubshell (union node *, int); 2347static void evalsubshell (union node *, int);
2395static void expredir (union node *); 2348static void expredir (union node *);
2396static void evalpipe (union node *); 2349static void evalpipe (union node *);
2397#ifdef notyet
2398static void evalcommand (union node *, int, struct backcmd *);
2399#else
2400static void evalcommand (union node *, int); 2350static void evalcommand (union node *, int);
2401#endif
2402static void prehash (union node *); 2351static void prehash (union node *);
2403static void eprintlist (struct strlist *); 2352static void eprintlist (struct strlist *);
2404 2353
@@ -2545,7 +2494,7 @@ evaltree(n, flags)
2545 (bcmd = find_builtin(n->narg.text)) && 2494 (bcmd = find_builtin(n->narg.text)) &&
2546 IS_BUILTIN_SPECIAL(bcmd) 2495 IS_BUILTIN_SPECIAL(bcmd)
2547 ) { 2496 ) {
2548 outfmt(out2, "%s is a special built-in\n", n->narg.text); 2497 out2fmt("%s is a special built-in\n", n->narg.text);
2549 exitstatus = 1; 2498 exitstatus = 1;
2550 break; 2499 break;
2551 } 2500 }
@@ -2563,19 +2512,12 @@ evaltree(n, flags)
2563 checkexit = 1; 2512 checkexit = 1;
2564 break; 2513 break;
2565 case NCMD: 2514 case NCMD:
2566#ifdef notyet
2567 evalcommand(n, flags, (struct backcmd *)NULL);
2568#else
2569 evalcommand(n, flags); 2515 evalcommand(n, flags);
2570#endif
2571 checkexit = 1; 2516 checkexit = 1;
2572 break; 2517 break;
2573#ifdef DEBUG 2518#ifdef DEBUG
2574 default: 2519 default:
2575 out1fmt("Node type = %d\n", n->type); 2520 out1fmt("Node type = %d\n", n->type);
2576#ifndef USE_GLIBC_STDIO
2577 flushout(out1);
2578#endif
2579 break; 2521 break;
2580#endif 2522#endif
2581 } 2523 }
@@ -2726,7 +2668,6 @@ evalsubshell(n, flags)
2726} 2668}
2727 2669
2728 2670
2729
2730/* 2671/*
2731 * Compute the names of the files in a redirection list. 2672 * Compute the names of the files in a redirection list.
2732 */ 2673 */
@@ -2855,38 +2796,24 @@ evalbackcmd(union node *n, struct backcmd *result)
2855 exitstatus = 0; 2796 exitstatus = 0;
2856 goto out; 2797 goto out;
2857 } 2798 }
2858#ifdef notyet 2799 exitstatus = 0;
2859 /* 2800 if (pipe(pip) < 0)
2860 * For now we disable executing builtins in the same 2801 error("Pipe call failed");
2861 * context as the shell, because we are not keeping 2802 jp = makejob(n, 1);
2862 * enough state to recover from changes that are 2803 if (forkshell(jp, n, FORK_NOJOB) == 0) {
2863 * supposed only to affect subshells. eg. echo "`cd /`" 2804 FORCEINTON;
2864 */ 2805 close(pip[0]);
2865 if (n->type == NCMD) { 2806 if (pip[1] != 1) {
2866 exitstatus = oexitstatus; 2807 close(1);
2867 evalcommand(n, EV_BACKCMD, result); 2808 dup_as_newfd(pip[1], 1);
2868 } else 2809 close(pip[1]);
2869#endif
2870 {
2871 exitstatus = 0;
2872 if (pipe(pip) < 0)
2873 error("Pipe call failed");
2874 jp = makejob(n, 1);
2875 if (forkshell(jp, n, FORK_NOJOB) == 0) {
2876 FORCEINTON;
2877 close(pip[0]);
2878 if (pip[1] != 1) {
2879 close(1);
2880 dup_as_newfd(pip[1], 1);
2881 close(pip[1]);
2882 }
2883 eflag = 0;
2884 evaltree(n, EV_EXIT);
2885 } 2810 }
2886 close(pip[1]); 2811 eflag = 0;
2887 result->fd = pip[0]; 2812 evaltree(n, EV_EXIT);
2888 result->jp = jp;
2889 } 2813 }
2814 close(pip[1]);
2815 result->fd = pip[0];
2816 result->jp = jp;
2890out: 2817out:
2891 popstackmark(&smark); 2818 popstackmark(&smark);
2892 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", 2819 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
@@ -2913,16 +2840,7 @@ isassignment(const char *word) {
2913} 2840}
2914 2841
2915static void 2842static void
2916#ifdef notyet 2843evalcommand(union node *cmd, int flags)
2917evalcommand(cmd, flags, backcmd)
2918 union node *cmd;
2919 int flags;
2920 struct backcmd *backcmd;
2921#else
2922evalcommand(cmd, flags)
2923 union node *cmd;
2924 int flags;
2925#endif
2926{ 2844{
2927 struct stackmark smark; 2845 struct stackmark smark;
2928 union node *argp; 2846 union node *argp;
@@ -2933,9 +2851,6 @@ evalcommand(cmd, flags)
2933 char **envp; 2851 char **envp;
2934 struct strlist *sp; 2852 struct strlist *sp;
2935 int mode; 2853 int mode;
2936#ifdef notyet
2937 int pip[2];
2938#endif
2939 struct cmdentry cmdentry; 2854 struct cmdentry cmdentry;
2940 struct job *jp; 2855 struct job *jp;
2941 char *volatile savecmdname; 2856 char *volatile savecmdname;
@@ -3006,19 +2921,10 @@ evalcommand(cmd, flags)
3006 2921
3007 /* Print the command if xflag is set. */ 2922 /* Print the command if xflag is set. */
3008 if (xflag) { 2923 if (xflag) {
3009#ifdef FLUSHERR 2924 out2c('+');
3010 outc('+', &errout);
3011#else
3012 outcslow('+', &errout);
3013#endif
3014 eprintlist(varlist.list); 2925 eprintlist(varlist.list);
3015 eprintlist(arglist.list); 2926 eprintlist(arglist.list);
3016#ifdef FLUSHERR 2927 out2c('\n');
3017 outc('\n', &errout);
3018 flushout(&errout);
3019#else
3020 outcslow('\n', &errout);
3021#endif
3022 } 2928 }
3023 2929
3024 /* Now locate the command. */ 2930 /* Now locate the command. */
@@ -3046,9 +2952,6 @@ evalcommand(cmd, flags)
3046 find_command(argv[0], &cmdentry, findflag, path); 2952 find_command(argv[0], &cmdentry, findflag, path);
3047 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ 2953 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
3048 exitstatus = 127; 2954 exitstatus = 127;
3049#ifdef FLUSHERR
3050 flushout(&errout);
3051#endif
3052 goto out; 2955 goto out;
3053 } 2956 }
3054 /* implement bltin and command here */ 2957 /* implement bltin and command here */
@@ -3066,11 +2969,8 @@ evalcommand(cmd, flags)
3066 if (--argc == 0) 2969 if (--argc == 0)
3067 goto found; 2970 goto found;
3068 if (!(bcmd = find_builtin(*argv))) { 2971 if (!(bcmd = find_builtin(*argv))) {
3069 outfmt(&errout, "%s: not found\n", *argv); 2972 out2fmt("%s: not found\n", *argv);
3070 exitstatus = 127; 2973 exitstatus = 127;
3071#ifdef FLUSHERR
3072 flushout(&errout);
3073#endif
3074 goto out; 2974 goto out;
3075 } 2975 }
3076 cmdentry.u.cmd = bcmd; 2976 cmdentry.u.cmd = bcmd;
@@ -3110,35 +3010,11 @@ found:
3110 /* Fork off a child process if necessary. */ 3010 /* Fork off a child process if necessary. */
3111 if (cmd->ncmd.backgnd 3011 if (cmd->ncmd.backgnd
3112 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) 3012 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
3113#ifdef notyet
3114 || ((flags & EV_BACKCMD) != 0
3115 && (cmdentry.cmdtype != CMDBUILTIN
3116 || cmdentry.u.bcmd == DOTCMD
3117 || cmdentry.u.bcmd == EVALCMD))
3118#endif
3119 ) { 3013 ) {
3120 jp = makejob(cmd, 1); 3014 jp = makejob(cmd, 1);
3121 mode = cmd->ncmd.backgnd; 3015 mode = cmd->ncmd.backgnd;
3122#ifdef notyet
3123 if (flags & EV_BACKCMD) {
3124 mode = FORK_NOJOB;
3125 if (pipe(pip) < 0)
3126 error("Pipe call failed");
3127 }
3128#endif
3129 if (forkshell(jp, cmd, mode) != 0) 3016 if (forkshell(jp, cmd, mode) != 0)
3130 goto parent; /* at end of routine */ 3017 goto parent; /* at end of routine */
3131#ifdef notyet
3132 if (flags & EV_BACKCMD) {
3133 FORCEINTON;
3134 close(pip[0]);
3135 if (pip[1] != 1) {
3136 close(1);
3137 dup_as_newfd(pip[1], 1);
3138 close(pip[1]);
3139 }
3140 }
3141#endif
3142 flags |= EV_EXIT; 3018 flags |= EV_EXIT;
3143 } 3019 }
3144 3020
@@ -3201,18 +3077,6 @@ found:
3201 trputs("builtin command: "); trargs(argv); 3077 trputs("builtin command: "); trargs(argv);
3202#endif 3078#endif
3203 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH; 3079 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
3204#ifdef notyet
3205 if (flags == EV_BACKCMD) {
3206#ifdef USE_GLIBC_STDIO
3207 openmemout();
3208#else
3209 memout.nleft = 0;
3210 memout.nextc = memout.buf;
3211 memout.bufsize = 64;
3212#endif
3213 mode |= REDIR_BACKQ;
3214 }
3215#endif
3216 redirect(cmd->ncmd.redirect, mode); 3080 redirect(cmd->ncmd.redirect, mode);
3217 savecmdname = commandname; 3081 savecmdname = commandname;
3218 if (IS_BUILTIN_SPECIAL(firstbltin)) { 3082 if (IS_BUILTIN_SPECIAL(firstbltin)) {
@@ -3234,10 +3098,6 @@ found:
3234 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv); 3098 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
3235 flushall(); 3099 flushall();
3236cmddone: 3100cmddone:
3237 exitstatus |= outerr(out1);
3238 out1 = &output;
3239 out2 = &errout;
3240 freestdout();
3241 cmdenviron = NULL; 3101 cmdenviron = NULL;
3242 if (e != EXSHELLPROC) { 3102 if (e != EXSHELLPROC) {
3243 commandname = savecmdname; 3103 commandname = savecmdname;
@@ -3256,23 +3116,6 @@ cmddone:
3256 } 3116 }
3257 if (cmdentry.u.cmd != EXECCMD) 3117 if (cmdentry.u.cmd != EXECCMD)
3258 popredir(); 3118 popredir();
3259#ifdef notyet
3260 if (flags == EV_BACKCMD) {
3261 INTOFF;
3262#ifdef USE_GLIBC_STDIO
3263 if (__closememout())
3264 error("__closememout() failed: %m");
3265#endif
3266 backcmd->buf = memout.buf;
3267#ifdef USE_GLIBC_STDIO
3268 backcmd->nleft = memout.bufsize;
3269#else
3270 backcmd->nleft = memout.nextc - memout.buf;
3271#endif
3272 memout.buf = NULL;
3273 INTON;
3274 }
3275#endif
3276 } else { 3119 } else {
3277#ifdef DEBUG 3120#ifdef DEBUG
3278 trputs("normal command: "); trargs(argv); 3121 trputs("normal command: "); trargs(argv);
@@ -3291,12 +3134,6 @@ parent: /* parent process gets here (if we forked) */
3291 INTOFF; 3134 INTOFF;
3292 exitstatus = waitforjob(jp); 3135 exitstatus = waitforjob(jp);
3293 INTON; 3136 INTON;
3294#ifdef notyet
3295 } else if (mode == 2) {
3296 backcmd->fd = pip[0];
3297 close(pip[1]);
3298 backcmd->jp = jp;
3299#endif
3300 } 3137 }
3301 3138
3302out: 3139out:
@@ -3477,7 +3314,7 @@ static void
3477eprintlist(struct strlist *sp) 3314eprintlist(struct strlist *sp)
3478{ 3315{
3479 for (; sp; sp = sp->next) { 3316 for (; sp; sp = sp->next) {
3480 outfmt(&errout, " %s",sp->text); 3317 out2fmt(" %s",sp->text);
3481 } 3318 }
3482} 3319}
3483/* 3320/*
@@ -3653,7 +3490,7 @@ static int preadfd (void);
3653 * Nul characters in the input are silently discarded. 3490 * Nul characters in the input are silently discarded.
3654 */ 3491 */
3655 3492
3656#ifdef ASH_BBAPPS_AS_BUILTINS 3493#ifndef ASH_OPTIMIZE_FOR_SIZE
3657#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) 3494#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3658static int 3495static int
3659pgetc(void) 3496pgetc(void)
@@ -3793,6 +3630,21 @@ tryexec(cmd, argv, envp)
3793 { 3630 {
3794 int e; 3631 int e;
3795 3632
3633#ifdef BB_FEATURE_SH_STANDALONE_SHELL
3634 char *name = cmd;
3635 char** argv_l=argv;
3636 int argc_l;
3637#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
3638 name = get_last_path_component(name);
3639#endif
3640 argv_l=envp;
3641 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3642 putenv(*argv_l);
3643 argv_l=argv;
3644 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
3645 optind = 1;
3646 run_applet_by_name(name, argc_l, argv);
3647#endif
3796 execve(cmd, argv, envp); 3648 execve(cmd, argv, envp);
3797 e = errno; 3649 e = errno;
3798 if (e == ENOEXEC) { 3650 if (e == ENOEXEC) {
@@ -4126,7 +3978,7 @@ loop:
4126 if (cmdp && updatetbl) 3978 if (cmdp && updatetbl)
4127 delete_cmd_entry(); 3979 delete_cmd_entry();
4128 if (act & DO_ERR) 3980 if (act & DO_ERR)
4129 outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC)); 3981 out2fmt("%s: %s\n", name, errmsg(e, E_EXEC));
4130 entry->cmdtype = CMDUNKNOWN; 3982 entry->cmdtype = CMDUNKNOWN;
4131 return; 3983 return;
4132 3984
@@ -4515,7 +4367,7 @@ describe_command(char *command, int verbose)
4515 } 4367 }
4516 4368
4517out: 4369out:
4518 out1c('\n'); 4370 putchar('\n');
4519 return 0; 4371 return 0;
4520} 4372}
4521#endif 4373#endif
@@ -4543,16 +4395,16 @@ commandcmd(argc, argv)
4543 verbose_verify_only = 1; 4395 verbose_verify_only = 1;
4544 break; 4396 break;
4545 default: 4397 default:
4546 outfmt(out2, 4398 out2fmt(
4547"command: nextopt returned character code 0%o\n", c); 4399"command: nextopt returned character code 0%o\n", c);
4548 return EX_SOFTWARE; 4400 return EX_SOFTWARE;
4549 } 4401 }
4550 4402
4551 if (default_path + verify_only + verbose_verify_only > 1 || 4403 if (default_path + verify_only + verbose_verify_only > 1 ||
4552 !*argptr) { 4404 !*argptr) {
4553 outfmt(out2, 4405 out2fmt(
4554"command [-p] command [arg ...]\n"); 4406"command [-p] command [arg ...]\n");
4555 outfmt(out2, 4407 out2fmt(
4556"command {-v|-V} command\n"); 4408"command {-v|-V} command\n");
4557 return EX_USAGE; 4409 return EX_USAGE;
4558 } 4410 }
@@ -4940,7 +4792,7 @@ expari(int flag)
4940 if (quotes) 4792 if (quotes)
4941 rmescapes(p+2); 4793 rmescapes(p+2);
4942 result = arith(p+2); 4794 result = arith(p+2);
4943 fmtstr(p, 12, "%d", result); 4795 snprintf(p, 12, "%d", result);
4944 4796
4945 while (*p++) 4797 while (*p++)
4946 ; 4798 ;
@@ -5099,7 +4951,7 @@ subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
5099 4951
5100 case VSQUESTION: 4952 case VSQUESTION:
5101 if (*p != CTLENDVAR) { 4953 if (*p != CTLENDVAR) {
5102 outfmt(&errout, snlfmt, startp); 4954 out2fmt(snlfmt, startp);
5103 error((char *)NULL); 4955 error((char *)NULL);
5104 } 4956 }
5105 error("%.*s: parameter %snot set", p - str - 1, 4957 error("%.*s: parameter %snot set", p - str - 1,
@@ -6260,13 +6112,6 @@ init(void) {
6260 basepf.nextc = basepf.buf = basebuf; 6112 basepf.nextc = basepf.buf = basebuf;
6261 } 6113 }
6262 6114
6263 /* from output.c: */
6264 {
6265#ifdef USE_GLIBC_STDIO
6266 initstreams();
6267#endif
6268 }
6269
6270 /* from var.c: */ 6115 /* from var.c: */
6271 { 6116 {
6272 char **envp; 6117 char **envp;
@@ -6279,7 +6124,7 @@ init(void) {
6279 } 6124 }
6280 } 6125 }
6281 6126
6282 fmtstr(ppid, sizeof(ppid), "%d", (int) getppid()); 6127 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
6283 setvar("PPID", ppid, 0); 6128 setvar("PPID", ppid, 0);
6284 } 6129 }
6285} 6130}
@@ -6328,19 +6173,6 @@ reset(void) {
6328 popredir(); 6173 popredir();
6329 } 6174 }
6330 6175
6331 /* from output.c: */
6332 {
6333 out1 = &output;
6334 out2 = &errout;
6335#ifdef USE_GLIBC_STDIO
6336 if (memout.stream != NULL)
6337 __closememout();
6338#endif
6339 if (memout.buf != NULL) {
6340 ckfree(memout.buf);
6341 memout.buf = NULL;
6342 }
6343 }
6344} 6176}
6345 6177
6346 6178
@@ -6513,10 +6345,7 @@ preadbuffer(void)
6513 } 6345 }
6514 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) 6346 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6515 return PEOF; 6347 return PEOF;
6516 flushout(&output); 6348 flushall();
6517#ifdef FLUSHERR
6518 flushout(&errout);
6519#endif
6520 6349
6521again: 6350again:
6522 if (parselleft <= 0) { 6351 if (parselleft <= 0) {
@@ -6557,9 +6386,6 @@ check:
6557 6386
6558 if (vflag) { 6387 if (vflag) {
6559 out2str(parsenextc); 6388 out2str(parsenextc);
6560#ifdef FLUSHERR
6561 flushout(out2);
6562#endif
6563 } 6389 }
6564 6390
6565 *q = savec; 6391 *q = savec;
@@ -6665,11 +6491,6 @@ fd0_redirected_p () {
6665 return fd0_redirected != 0; 6491 return fd0_redirected != 0;
6666} 6492}
6667 6493
6668/*
6669 * We also keep track of where fileno2 goes.
6670 */
6671static int fileno2 = 2;
6672
6673static int openredirect (union node *); 6494static int openredirect (union node *);
6674static void dupredirect (union node *, int, char[10 ]); 6495static void dupredirect (union node *, int, char[10 ]);
6675static int openhere (union node *); 6496static int openhere (union node *);
@@ -6699,9 +6520,9 @@ static void setjobctl(int enable)
6699 if (enable) { 6520 if (enable) {
6700 do { /* while we are in the background */ 6521 do { /* while we are in the background */
6701#ifdef OLD_TTY_DRIVER 6522#ifdef OLD_TTY_DRIVER
6702 if (ioctl(fileno2, TIOCGPGRP, (char *)&initialpgrp) < 0) { 6523 if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6703#else 6524#else
6704 initialpgrp = tcgetpgrp(fileno2); 6525 initialpgrp = tcgetpgrp(2);
6705 if (initialpgrp < 0) { 6526 if (initialpgrp < 0) {
6706#endif 6527#endif
6707 out2str("sh: can't access tty; job cenabletrol turned off\n"); 6528 out2str("sh: can't access tty; job cenabletrol turned off\n");
@@ -6716,7 +6537,7 @@ static void setjobctl(int enable)
6716 } 6537 }
6717 } while (0); 6538 } while (0);
6718#ifdef OLD_TTY_DRIVER 6539#ifdef OLD_TTY_DRIVER
6719 if (ioctl(fileno2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { 6540 if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6720 out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n"); 6541 out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n");
6721 mflag = 0; 6542 mflag = 0;
6722 return; 6543 return;
@@ -6727,16 +6548,16 @@ static void setjobctl(int enable)
6727 setsignal(SIGTTIN); 6548 setsignal(SIGTTIN);
6728 setpgid(0, rootpid); 6549 setpgid(0, rootpid);
6729#ifdef OLD_TTY_DRIVER 6550#ifdef OLD_TTY_DRIVER
6730 ioctl(fileno2, TIOCSPGRP, (char *)&rootpid); 6551 ioctl(2, TIOCSPGRP, (char *)&rootpid);
6731#else 6552#else
6732 tcsetpgrp(fileno2, rootpid); 6553 tcsetpgrp(2, rootpid);
6733#endif 6554#endif
6734 } else { /* turning job cenabletrol off */ 6555 } else { /* turning job cenabletrol off */
6735 setpgid(0, initialpgrp); 6556 setpgid(0, initialpgrp);
6736#ifdef OLD_TTY_DRIVER 6557#ifdef OLD_TTY_DRIVER
6737 ioctl(fileno2, TIOCSPGRP, (char *)&initialpgrp); 6558 ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
6738#else 6559#else
6739 tcsetpgrp(fileno2, initialpgrp); 6560 tcsetpgrp(2, initialpgrp);
6740#endif 6561#endif
6741 setsignal(SIGTSTP); 6562 setsignal(SIGTSTP);
6742 setsignal(SIGTTOU); 6563 setsignal(SIGTTOU);
@@ -6924,9 +6745,9 @@ fgcmd(argc, argv)
6924 error("job not created under job control"); 6745 error("job not created under job control");
6925 pgrp = jp->ps[0].pid; 6746 pgrp = jp->ps[0].pid;
6926#ifdef OLD_TTY_DRIVER 6747#ifdef OLD_TTY_DRIVER
6927 ioctl(fileno2, TIOCSPGRP, (char *)&pgrp); 6748 ioctl(2, TIOCSPGRP, (char *)&pgrp);
6928#else 6749#else
6929 tcsetpgrp(fileno2, pgrp); 6750 tcsetpgrp(2, pgrp);
6930#endif 6751#endif
6931 restartjob(jp); 6752 restartjob(jp);
6932 INTOFF; 6753 INTOFF;
@@ -7022,10 +6843,10 @@ showjobs(change)
7022 procno = jp->nprocs; 6843 procno = jp->nprocs;
7023 for (ps = jp->ps ; ; ps++) { /* for each process */ 6844 for (ps = jp->ps ; ; ps++) { /* for each process */
7024 if (ps == jp->ps) 6845 if (ps == jp->ps)
7025 fmtstr(s, 64, "[%d] %ld ", jobno, 6846 snprintf(s, 64, "[%d] %ld ", jobno,
7026 (long)ps->pid); 6847 (long)ps->pid);
7027 else 6848 else
7028 fmtstr(s, 64, " %ld ", 6849 snprintf(s, 64, " %ld ",
7029 (long)ps->pid); 6850 (long)ps->pid);
7030 out1str(s); 6851 out1str(s);
7031 col = strlen(s); 6852 col = strlen(s);
@@ -7033,7 +6854,7 @@ showjobs(change)
7033 if (ps->status == -1) { 6854 if (ps->status == -1) {
7034 /* don't print anything */ 6855 /* don't print anything */
7035 } else if (WIFEXITED(ps->status)) { 6856 } else if (WIFEXITED(ps->status)) {
7036 fmtstr(s, 64, "Exit %d", 6857 snprintf(s, 64, "Exit %d",
7037 WEXITSTATUS(ps->status)); 6858 WEXITSTATUS(ps->status));
7038 } else { 6859 } else {
7039#ifdef JOBS 6860#ifdef JOBS
@@ -7045,7 +6866,7 @@ showjobs(change)
7045 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) 6866 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
7046 strcpy(s, sys_siglist[i & 0x7F]); 6867 strcpy(s, sys_siglist[i & 0x7F]);
7047 else 6868 else
7048 fmtstr(s, 64, "Signal %d", i & 0x7F); 6869 snprintf(s, 64, "Signal %d", i & 0x7F);
7049 if (WCOREDUMP(ps->status)) 6870 if (WCOREDUMP(ps->status))
7050 strcat(s, " (core dumped)"); 6871 strcat(s, " (core dumped)");
7051 } 6872 }
@@ -7315,10 +7136,10 @@ forkshell(struct job *jp, union node *n, int mode)
7315 if (mode == FORK_FG) { 7136 if (mode == FORK_FG) {
7316 /*** this causes superfluous TIOCSPGRPS ***/ 7137 /*** this causes superfluous TIOCSPGRPS ***/
7317#ifdef OLD_TTY_DRIVER 7138#ifdef OLD_TTY_DRIVER
7318 if (ioctl(fileno2, TIOCSPGRP, (char *)&pgrp) < 0) 7139 if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
7319 error("TIOCSPGRP failed, errno=%d", errno); 7140 error("TIOCSPGRP failed, errno=%d", errno);
7320#else 7141#else
7321 if (tcsetpgrp(fileno2, pgrp) < 0) 7142 if (tcsetpgrp(2, pgrp) < 0)
7322 error("tcsetpgrp failed, errno=%d", errno); 7143 error("tcsetpgrp failed, errno=%d", errno);
7323#endif 7144#endif
7324 } 7145 }
@@ -7436,10 +7257,10 @@ waitforjob(jp)
7436#ifdef JOBS 7257#ifdef JOBS
7437 if (jp->jobctl) { 7258 if (jp->jobctl) {
7438#ifdef OLD_TTY_DRIVER 7259#ifdef OLD_TTY_DRIVER
7439 if (ioctl(fileno2, TIOCSPGRP, (char *)&mypgrp) < 0) 7260 if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
7440 error("TIOCSPGRP failed, errno=%d\n", errno); 7261 error("TIOCSPGRP failed, errno=%d\n", errno);
7441#else 7262#else
7442 if (tcsetpgrp(fileno2, mypgrp) < 0) 7263 if (tcsetpgrp(2, mypgrp) < 0)
7443 error("tcsetpgrp failed, errno=%d\n", errno); 7264 error("tcsetpgrp failed, errno=%d\n", errno);
7444#endif 7265#endif
7445 } 7266 }
@@ -7549,22 +7370,19 @@ dowait(block, job)
7549 7370
7550 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) { 7371 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7551 if (thisjob != job) 7372 if (thisjob != job)
7552 outfmt(out2, "%d: ", pid); 7373 out2fmt("%d: ", pid);
7553#ifdef JOBS 7374#ifdef JOBS
7554 if (sig == SIGTSTP && rootshell && iflag) 7375 if (sig == SIGTSTP && rootshell && iflag)
7555 outfmt(out2, "%%%ld ", 7376 out2fmt("%%%ld ",
7556 (long)(job - jobtab + 1)); 7377 (long)(job - jobtab + 1));
7557#endif 7378#endif
7558 if (sig < NSIG && sys_siglist[sig]) 7379 if (sig < NSIG && sys_siglist[sig])
7559 out2str(sys_siglist[sig]); 7380 out2str(sys_siglist[sig]);
7560 else 7381 else
7561 outfmt(out2, "Signal %d", sig); 7382 out2fmt("Signal %d", sig);
7562 if (core) 7383 if (core)
7563 out2str(" - core dumped"); 7384 out2str(" - core dumped");
7564 out2c('\n'); 7385 out2c('\n');
7565#ifdef FLUSHERR
7566 flushout(&errout);
7567#endif
7568 } else { 7386 } else {
7569 TRACE(("Not printing status: status=%d, sig=%d\n", 7387 TRACE(("Not printing status: status=%d, sig=%d\n",
7570 status, sig)); 7388 status, sig));
@@ -7889,10 +7707,8 @@ chkmail(int silent)
7889 if (stat(p, &statb) < 0) 7707 if (stat(p, &statb) < 0)
7890 statb.st_size = 0; 7708 statb.st_size = 0;
7891 if (statb.st_size > mailtime[i] && ! silent) { 7709 if (statb.st_size > mailtime[i] && ! silent) {
7892 outfmt( 7710 out2fmt(snlfmt,
7893 &errout, snlfmt, 7711 pathopt? pathopt : "you have mail");
7894 pathopt? pathopt : "you have mail"
7895 );
7896 } 7712 }
7897 mailtime[i] = statb.st_size; 7713 mailtime[i] = statb.st_size;
7898 } 7714 }
@@ -7980,9 +7796,6 @@ shell_main(argc, argv)
7980 reset(); 7796 reset();
7981 if (exception == EXINT) { 7797 if (exception == EXINT) {
7982 out2c('\n'); 7798 out2c('\n');
7983#ifdef FLUSHERR
7984 flushout(out2);
7985#endif
7986 } 7799 }
7987 popstackmark(&smark); 7800 popstackmark(&smark);
7988 FORCEINTON; /* enable interrupts */ 7801 FORCEINTON; /* enable interrupts */
@@ -8079,7 +7892,7 @@ cmdloop(int top)
8079 inter++; 7892 inter++;
8080 showjobs(1); 7893 showjobs(1);
8081 chkmail(0); 7894 chkmail(0);
8082 flushout(&output); 7895 flushall();
8083 } 7896 }
8084 n = parsecmd(inter); 7897 n = parsecmd(inter);
8085 /* showtree(n); DEBUG */ 7898 /* showtree(n); DEBUG */
@@ -9607,7 +9420,7 @@ atend:
9607 err |= setvarsafe("OPTARG", s, 0); 9420 err |= setvarsafe("OPTARG", s, 0);
9608 } 9421 }
9609 else { 9422 else {
9610 outfmt(&errout, "Illegal option -%c\n", c); 9423 out2fmt("Illegal option -%c\n", c);
9611 (void) unsetvar("OPTARG"); 9424 (void) unsetvar("OPTARG");
9612 } 9425 }
9613 c = '?'; 9426 c = '?';
@@ -9626,7 +9439,7 @@ atend:
9626 c = ':'; 9439 c = ':';
9627 } 9440 }
9628 else { 9441 else {
9629 outfmt(&errout, "No arg for -%c option\n", c); 9442 out2fmt("No arg for -%c option\n", c);
9630 (void) unsetvar("OPTARG"); 9443 (void) unsetvar("OPTARG");
9631 c = '?'; 9444 c = '?';
9632 } 9445 }
@@ -9648,7 +9461,7 @@ bad:
9648 p = NULL; 9461 p = NULL;
9649out: 9462out:
9650 *optoff = p ? p - *(optnext - 1) : -1; 9463 *optoff = p ? p - *(optnext - 1) : -1;
9651 fmtstr(s, sizeof(s), "%d", *myoptind); 9464 snprintf(s, sizeof(s), "%d", *myoptind);
9652 err |= setvarsafe("OPTIND", s, VNOFUNC); 9465 err |= setvarsafe("OPTIND", s, VNOFUNC);
9653 s[0] = c; 9466 s[0] = c;
9654 s[1] = '\0'; 9467 s[1] = '\0';
@@ -9707,249 +9520,33 @@ nextopt(optstring)
9707 return c; 9520 return c;
9708} 9521}
9709 9522
9710
9711/*
9712 * Shell output routines. We use our own output routines because:
9713 * When a builtin command is interrupted we have to discard
9714 * any pending output.
9715 * When a builtin command appears in back quotes, we want to
9716 * save the output of the command in a region obtained
9717 * via malloc, rather than doing a fork and reading the
9718 * output of the command via a pipe.
9719 * Our output routines may be smaller than the stdio routines.
9720 */
9721
9722
9723
9724#ifndef USE_GLIBC_STDIO
9725static void __outstr (const char *, size_t, struct output*);
9726#endif
9727
9728
9729#ifndef USE_GLIBC_STDIO
9730static void
9731__outstr(const char *p, size_t len, struct output *dest) {
9732 if (!dest->bufsize) {
9733 dest->nleft = 0;
9734 } else if (dest->buf == NULL) {
9735 if (len > dest->bufsize && dest->fd == MEM_OUT) {
9736 dest->bufsize = len;
9737 }
9738 INTOFF;
9739 dest->buf = ckmalloc(dest->bufsize);
9740 dest->nextc = dest->buf;
9741 dest->nleft = dest->bufsize;
9742 INTON;
9743 } else if (dest->fd == MEM_OUT) {
9744 int offset;
9745
9746 offset = dest->bufsize;
9747 INTOFF;
9748 if (dest->bufsize >= len) {
9749 dest->bufsize <<= 1;
9750 } else {
9751 dest->bufsize += len;
9752 }
9753 dest->buf = ckrealloc(dest->buf, dest->bufsize);
9754 dest->nleft = dest->bufsize - offset;
9755 dest->nextc = dest->buf + offset;
9756 INTON;
9757 } else {
9758 flushout(dest);
9759 }
9760
9761 if (len < dest->nleft) {
9762 dest->nleft -= len;
9763 memcpy(dest->nextc, p, len);
9764 dest->nextc += len;
9765 return;
9766 }
9767
9768 if (xwrite(dest->fd, p, len) < len)
9769 dest->flags |= OUTPUT_ERR;
9770}
9771#endif
9772
9773
9774static void
9775outstr(const char *p, struct output *file)
9776{
9777#ifdef USE_GLIBC_STDIO
9778 INTOFF;
9779 fputs(p, file->stream);
9780 INTON;
9781#else
9782 size_t len;
9783
9784 if (!*p) {
9785 return;
9786 }
9787 len = strlen(p);
9788 if ((file->nleft -= len) > 0) {
9789 memcpy(file->nextc, p, len);
9790 file->nextc += len;
9791 return;
9792 }
9793 __outstr(p, len, file);
9794#endif
9795}
9796
9797
9798#ifndef USE_GLIBC_STDIO
9799
9800
9801static void
9802outcslow(c, dest)
9803 char c;
9804 struct output *dest;
9805 {
9806 __outstr(&c, 1, dest);
9807}
9808#endif
9809
9810
9811static void 9523static void
9812flushall() { 9524flushall() {
9813 flushout(&output);
9814#ifdef FLUSHERR
9815 flushout(&errout);
9816#endif
9817}
9818
9819
9820static void
9821flushout(dest)
9822 struct output *dest;
9823 {
9824#ifdef USE_GLIBC_STDIO
9825 INTOFF; 9525 INTOFF;
9826 fflush(dest->stream); 9526 fflush(stdout);
9827 INTON; 9527 INTON;
9828#else
9829 size_t len;
9830
9831 len = dest->nextc - dest->buf;
9832 if (dest->buf == NULL || !len || dest->fd < 0)
9833 return;
9834 dest->nextc = dest->buf;
9835 dest->nleft = dest->bufsize;
9836 if (xwrite(dest->fd, dest->buf, len) < len)
9837 dest->flags |= OUTPUT_ERR;
9838#endif
9839}
9840
9841
9842static void
9843freestdout() {
9844 if (output.buf) {
9845 INTOFF;
9846 ckfree(output.buf);
9847 output.buf = NULL;
9848 output.nleft = 0;
9849 INTON;
9850 }
9851 output.flags = 0;
9852} 9528}
9853 9529
9854 9530
9855static void 9531static void
9856#ifdef __STDC__ 9532out2fmt(const char *fmt, ...)
9857outfmt(struct output *file, const char *fmt, ...)
9858#else
9859static void
9860outfmt(va_alist)
9861 va_dcl
9862#endif
9863{ 9533{
9864 va_list ap; 9534 va_list ap;
9865#ifndef __STDC__
9866 struct output *file;
9867 const char *fmt;
9868
9869 va_start(ap);
9870 file = va_arg(ap, struct output *);
9871 fmt = va_arg(ap, const char *);
9872#else
9873 va_start(ap, fmt); 9535 va_start(ap, fmt);
9874#endif 9536 vfprintf(stderr, fmt, ap);
9875 doformat(file, fmt, ap);
9876 va_end(ap); 9537 va_end(ap);
9877} 9538}
9878 9539
9879 9540
9880static void 9541static void
9881#ifdef __STDC__
9882out1fmt(const char *fmt, ...) 9542out1fmt(const char *fmt, ...)
9883#else
9884out1fmt(va_alist)
9885 va_dcl
9886#endif
9887{ 9543{
9888 va_list ap; 9544 va_list ap;
9889#ifndef __STDC__
9890 const char *fmt;
9891
9892 va_start(ap);
9893 fmt = va_arg(ap, const char *);
9894#else
9895 va_start(ap, fmt); 9545 va_start(ap, fmt);
9896#endif 9546 vfprintf(stdout, fmt, ap);
9897 doformat(out1, fmt, ap);
9898 va_end(ap); 9547 va_end(ap);
9899} 9548}
9900 9549
9901static void
9902#ifdef __STDC__
9903fmtstr(char *outbuf, size_t length, const char *fmt, ...)
9904#else
9905fmtstr(va_alist)
9906 va_dcl
9907#endif
9908{
9909 va_list ap;
9910#ifndef __STDC__
9911 char *outbuf;
9912 size_t length;
9913 const char *fmt;
9914
9915 va_start(ap);
9916 outbuf = va_arg(ap, char *);
9917 length = va_arg(ap, size_t);
9918 fmt = va_arg(ap, const char *);
9919#else
9920 va_start(ap, fmt);
9921#endif
9922 INTOFF;
9923 vsnprintf(outbuf, length, fmt, ap);
9924 INTON;
9925}
9926
9927#ifndef USE_GLIBC_STDIO
9928
9929static void
9930doformat(struct output *dest, const char *f, va_list ap)
9931{
9932 char *pm;
9933 int size = BUFSIZ;
9934
9935 while(size) {
9936 int nchars;
9937
9938 pm = xmalloc(size);
9939 nchars = vsnprintf(pm, size, f, ap);
9940 if(nchars > -1) {
9941 outstr(pm, dest);
9942 size = 0;
9943 }
9944 else
9945 size *= 2;
9946 free(pm);
9947 }
9948}
9949#endif
9950
9951
9952
9953/* 9550/*
9954 * Version of write which resumes after a signal is caught. 9551 * Version of write which resumes after a signal is caught.
9955 */ 9552 */
@@ -9980,29 +9577,6 @@ xwrite(int fd, const char *buf, int nbytes)
9980} 9577}
9981 9578
9982 9579
9983#ifdef USE_GLIBC_STDIO
9984static void initstreams() {
9985 output.stream = stdout;
9986 errout.stream = stderr;
9987}
9988
9989
9990static void
9991openmemout() {
9992 INTOFF;
9993 memout.stream = open_memstream(&memout.buf, &memout.bufsize);
9994 INTON;
9995}
9996
9997
9998static int
9999__closememout() {
10000 int error;
10001 error = fclose(memout.stream);
10002 memout.stream = NULL;
10003 return error;
10004}
10005#endif
10006/* 9580/*
10007 * Shell command parser. 9581 * Shell command parser.
10008 */ 9582 */
@@ -10722,7 +10296,9 @@ xxreadtoken() {
10722 c = pgetc_macro(); 10296 c = pgetc_macro();
10723 switch (c) { 10297 switch (c) {
10724 case ' ': case '\t': 10298 case ' ': case '\t':
10299#ifdef ASH_ALIAS
10725 case PEOA: 10300 case PEOA:
10301#endif
10726 continue; 10302 continue;
10727 case '#': 10303 case '#':
10728 while ((c = pgetc()) != '\n' && c != PEOF); 10304 while ((c = pgetc()) != '\n' && c != PEOF);
@@ -10969,9 +10545,11 @@ readtoken1(firstc, syntax, eofmark, striptabs)
10969 default: 10545 default:
10970 if (varnest == 0) 10546 if (varnest == 0)
10971 goto endword; /* exit outer loop */ 10547 goto endword; /* exit outer loop */
10972 if (c != PEOA) { 10548#ifdef ASH_ALIAS
10549 if (c != PEOA)
10550#endif
10973 USTPUTC(c, out); 10551 USTPUTC(c, out);
10974 } 10552
10975 } 10553 }
10976 c = pgetc_macro(); 10554 c = pgetc_macro();
10977 } 10555 }
@@ -11459,10 +11037,10 @@ synexpect(token)
11459 char msg[64]; 11037 char msg[64];
11460 11038
11461 if (token >= 0) { 11039 if (token >= 0) {
11462 fmtstr(msg, 64, "%s unexpected (expecting %s)", 11040 snprintf(msg, 64, "%s unexpected (expecting %s)",
11463 tokname[lasttoken], tokname[token]); 11041 tokname[lasttoken], tokname[token]);
11464 } else { 11042 } else {
11465 fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); 11043 snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
11466 } 11044 }
11467 synerror(msg); 11045 synerror(msg);
11468 /* NOTREACHED */ 11046 /* NOTREACHED */
@@ -11473,8 +11051,8 @@ static void
11473synerror(const char *msg) 11051synerror(const char *msg)
11474{ 11052{
11475 if (commandname) 11053 if (commandname)
11476 outfmt(&errout, "%s: %d: ", commandname, startlinno); 11054 out2fmt("%s: %d: ", commandname, startlinno);
11477 outfmt(&errout, "Syntax error: %s\n", msg); 11055 out2fmt("Syntax error: %s\n", msg);
11478 error((char *)NULL); 11056 error((char *)NULL);
11479 /* NOTREACHED */ 11057 /* NOTREACHED */
11480} 11058}
@@ -11484,7 +11062,7 @@ synerror(const char *msg)
11484 * called by editline -- any expansions to the prompt 11062 * called by editline -- any expansions to the prompt
11485 * should be added here. 11063 * should be added here.
11486 */ 11064 */
11487static const char * 11065static inline const char *
11488getprompt(void *unused) 11066getprompt(void *unused)
11489{ 11067{
11490 switch (whichprompt) { 11068 switch (whichprompt) {
@@ -11525,7 +11103,7 @@ setprompt(int which)
11525 * old file descriptors are stashed away so that the redirection can be 11103 * old file descriptors are stashed away so that the redirection can be
11526 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the 11104 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11527 * standard output, and the standard error if it becomes a duplicate of 11105 * standard output, and the standard error if it becomes a duplicate of
11528 * stdout, is saved in memory. 11106 * stdout.
11529 */ 11107 */
11530 11108
11531static void 11109static void
@@ -11560,8 +11138,7 @@ redirect(redir, flags)
11560 11138
11561 INTOFF; 11139 INTOFF;
11562 newfd = openredirect(n); 11140 newfd = openredirect(n);
11563 if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) || 11141 if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
11564 (fd == fileno2)) {
11565 if (newfd == fd) { 11142 if (newfd == fd) {
11566 try++; 11143 try++;
11567 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { 11144 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
@@ -11587,9 +11164,6 @@ redirect(redir, flags)
11587 if (flags & REDIR_PUSH) { 11164 if (flags & REDIR_PUSH) {
11588 sv->renamed[fd] = i; 11165 sv->renamed[fd] = i;
11589 } 11166 }
11590 if (fd == fileno2) {
11591 fileno2 = i;
11592 }
11593 } 11167 }
11594 } else if (fd != newfd) { 11168 } else if (fd != newfd) {
11595 close(fd); 11169 close(fd);
@@ -11600,10 +11174,6 @@ redirect(redir, flags)
11600 dupredirect(n, newfd, memory); 11174 dupredirect(n, newfd, memory);
11601 INTON; 11175 INTON;
11602 } 11176 }
11603 if (memory[1])
11604 out1 = &memout;
11605 if (memory[2])
11606 out2 = &memout;
11607} 11177}
11608 11178
11609 11179
@@ -11765,9 +11335,6 @@ popredir(void)
11765 dup_as_newfd(rp->renamed[i], i); 11335 dup_as_newfd(rp->renamed[i], i);
11766 close(rp->renamed[i]); 11336 close(rp->renamed[i]);
11767 } 11337 }
11768 if (rp->renamed[i] == fileno2) {
11769 fileno2 = i;
11770 }
11771 } 11338 }
11772 } 11339 }
11773 redirlist = rp->next; 11340 redirlist = rp->next;
@@ -11788,17 +11355,10 @@ clearredir(void) {
11788 for (i = 0 ; i < 10 ; i++) { 11355 for (i = 0 ; i < 10 ; i++) {
11789 if (rp->renamed[i] >= 0) { 11356 if (rp->renamed[i] >= 0) {
11790 close(rp->renamed[i]); 11357 close(rp->renamed[i]);
11791 if (rp->renamed[i] == fileno2) {
11792 fileno2 = -1;
11793 }
11794 } 11358 }
11795 rp->renamed[i] = EMPTY; 11359 rp->renamed[i] = EMPTY;
11796 } 11360 }
11797 } 11361 }
11798 if (fileno2 != 2 && fileno2 >= 0) {
11799 close(fileno2);
11800 fileno2 = -1;
11801 }
11802} 11362}
11803 11363
11804 11364
@@ -13528,7 +13088,7 @@ findvar(struct var **vpp, const char *name)
13528/* 13088/*
13529 * Copyright (c) 1999 Herbert Xu <herbert@debian.org> 13089 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
13530 * This file contains code for the times builtin. 13090 * This file contains code for the times builtin.
13531 * $Id: ash.c,v 1.5 2001/07/05 05:24:12 andersen Exp $ 13091 * $Id: ash.c,v 1.6 2001/07/06 04:26:23 andersen Exp $
13532 */ 13092 */
13533static int timescmd (int argc, char **argv) 13093static int timescmd (int argc, char **argv)
13534{ 13094{