diff options
| author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-07-06 04:26:23 +0000 |
|---|---|---|
| committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-07-06 04:26:23 +0000 |
| commit | aa0b6cfc93e8ff0b8c51c2ad49bb66cd12831421 (patch) | |
| tree | 4f6d1fa7ff379817afc74301bac06baf9d0d6bd7 /shell | |
| parent | 9efd582dc713b90a69682538ec34579a2bd38afb (diff) | |
| download | busybox-w32-aa0b6cfc93e8ff0b8c51c2ad49bb66cd12831421.tar.gz busybox-w32-aa0b6cfc93e8ff0b8c51c2ad49bb66cd12831421.tar.bz2 busybox-w32-aa0b6cfc93e8ff0b8c51c2ad49bb66cd12831421.zip | |
This is vodz' latest ash update.
git-svn-id: svn://busybox.net/trunk/busybox@3013 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 702 |
1 files changed, 131 insertions, 571 deletions
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 | { |
