diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-07-06 04:26:23 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-07-06 04:26:23 +0000 |
commit | 3102ac4b582b144ad0e04c7cbe511c25c1175ee2 (patch) | |
tree | 4f6d1fa7ff379817afc74301bac06baf9d0d6bd7 | |
parent | 5009f90ea24224638af6945552012ce60efb3cea (diff) | |
download | busybox-w32-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.tar.gz busybox-w32-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.tar.bz2 busybox-w32-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.zip |
This is vodz' latest ash update.
-rw-r--r-- | ash.c | 702 | ||||
-rw-r--r-- | shell/ash.c | 702 |
2 files changed, 262 insertions, 1142 deletions
@@ -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; | |||
302 | static volatile int intpending; | 299 | static 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 |
308 | static void __inton (void); | 306 | static void __inton (void); |
307 | static 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); | |||
326 | static void stunalloc (pointer); | 326 | static void stunalloc (pointer); |
327 | static void ungrabstackstr (char *, char *); | 327 | static void ungrabstackstr (char *, char *); |
328 | static char * growstackstr(void); | 328 | static char * growstackstr(void); |
329 | static char * makestrspace(size_t newlen); | ||
329 | static char *sstrdup (const char *); | 330 | static 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 | ||
371 | static 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 | ||
662 | struct 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 | ||
679 | static struct output output = {NULL, NULL, 0, NULL, 0, 1, 0}; | ||
680 | static struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0}; | ||
681 | static struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0}; | ||
682 | #else | ||
683 | static struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0}; | ||
684 | static struct output errout = {NULL, 0, NULL, 0, 2, 0}; | ||
685 | static struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0}; | ||
686 | #endif | ||
687 | static struct output *out1 = &output; | ||
688 | static struct output *out2 = &errout; | ||
689 | |||
690 | #ifndef USE_GLIBC_STDIO | ||
691 | static void outcslow (char, struct output *); | ||
692 | #endif | ||
693 | static void flushall (void); | 665 | static void flushall (void); |
694 | static void flushout (struct output *); | 666 | static void out2fmt (const char *, ...) |
695 | static void freestdout (void); | 667 | __attribute__((__format__(__printf__,1,2))); |
696 | static void outfmt (struct output *, const char *, ...) | ||
697 | __attribute__((__format__(__printf__,2,3))); | ||
698 | static void out1fmt (const char *, ...) | 668 | static void out1fmt (const char *, ...) |
699 | __attribute__((__format__(__printf__,1,2))); | 669 | __attribute__((__format__(__printf__,1,2))); |
700 | static void fmtstr (char *, size_t, const char *, ...) | ||
701 | __attribute__((__format__(__printf__,3,4))); | ||
702 | #ifndef USE_GLIBC_STDIO | ||
703 | static void doformat (struct output *, const char *, va_list); | ||
704 | #endif | ||
705 | static int xwrite (int, const char *, int); | 670 | static int xwrite (int, const char *, int); |
706 | #ifdef USE_GLIBC_STDIO | ||
707 | static void initstreams (void); | ||
708 | static void openmemout (void); | ||
709 | static int __closememout (void); | ||
710 | #endif | ||
711 | 671 | ||
712 | static void outstr(const char *p, struct output *file); | 672 | static void outstr (const char *p, FILE *file) { fputs(p, file); } |
673 | static void out1str(const char *p) { outstr(p, stdout); } | ||
674 | static 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 */ |
729 | static const char basesyntax[257] = { | 679 | static 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 | |||
1392 | struct alias { | 1344 | struct 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 **); | |||
1653 | static int hashcmd (int, char **); | 1605 | static int hashcmd (int, char **); |
1654 | static int jobscmd (int, char **); | 1606 | static int jobscmd (int, char **); |
1655 | static int localcmd (int, char **); | 1607 | static int localcmd (int, char **); |
1656 | #ifdef ASH_PWD | 1608 | #ifndef BB_PWD |
1657 | static int pwdcmd (int, char **); | 1609 | static int pwdcmd (int, char **); |
1658 | #endif | 1610 | #endif |
1659 | static int readcmd (int, char **); | 1611 | static 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 |
2053 | static int | 2005 | static int |
2054 | pwdcmd(argc, argv) | 2006 | pwdcmd(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 |
2366 | static void | 2314 | static void |
2367 | __inton() { | 2315 | __inton() { |
2368 | if (--suppressint == 0 && intpending) { | 2316 | if (--suppressint == 0 && intpending) { |
2369 | onint(); | 2317 | onint(); |
2370 | } | 2318 | } |
2371 | } | 2319 | } |
2320 | static 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); | |||
2394 | static void evalsubshell (union node *, int); | 2347 | static void evalsubshell (union node *, int); |
2395 | static void expredir (union node *); | 2348 | static void expredir (union node *); |
2396 | static void evalpipe (union node *); | 2349 | static void evalpipe (union node *); |
2397 | #ifdef notyet | ||
2398 | static void evalcommand (union node *, int, struct backcmd *); | ||
2399 | #else | ||
2400 | static void evalcommand (union node *, int); | 2350 | static void evalcommand (union node *, int); |
2401 | #endif | ||
2402 | static void prehash (union node *); | 2351 | static void prehash (union node *); |
2403 | static void eprintlist (struct strlist *); | 2352 | static 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; | ||
2890 | out: | 2817 | out: |
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 | ||
2915 | static void | 2842 | static void |
2916 | #ifdef notyet | 2843 | evalcommand(union node *cmd, int flags) |
2917 | evalcommand(cmd, flags, backcmd) | ||
2918 | union node *cmd; | ||
2919 | int flags; | ||
2920 | struct backcmd *backcmd; | ||
2921 | #else | ||
2922 | evalcommand(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(); |
3236 | cmddone: | 3100 | cmddone: |
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 | ||
3302 | out: | 3139 | out: |
@@ -3477,7 +3314,7 @@ static void | |||
3477 | eprintlist(struct strlist *sp) | 3314 | eprintlist(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()) |
3658 | static int | 3495 | static int |
3659 | pgetc(void) | 3496 | pgetc(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 | ||
4517 | out: | 4369 | out: |
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 | ||
6521 | again: | 6350 | again: |
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 | */ | ||
6671 | static int fileno2 = 2; | ||
6672 | |||
6673 | static int openredirect (union node *); | 6494 | static int openredirect (union node *); |
6674 | static void dupredirect (union node *, int, char[10 ]); | 6495 | static void dupredirect (union node *, int, char[10 ]); |
6675 | static int openhere (union node *); | 6496 | static 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; |
9649 | out: | 9462 | out: |
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 | ||
9725 | static void __outstr (const char *, size_t, struct output*); | ||
9726 | #endif | ||
9727 | |||
9728 | |||
9729 | #ifndef USE_GLIBC_STDIO | ||
9730 | static 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 | |||
9774 | static void | ||
9775 | outstr(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 | |||
9801 | static void | ||
9802 | outcslow(c, dest) | ||
9803 | char c; | ||
9804 | struct output *dest; | ||
9805 | { | ||
9806 | __outstr(&c, 1, dest); | ||
9807 | } | ||
9808 | #endif | ||
9809 | |||
9810 | |||
9811 | static void | 9523 | static void |
9812 | flushall() { | 9524 | flushall() { |
9813 | flushout(&output); | ||
9814 | #ifdef FLUSHERR | ||
9815 | flushout(&errout); | ||
9816 | #endif | ||
9817 | } | ||
9818 | |||
9819 | |||
9820 | static void | ||
9821 | flushout(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 | |||
9842 | static void | ||
9843 | freestdout() { | ||
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 | ||
9855 | static void | 9531 | static void |
9856 | #ifdef __STDC__ | 9532 | out2fmt(const char *fmt, ...) |
9857 | outfmt(struct output *file, const char *fmt, ...) | ||
9858 | #else | ||
9859 | static void | ||
9860 | outfmt(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 | ||
9880 | static void | 9541 | static void |
9881 | #ifdef __STDC__ | ||
9882 | out1fmt(const char *fmt, ...) | 9542 | out1fmt(const char *fmt, ...) |
9883 | #else | ||
9884 | out1fmt(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 | ||
9901 | static void | ||
9902 | #ifdef __STDC__ | ||
9903 | fmtstr(char *outbuf, size_t length, const char *fmt, ...) | ||
9904 | #else | ||
9905 | fmtstr(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 | |||
9929 | static void | ||
9930 | doformat(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 | ||
9984 | static void initstreams() { | ||
9985 | output.stream = stdout; | ||
9986 | errout.stream = stderr; | ||
9987 | } | ||
9988 | |||
9989 | |||
9990 | static void | ||
9991 | openmemout() { | ||
9992 | INTOFF; | ||
9993 | memout.stream = open_memstream(&memout.buf, &memout.bufsize); | ||
9994 | INTON; | ||
9995 | } | ||
9996 | |||
9997 | |||
9998 | static 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 | |||
11473 | synerror(const char *msg) | 11051 | synerror(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 | */ |
11487 | static const char * | 11065 | static inline const char * |
11488 | getprompt(void *unused) | 11066 | getprompt(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 | ||
11531 | static void | 11109 | static 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 | */ |
13533 | static int timescmd (int argc, char **argv) | 13093 | static 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; | |||
302 | static volatile int intpending; | 299 | static 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 |
308 | static void __inton (void); | 306 | static void __inton (void); |
307 | static 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); | |||
326 | static void stunalloc (pointer); | 326 | static void stunalloc (pointer); |
327 | static void ungrabstackstr (char *, char *); | 327 | static void ungrabstackstr (char *, char *); |
328 | static char * growstackstr(void); | 328 | static char * growstackstr(void); |
329 | static char * makestrspace(size_t newlen); | ||
329 | static char *sstrdup (const char *); | 330 | static 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 | ||
371 | static 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 | ||
662 | struct 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 | ||
679 | static struct output output = {NULL, NULL, 0, NULL, 0, 1, 0}; | ||
680 | static struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0}; | ||
681 | static struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0}; | ||
682 | #else | ||
683 | static struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0}; | ||
684 | static struct output errout = {NULL, 0, NULL, 0, 2, 0}; | ||
685 | static struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0}; | ||
686 | #endif | ||
687 | static struct output *out1 = &output; | ||
688 | static struct output *out2 = &errout; | ||
689 | |||
690 | #ifndef USE_GLIBC_STDIO | ||
691 | static void outcslow (char, struct output *); | ||
692 | #endif | ||
693 | static void flushall (void); | 665 | static void flushall (void); |
694 | static void flushout (struct output *); | 666 | static void out2fmt (const char *, ...) |
695 | static void freestdout (void); | 667 | __attribute__((__format__(__printf__,1,2))); |
696 | static void outfmt (struct output *, const char *, ...) | ||
697 | __attribute__((__format__(__printf__,2,3))); | ||
698 | static void out1fmt (const char *, ...) | 668 | static void out1fmt (const char *, ...) |
699 | __attribute__((__format__(__printf__,1,2))); | 669 | __attribute__((__format__(__printf__,1,2))); |
700 | static void fmtstr (char *, size_t, const char *, ...) | ||
701 | __attribute__((__format__(__printf__,3,4))); | ||
702 | #ifndef USE_GLIBC_STDIO | ||
703 | static void doformat (struct output *, const char *, va_list); | ||
704 | #endif | ||
705 | static int xwrite (int, const char *, int); | 670 | static int xwrite (int, const char *, int); |
706 | #ifdef USE_GLIBC_STDIO | ||
707 | static void initstreams (void); | ||
708 | static void openmemout (void); | ||
709 | static int __closememout (void); | ||
710 | #endif | ||
711 | 671 | ||
712 | static void outstr(const char *p, struct output *file); | 672 | static void outstr (const char *p, FILE *file) { fputs(p, file); } |
673 | static void out1str(const char *p) { outstr(p, stdout); } | ||
674 | static 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 */ |
729 | static const char basesyntax[257] = { | 679 | static 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 | |||
1392 | struct alias { | 1344 | struct 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 **); | |||
1653 | static int hashcmd (int, char **); | 1605 | static int hashcmd (int, char **); |
1654 | static int jobscmd (int, char **); | 1606 | static int jobscmd (int, char **); |
1655 | static int localcmd (int, char **); | 1607 | static int localcmd (int, char **); |
1656 | #ifdef ASH_PWD | 1608 | #ifndef BB_PWD |
1657 | static int pwdcmd (int, char **); | 1609 | static int pwdcmd (int, char **); |
1658 | #endif | 1610 | #endif |
1659 | static int readcmd (int, char **); | 1611 | static 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 |
2053 | static int | 2005 | static int |
2054 | pwdcmd(argc, argv) | 2006 | pwdcmd(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 |
2366 | static void | 2314 | static void |
2367 | __inton() { | 2315 | __inton() { |
2368 | if (--suppressint == 0 && intpending) { | 2316 | if (--suppressint == 0 && intpending) { |
2369 | onint(); | 2317 | onint(); |
2370 | } | 2318 | } |
2371 | } | 2319 | } |
2320 | static 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); | |||
2394 | static void evalsubshell (union node *, int); | 2347 | static void evalsubshell (union node *, int); |
2395 | static void expredir (union node *); | 2348 | static void expredir (union node *); |
2396 | static void evalpipe (union node *); | 2349 | static void evalpipe (union node *); |
2397 | #ifdef notyet | ||
2398 | static void evalcommand (union node *, int, struct backcmd *); | ||
2399 | #else | ||
2400 | static void evalcommand (union node *, int); | 2350 | static void evalcommand (union node *, int); |
2401 | #endif | ||
2402 | static void prehash (union node *); | 2351 | static void prehash (union node *); |
2403 | static void eprintlist (struct strlist *); | 2352 | static 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; | ||
2890 | out: | 2817 | out: |
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 | ||
2915 | static void | 2842 | static void |
2916 | #ifdef notyet | 2843 | evalcommand(union node *cmd, int flags) |
2917 | evalcommand(cmd, flags, backcmd) | ||
2918 | union node *cmd; | ||
2919 | int flags; | ||
2920 | struct backcmd *backcmd; | ||
2921 | #else | ||
2922 | evalcommand(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(); |
3236 | cmddone: | 3100 | cmddone: |
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 | ||
3302 | out: | 3139 | out: |
@@ -3477,7 +3314,7 @@ static void | |||
3477 | eprintlist(struct strlist *sp) | 3314 | eprintlist(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()) |
3658 | static int | 3495 | static int |
3659 | pgetc(void) | 3496 | pgetc(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 | ||
4517 | out: | 4369 | out: |
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 | ||
6521 | again: | 6350 | again: |
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 | */ | ||
6671 | static int fileno2 = 2; | ||
6672 | |||
6673 | static int openredirect (union node *); | 6494 | static int openredirect (union node *); |
6674 | static void dupredirect (union node *, int, char[10 ]); | 6495 | static void dupredirect (union node *, int, char[10 ]); |
6675 | static int openhere (union node *); | 6496 | static 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; |
9649 | out: | 9462 | out: |
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 | ||
9725 | static void __outstr (const char *, size_t, struct output*); | ||
9726 | #endif | ||
9727 | |||
9728 | |||
9729 | #ifndef USE_GLIBC_STDIO | ||
9730 | static 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 | |||
9774 | static void | ||
9775 | outstr(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 | |||
9801 | static void | ||
9802 | outcslow(c, dest) | ||
9803 | char c; | ||
9804 | struct output *dest; | ||
9805 | { | ||
9806 | __outstr(&c, 1, dest); | ||
9807 | } | ||
9808 | #endif | ||
9809 | |||
9810 | |||
9811 | static void | 9523 | static void |
9812 | flushall() { | 9524 | flushall() { |
9813 | flushout(&output); | ||
9814 | #ifdef FLUSHERR | ||
9815 | flushout(&errout); | ||
9816 | #endif | ||
9817 | } | ||
9818 | |||
9819 | |||
9820 | static void | ||
9821 | flushout(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 | |||
9842 | static void | ||
9843 | freestdout() { | ||
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 | ||
9855 | static void | 9531 | static void |
9856 | #ifdef __STDC__ | 9532 | out2fmt(const char *fmt, ...) |
9857 | outfmt(struct output *file, const char *fmt, ...) | ||
9858 | #else | ||
9859 | static void | ||
9860 | outfmt(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 | ||
9880 | static void | 9541 | static void |
9881 | #ifdef __STDC__ | ||
9882 | out1fmt(const char *fmt, ...) | 9542 | out1fmt(const char *fmt, ...) |
9883 | #else | ||
9884 | out1fmt(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 | ||
9901 | static void | ||
9902 | #ifdef __STDC__ | ||
9903 | fmtstr(char *outbuf, size_t length, const char *fmt, ...) | ||
9904 | #else | ||
9905 | fmtstr(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 | |||
9929 | static void | ||
9930 | doformat(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 | ||
9984 | static void initstreams() { | ||
9985 | output.stream = stdout; | ||
9986 | errout.stream = stderr; | ||
9987 | } | ||
9988 | |||
9989 | |||
9990 | static void | ||
9991 | openmemout() { | ||
9992 | INTOFF; | ||
9993 | memout.stream = open_memstream(&memout.buf, &memout.bufsize); | ||
9994 | INTON; | ||
9995 | } | ||
9996 | |||
9997 | |||
9998 | static 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 | |||
11473 | synerror(const char *msg) | 11051 | synerror(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 | */ |
11487 | static const char * | 11065 | static inline const char * |
11488 | getprompt(void *unused) | 11066 | getprompt(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 | ||
11531 | static void | 11109 | static 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 | */ |
13533 | static int timescmd (int argc, char **argv) | 13093 | static int timescmd (int argc, char **argv) |
13534 | { | 13094 | { |