diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2009-04-01 13:01:54 +0000 |
---|---|---|
committer | Peter Korsgaard <jacmet@sunsite.dk> | 2009-04-01 13:01:54 +0000 |
commit | b54bedd60c7e77ef274d272ec5807fce85134ad3 (patch) | |
tree | 3424849e97c9d44aae55ee2ff0b28e0c24088c71 /package/busybox/busybox-1.13.3-ash.patch | |
parent | bb62b139ba7a1dd1e160b2151dc1f9f3eb6cd60f (diff) |
busybox: additional 1.13.3 fixes
Diffstat (limited to 'package/busybox/busybox-1.13.3-ash.patch')
-rw-r--r-- | package/busybox/busybox-1.13.3-ash.patch | 460 |
1 files changed, 448 insertions, 12 deletions
diff --git a/package/busybox/busybox-1.13.3-ash.patch b/package/busybox/busybox-1.13.3-ash.patch index 761af28d5..eeb4d7f46 100644 --- a/package/busybox/busybox-1.13.3-ash.patch +++ b/package/busybox/busybox-1.13.3-ash.patch @@ -1,6 +1,152 @@ ---- busybox-1.13.3/shell/ash.c Thu Feb 26 12:46:55 2009 -+++ busybox-1.13.3-ash/shell/ash.c Thu Mar 19 04:34:01 2009 -@@ -376,7 +376,6 @@ +diff -urpN busybox-1.13.3/shell/ash.c busybox-1.13.3-ash/shell/ash.c +--- busybox-1.13.3/shell/ash.c 2009-02-26 12:46:55.000000000 +0100 ++++ busybox-1.13.3-ash/shell/ash.c 2009-04-01 01:16:44.000000000 +0200 +@@ -30,7 +30,7 @@ + */ + + /* +- * The follow should be set to reflect the type of system you have: ++ * The following should be set to reflect the type of system you have: + * JOBS -> 1 if you have Berkeley job control, 0 otherwise. + * define SYSV if you are running under System V. + * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) +@@ -40,6 +40,11 @@ + * a quit signal will generate a core dump. + */ + #define DEBUG 0 ++/* Tweak debug output verbosity here */ ++#define DEBUG_TIME 0 ++#define DEBUG_PID 1 ++#define DEBUG_SIG 1 ++ + #define PROFILE 0 + + #define IFS_BROKEN +@@ -47,9 +52,9 @@ + #define JOBS ENABLE_ASH_JOB_CONTROL + + #if DEBUG +-#ifndef _GNU_SOURCE +-#define _GNU_SOURCE +-#endif ++# ifndef _GNU_SOURCE ++# define _GNU_SOURCE ++# endif + #endif + + #include "busybox.h" /* for applet_names */ +@@ -57,15 +62,15 @@ + #include <setjmp.h> + #include <fnmatch.h> + #if JOBS || ENABLE_ASH_READ_NCHARS +-#include <termios.h> ++# include <termios.h> + #endif + + #ifndef PIPE_BUF +-#define PIPE_BUF 4096 /* amount of buffering in a pipe */ ++# define PIPE_BUF 4096 /* amount of buffering in a pipe */ + #endif + + #if defined(__uClinux__) +-#error "Do not even bother, ash will not run on uClinux" ++# error "Do not even bother, ash will not run on uClinux" + #endif + + +@@ -76,14 +81,6 @@ + #define CMDTABLESIZE 31 /* should be prime */ + + +-/* ============ Misc helpers */ +- +-#define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0) +- +-/* C99 say: "char" declaration may be signed or unsigned default */ +-#define signed_char2int(sc) ((int)((signed char)sc)) +- +- + /* ============ Shell options */ + + static const char *const optletters_optnames[] = { +@@ -245,7 +242,30 @@ extern struct globals_misc *const ash_pt + } while (0) + + ++/* ============ DEBUG */ ++#if DEBUG ++static void trace_printf(const char *fmt, ...); ++static void trace_vprintf(const char *fmt, va_list va); ++# define TRACE(param) trace_printf param ++# define TRACEV(param) trace_vprintf param ++# define close(f) do { \ ++ int dfd = (f); \ ++ if (close(dfd) < 0) \ ++ bb_error_msg("bug on %d: closing %d(%x)", \ ++ __LINE__, dfd, dfd); \ ++} while (0) ++#else ++# define TRACE(param) ++# define TRACEV(param) ++#endif ++ ++ + /* ============ Utility functions */ ++#define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0) ++ ++/* C99 say: "char" declaration may be signed or unsigned by default */ ++#define signed_char2int(sc) ((int)(signed char)(sc)) ++ + static int isdigit_str9(const char *str) + { + int maxlen = 9 + 1; /* max 9 digits: 999999999 */ +@@ -284,6 +304,12 @@ raise_exception(int e) + exception = e; + longjmp(exception_handler->loc, 1); + } ++#if DEBUG ++#define raise_exception(e) do { \ ++ TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \ ++ raise_exception(e); \ ++} while (0) ++#endif + + /* + * Called from trap.c when a SIGINT is received. (If the user specifies +@@ -316,6 +342,12 @@ raise_interrupt(void) + raise_exception(i); + /* NOTREACHED */ + } ++#if DEBUG ++#define raise_interrupt() do { \ ++ TRACE(("raising interrupt on line %d\n", __LINE__)); \ ++ raise_interrupt(); \ ++} while (0) ++#endif + + #if ENABLE_ASH_OPTIMIZE_FOR_SIZE + static void +@@ -334,7 +366,9 @@ force_int_on(void) + raise_interrupt(); + } + #define FORCE_INT_ON force_int_on() +-#else ++ ++#else /* !ASH_OPTIMIZE_FOR_SIZE */ ++ + #define INT_ON do { \ + xbarrier(); \ + if (--suppressint == 0 && intpending) \ +@@ -346,7 +380,7 @@ force_int_on(void) + if (intpending) \ + raise_interrupt(); \ + } while (0) +-#endif /* ASH_OPTIMIZE_FOR_SIZE */ ++#endif /* !ASH_OPTIMIZE_FOR_SIZE */ + + #define SAVE_INT(v) ((v) = suppressint) + +@@ -376,7 +410,6 @@ static void onsig(int signo) { gotsig[signo - 1] = 1; @@ -8,7 +154,7 @@ if (/* exsig || */ (signo == SIGINT && !trap[SIGINT])) { if (!suppressint) { -@@ -384,6 +383,8 @@ +@@ -384,6 +417,8 @@ onsig(int signo) raise_interrupt(); /* does not return */ } intpending = 1; @@ -17,7 +163,268 @@ } } -@@ -13692,15 +13693,20 @@ +@@ -684,6 +719,12 @@ trace_printf(const char *fmt, ...) + + if (debug != 1) + return; ++ if (DEBUG_TIME) ++ fprintf(tracefile, "%u ", (int) time(NULL)); ++ if (DEBUG_PID) ++ fprintf(tracefile, "[%u] ", (int) getpid()); ++ if (DEBUG_SIG) ++ fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint); + va_start(va, fmt); + vfprintf(tracefile, fmt, va); + va_end(va); +@@ -694,6 +735,12 @@ trace_vprintf(const char *fmt, va_list v + { + if (debug != 1) + return; ++ if (DEBUG_TIME) ++ fprintf(tracefile, "%u ", (int) time(NULL)); ++ if (DEBUG_PID) ++ fprintf(tracefile, "[%u] ", (int) getpid()); ++ if (DEBUG_SIG) ++ fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint); + vfprintf(tracefile, fmt, va); + } + +@@ -998,14 +1045,6 @@ showtree(union node *n) + shtree(n, 1, NULL, stdout); + } + +-#define TRACE(param) trace_printf param +-#define TRACEV(param) trace_vprintf param +- +-#else +- +-#define TRACE(param) +-#define TRACEV(param) +- + #endif /* DEBUG */ + + +@@ -3779,7 +3818,7 @@ dowait(int wait_flags, struct job *job) + * NB: _not_ safe_waitpid, we need to detect EINTR */ + pid = waitpid(-1, &status, + (doing_jobctl ? (wait_flags | WUNTRACED) : wait_flags)); +- TRACE(("wait returns pid=%d, status=0x%x\n", pid, status)); ++ TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n", pid, status, errno, strerror(errno))); + + if (pid <= 0) { + /* If we were doing blocking wait and (probably) got EINTR, +@@ -5031,7 +5070,9 @@ redirect(union node *redir, int flags) + if (newfd < 0) { + /* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */ + if (redir->ndup.dupfd < 0) { /* "fd>&-" */ +- close(fd); ++ /* Don't want to trigger debugging */ ++ if (fd != -1) ++ close(fd); + } else { + copyfd(redir->ndup.dupfd, fd | COPYFD_EXACT); + } +@@ -5084,7 +5125,7 @@ popredir(int drop, int restore) + /*close(fd);*/ + copyfd(copy, fd | COPYFD_EXACT); + } +- close(copy); ++ close(copy & ~COPYFD_RESTORE); + } + } + redirlist = rp->next; +@@ -7871,20 +7912,30 @@ dotrap(void) + pendingsig = 0; + xbarrier(); + ++ TRACE(("dotrap entered\n")); + for (i = 1, q = gotsig; i < NSIG; i++, q++) { + if (!*q) + continue; +- *q = '\0'; + + p = trap[i]; ++ /* non-trapped SIGINT is handled separately by raise_interrupt, ++ * don't upset it by resetting gotsig[SIGINT-1] */ ++ if (i == SIGINT && !p) ++ continue; ++ ++ TRACE(("sig %d is active, will run handler '%s'\n", i, p)); ++ *q = '\0'; + if (!p) + continue; + skip = evalstring(p, SKIPEVAL); + exitstatus = savestatus; +- if (skip) ++ if (skip) { ++ TRACE(("dotrap returns %d\n", skip)); + return skip; ++ } + } + ++ TRACE(("dotrap returns 0\n")); + return 0; + } + +@@ -7906,28 +7957,32 @@ static void prehash(union node *); + static void + evaltree(union node *n, int flags) + { +- + struct jmploc *volatile savehandler = exception_handler; + struct jmploc jmploc; + int checkexit = 0; + void (*evalfn)(union node *, int); + int status; ++ int int_level; ++ ++ SAVE_INT(int_level); + + if (n == NULL) { + TRACE(("evaltree(NULL) called\n")); + goto out1; + } +- TRACE(("pid %d, evaltree(%p: %d, %d) called\n", +- getpid(), n, n->type, flags)); ++ TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags)); + + exception_handler = &jmploc; + { + int err = setjmp(jmploc.loc); + if (err) { + /* if it was a signal, check for trap handlers */ +- if (exception == EXSIG) ++ if (exception == EXSIG) { ++ TRACE(("exception %d (EXSIG) in evaltree, err=%d\n", exception, err)); + goto out; ++ } + /* continue on the way out */ ++ TRACE(("exception %d in evaltree, propagating err=%d\n", exception, err)); + exception_handler = savehandler; + longjmp(exception_handler->loc, err); + } +@@ -8010,7 +8065,8 @@ evaltree(union node *n, int flags) + if (exitstatus == 0) { + n = n->nif.ifpart; + goto evaln; +- } else if (n->nif.elsepart) { ++ } ++ if (n->nif.elsepart) { + n = n->nif.elsepart; + goto evaln; + } +@@ -8036,6 +8092,9 @@ evaltree(union node *n, int flags) + exexit: + raise_exception(EXEXIT); + } ++ ++ RESTORE_INT(int_level); ++ TRACE(("leaving evaltree (no interrupts)\n")); + } + + #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3) +@@ -8281,7 +8340,9 @@ evalpipe(union node *n, int flags) + if (prevfd >= 0) + close(prevfd); + prevfd = pip[0]; +- close(pip[1]); ++ /* Don't want to trigger debugging */ ++ if (pip[1] != -1) ++ close(pip[1]); + } + if (n->npipe.pipe_backgnd == 0) { + exitstatus = waitforjob(jp); +@@ -8913,6 +8974,7 @@ evalcommand(union node *cmd, int flags) + if (forkshell(jp, cmd, FORK_FG) != 0) { + exitstatus = waitforjob(jp); + INT_ON; ++ TRACE(("forked child exited with %d\n", exitstatus)); + break; + } + FORCE_INT_ON; +@@ -12391,7 +12453,7 @@ readcmd(int argc UNUSED_PARAM, char **ar + #endif + + status = 0; +- startword = 1; ++ startword = 2; + backslash = 0; + #if ENABLE_ASH_READ_TIMEOUT + if (timeout) /* NB: ensuring end_ms is nonzero */ +@@ -12399,6 +12461,8 @@ readcmd(int argc UNUSED_PARAM, char **ar + #endif + STARTSTACKSTR(p); + do { ++ const char *is_ifs; ++ + #if ENABLE_ASH_READ_TIMEOUT + if (end_ms) { + struct pollfd pfd[1]; +@@ -12428,25 +12492,34 @@ readcmd(int argc UNUSED_PARAM, char **ar + continue; + } + if (!rflag && c == '\\') { +- backslash++; ++ backslash = 1; + continue; + } + if (c == '\n') + break; +- if (startword && *ifs == ' ' && strchr(ifs, c)) { +- continue; ++ is_ifs = strchr(ifs, c); ++ if (startword && is_ifs) { ++ if (isspace(c)) ++ continue; ++ /* non-space ifs char */ ++ startword--; ++ if (startword == 1) /* first one? */ ++ continue; + } + startword = 0; +- if (ap[1] != NULL && strchr(ifs, c) != NULL) { ++ if (ap[1] != NULL && is_ifs) { ++ const char *beg; + STACKSTRNUL(p); +- setvar(*ap, stackblock(), 0); ++ beg = stackblock(); ++ setvar(*ap, beg, 0); + ap++; +- startword = 1; ++ /* can we skip one non-space ifs? (2: yes) */ ++ startword = isspace(c) ? 2 : 1; + STARTSTACKSTR(p); +- } else { +- put: +- STPUTC(c, p); ++ continue; + } ++ put: ++ STPUTC(c, p); + } + /* end of do {} while: */ + #if ENABLE_ASH_READ_NCHARS +@@ -12460,8 +12533,8 @@ readcmd(int argc UNUSED_PARAM, char **ar + #endif + + STACKSTRNUL(p); +- /* Remove trailing blanks */ +- while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL) ++ /* Remove trailing space ifs chars */ ++ while ((char *)stackblock() <= --p && isspace(*p) && strchr(ifs, *p) != NULL) + *p = '\0'; + setvar(*ap, stackblock(), 0); + while (*++ap != NULL) +@@ -13640,7 +13713,7 @@ int ash_main(int argc UNUSED_PARAM, char + exception_handler = &jmploc; + #if DEBUG + opentrace(); +- trace_puts("Shell args: "); ++ TRACE(("Shell args: ")); + trace_puts_args(argv); + #endif + rootpid = getpid(); +@@ -13692,8 +13765,14 @@ int ash_main(int argc UNUSED_PARAM, char } state3: state = 4; @@ -33,11 +440,40 @@ if (sflag || minusc == NULL) { #if ENABLE_FEATURE_EDITING_SAVEHISTORY - if (iflag) { - const char *hp = lookupvar("HISTFILE"); +@@ -13720,14 +13799,6 @@ int ash_main(int argc UNUSED_PARAM, char + /* NOTREACHED */ + } + +-#if DEBUG +-const char *applet_name = "debug stuff usage"; +-int main(int argc, char **argv) +-{ +- return ash_main(argc, argv); +-} +-#endif - -- if (hp != NULL) -+ if (hp) - line_input_state->hist_file = hp; - } - #endif + + /*- + * Copyright (c) 1989, 1991, 1993, 1994 +diff -urpN busybox-1.13.3/shell/ash_test/ash-read/read_ifs.right busybox-1.13.3-ash/shell/ash_test/ash-read/read_ifs.right +--- busybox-1.13.3/shell/ash_test/ash-read/read_ifs.right 1970-01-01 01:00:00.000000000 +0100 ++++ busybox-1.13.3-ash/shell/ash_test/ash-read/read_ifs.right 2009-04-01 01:16:44.000000000 +0200 +@@ -0,0 +1,7 @@ ++.a. .b. .c. ++.a. .b. .c. ++.a. .. .b,c. ++.a. .. .b,c. ++.a. .. .c. ++.a. .. .c. .d. ++.a. .. .b,c,d , ,. +diff -urpN busybox-1.13.3/shell/ash_test/ash-read/read_ifs.tests busybox-1.13.3-ash/shell/ash_test/ash-read/read_ifs.tests +--- busybox-1.13.3/shell/ash_test/ash-read/read_ifs.tests 1970-01-01 01:00:00.000000000 +0100 ++++ busybox-1.13.3-ash/shell/ash_test/ash-read/read_ifs.tests 2009-04-01 01:16:44.000000000 +0200 +@@ -0,0 +1,7 @@ ++printf 'a\t\tb\tc\n' | ( IFS=$(printf "\t") read a b c; echo ".$a. .$b. .$c." ) ++printf 'a\t\tb\tc\n' | ( IFS=$(printf " \t") read a b c; echo ".$a. .$b. .$c." ) ++printf 'a,,b,c\n' | ( IFS="," read a b c; echo ".$a. .$b. .$c." ) ++printf 'a,,b,c\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." ) ++printf 'a ,, c\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." ) ++printf 'a ,, c d\n' | ( IFS=" ," read a b c d; echo ".$a. .$b. .$c. .$d." ) ++printf ' a,,b,c,d , ,\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." ) |