busybox: bump 1.13.x version
This commit is contained in:
parent
ef8fd64dcb
commit
edfe9feee7
@ -66,7 +66,7 @@ config BR2_BUSYBOX_VERSION
|
||||
default "1.10.4" if BR2_BUSYBOX_VERSION_1_10_X
|
||||
default "1.11.3" if BR2_BUSYBOX_VERSION_1_11_X
|
||||
default "1.12.4" if BR2_BUSYBOX_VERSION_1_12_X
|
||||
default "1.13.3" if BR2_BUSYBOX_VERSION_1_13_X
|
||||
default "1.13.4" if BR2_BUSYBOX_VERSION_1_13_X
|
||||
|
||||
config BR2_PACKAGE_BUSYBOX_FULLINSTALL
|
||||
bool "Run BusyBox's own full installation"
|
||||
|
@ -1,479 +0,0 @@
|
||||
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;
|
||||
- pendingsig = signo;
|
||||
|
||||
if (/* exsig || */ (signo == SIGINT && !trap[SIGINT])) {
|
||||
if (!suppressint) {
|
||||
@@ -384,6 +417,8 @@ onsig(int signo)
|
||||
raise_interrupt(); /* does not return */
|
||||
}
|
||||
intpending = 1;
|
||||
+ } else {
|
||||
+ pendingsig = signo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
- if (minusc)
|
||||
+ if (minusc) {
|
||||
+ /* evalstring pushes parsefile stack.
|
||||
+ * Ensure we don't falsely claim that 0 (stdin)
|
||||
+ * is one of stacked source fds */
|
||||
+ if (!sflag)
|
||||
+ g_parsefile->fd = -1;
|
||||
evalstring(minusc, 0);
|
||||
+ }
|
||||
|
||||
if (sflag || minusc == NULL) {
|
||||
#if ENABLE_FEATURE_EDITING_SAVEHISTORY
|
||||
@@ -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
|
||||
-
|
||||
|
||||
/*-
|
||||
* 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." )
|
@ -1,179 +0,0 @@
|
||||
diff -urpN busybox-1.13.3/shell/hush.c busybox-1.13.3-hush/shell/hush.c
|
||||
--- busybox-1.13.3/shell/hush.c 2009-02-26 12:46:55.000000000 +0100
|
||||
+++ busybox-1.13.3-hush/shell/hush.c 2009-03-22 12:46:42.000000000 +0100
|
||||
@@ -458,8 +458,11 @@ struct globals {
|
||||
smallint fake_mode;
|
||||
/* these three support $?, $#, and $1 */
|
||||
smalluint last_return_code;
|
||||
- char **global_argv;
|
||||
+ /* is global_argv and global_argv[1..n] malloced? (note: not [0]) */
|
||||
+ smalluint global_args_malloced;
|
||||
+ /* how many non-NULL argv's we have. NB: $# + 1 */
|
||||
int global_argc;
|
||||
+ char **global_argv;
|
||||
#if ENABLE_HUSH_LOOPS
|
||||
unsigned depth_break_continue;
|
||||
unsigned depth_of_loop;
|
||||
@@ -633,7 +636,7 @@ static char *unbackslash(char *src)
|
||||
return dst;
|
||||
}
|
||||
|
||||
-static char **add_strings_to_strings(char **strings, char **add)
|
||||
+static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
|
||||
{
|
||||
int i;
|
||||
unsigned count1;
|
||||
@@ -658,7 +661,7 @@ static char **add_strings_to_strings(cha
|
||||
v[count1 + count2] = NULL;
|
||||
i = count2;
|
||||
while (--i >= 0)
|
||||
- v[count1 + i] = add[i];
|
||||
+ v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -667,7 +670,7 @@ static char **add_string_to_strings(char
|
||||
char *v[2];
|
||||
v[0] = add;
|
||||
v[1] = NULL;
|
||||
- return add_strings_to_strings(strings, v);
|
||||
+ return add_strings_to_strings(strings, v, /*dup:*/ 0);
|
||||
}
|
||||
|
||||
static void putenv_all(char **strings)
|
||||
@@ -1213,8 +1216,13 @@ static int o_glob(o_string *o, int n)
|
||||
* Otherwise, just finish current list[] and start new */
|
||||
static int o_save_ptr(o_string *o, int n)
|
||||
{
|
||||
- if (o->o_glob)
|
||||
- return o_glob(o, n); /* o_save_ptr_helper is inside */
|
||||
+ if (o->o_glob) { /* if globbing is requested */
|
||||
+ /* If o->has_empty_slot, list[n] was already globbed
|
||||
+ * (if it was requested back then when it was filled)
|
||||
+ * so don't do that again! */
|
||||
+ if (!o->has_empty_slot)
|
||||
+ return o_glob(o, n); /* o_save_ptr_helper is inside */
|
||||
+ }
|
||||
return o_save_ptr_helper(o, n);
|
||||
}
|
||||
|
||||
@@ -4279,6 +4287,11 @@ int hush_main(int argc, char **argv)
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
G.global_argv = argv + optind;
|
||||
+ if (!argv[optind]) {
|
||||
+ /* -c 'script' (no params): prevent empty $0 */
|
||||
+ *--G.global_argv = argv[0];
|
||||
+ optind--;
|
||||
+ } /* else -c 'script' PAR0 PAR1: $0 is PAR0 */
|
||||
G.global_argc = argc - optind;
|
||||
opt = parse_and_run_string(optarg, 0 /* parse_flag */);
|
||||
goto final_return;
|
||||
@@ -4639,17 +4652,68 @@ static int builtin_read(char **argv)
|
||||
return set_local_var(string, 0);
|
||||
}
|
||||
|
||||
-/* built-in 'set [VAR=value]' handler */
|
||||
+/* built-in 'set' handler
|
||||
+ * SUSv3 says:
|
||||
+ * set [-abCefmnuvx] [-h] [-o option] [argument...]
|
||||
+ * set [+abCefmnuvx] [+h] [+o option] [argument...]
|
||||
+ * set -- [argument...]
|
||||
+ * set -o
|
||||
+ * set +o
|
||||
+ * Implementations shall support the options in both their hyphen and
|
||||
+ * plus-sign forms. These options can also be specified as options to sh.
|
||||
+ * Examples:
|
||||
+ * Write out all variables and their values: set
|
||||
+ * Set $1, $2, and $3 and set "$#" to 3: set c a b
|
||||
+ * Turn on the -x and -v options: set -xv
|
||||
+ * Unset all positional parameters: set --
|
||||
+ * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
|
||||
+ * Set the positional parameters to the expansion of x, even if x expands
|
||||
+ * with a leading '-' or '+': set -- $x
|
||||
+ *
|
||||
+ * So far, we only support "set -- [argument...]" by ignoring all options
|
||||
+ * (also, "-o option" will be mishandled by taking "option" as parameter #1).
|
||||
+ */
|
||||
static int builtin_set(char **argv)
|
||||
{
|
||||
- char *temp = argv[1];
|
||||
struct variable *e;
|
||||
+ char **pp;
|
||||
+ char *arg = *++argv;
|
||||
|
||||
- if (temp == NULL)
|
||||
+ if (arg == NULL) {
|
||||
for (e = G.top_var; e; e = e->next)
|
||||
puts(e->varstr);
|
||||
- else
|
||||
- set_local_var(xstrdup(temp), 0);
|
||||
+ } else {
|
||||
+ /* NB: G.global_argv[0] ($0) is never freed/changed */
|
||||
+
|
||||
+ if (G.global_args_malloced) {
|
||||
+ pp = G.global_argv;
|
||||
+ while (*++pp)
|
||||
+ free(*pp);
|
||||
+ G.global_argv[1] = NULL;
|
||||
+ } else {
|
||||
+ G.global_args_malloced = 1;
|
||||
+ pp = xzalloc(sizeof(pp[0]) * 2);
|
||||
+ pp[0] = G.global_argv[0]; /* retain $0 */
|
||||
+ G.global_argv = pp;
|
||||
+ }
|
||||
+ do {
|
||||
+ if (arg[0] == '+')
|
||||
+ continue;
|
||||
+ if (arg[0] != '-')
|
||||
+ break;
|
||||
+ if (arg[1] == '-' && arg[2] == '\0') {
|
||||
+ argv++;
|
||||
+ break;
|
||||
+ }
|
||||
+ } while ((arg = *++argv) != NULL);
|
||||
+ /* Now argv[0] is 1st argument */
|
||||
+
|
||||
+ /* This realloc's G.global_argv */
|
||||
+ G.global_argv = pp = add_strings_to_strings(G.global_argv, argv, /*dup:*/ 1);
|
||||
+ G.global_argc = 1;
|
||||
+ while (*++pp)
|
||||
+ G.global_argc++;
|
||||
+ }
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -4661,9 +4725,14 @@ static int builtin_shift(char **argv)
|
||||
n = atoi(argv[1]);
|
||||
}
|
||||
if (n >= 0 && n < G.global_argc) {
|
||||
- G.global_argv[n] = G.global_argv[0];
|
||||
+ if (G.global_args_malloced) {
|
||||
+ int m = 1;
|
||||
+ while (m <= n)
|
||||
+ free(G.global_argv[m++]);
|
||||
+ }
|
||||
G.global_argc -= n;
|
||||
- G.global_argv += n;
|
||||
+ memmove(&G.global_argv[1], &G.global_argv[n+1],
|
||||
+ G.global_argc * sizeof(G.global_argv[0]));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
diff -urpN busybox-1.13.3/shell/hush_test/hush-parsing/starquoted2.right busybox-1.13.3-hush/shell/hush_test/hush-parsing/starquoted2.right
|
||||
--- busybox-1.13.3/shell/hush_test/hush-parsing/starquoted2.right 2009-02-26 12:46:52.000000000 +0100
|
||||
+++ busybox-1.13.3-hush/shell/hush_test/hush-parsing/starquoted2.right 2009-03-22 12:46:20.000000000 +0100
|
||||
@@ -1,2 +1,3 @@
|
||||
Should be printed
|
||||
Should be printed
|
||||
+Empty:
|
||||
diff -urpN busybox-1.13.3/shell/hush_test/hush-parsing/starquoted2.tests busybox-1.13.3-hush/shell/hush_test/hush-parsing/starquoted2.tests
|
||||
--- busybox-1.13.3/shell/hush_test/hush-parsing/starquoted2.tests 2009-02-26 12:46:52.000000000 +0100
|
||||
+++ busybox-1.13.3-hush/shell/hush_test/hush-parsing/starquoted2.tests 2009-03-22 12:46:20.000000000 +0100
|
||||
@@ -12,3 +12,6 @@ for a in "$@"""; do echo Should not be p
|
||||
for a in """$@"; do echo Should not be printed; done
|
||||
for a in """$@"''"$@"''; do echo Should not be printed; done
|
||||
for a in ""; do echo Should be printed; done
|
||||
+
|
||||
+# Bug 207: "$@" expands to nothing, and we erroneously glob "%s\\n" twice:
|
||||
+printf "Empty:%s\\n" "$@"
|
@ -1,12 +0,0 @@
|
||||
diff -urpN busybox-1.13.3/coreutils/tail.c busybox-1.13.3-tail/coreutils/tail.c
|
||||
--- busybox-1.13.3/coreutils/tail.c 2009-02-26 12:47:02.000000000 +0100
|
||||
+++ busybox-1.13.3-tail/coreutils/tail.c 2009-03-27 03:34:57.000000000 +0100
|
||||
@@ -104,7 +104,7 @@ int tail_main(int argc, char **argv)
|
||||
if (argv[1] && (argv[1][0] == '+' || argv[1][0] == '-')
|
||||
&& isdigit(argv[1][1])
|
||||
) {
|
||||
- count = eat_num(&argv[1][1]);
|
||||
+ count = eat_num(argv[1]);
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
diff -urpN busybox-1.13.3/archival/libunarchive/get_header_tar.c busybox-1.13.3-tar/archival/libunarchive/get_header_tar.c
|
||||
--- busybox-1.13.3/archival/libunarchive/get_header_tar.c 2009-02-26 12:46:40.000000000 +0100
|
||||
+++ busybox-1.13.3-tar/archival/libunarchive/get_header_tar.c 2009-04-01 01:15:26.000000000 +0200
|
||||
@@ -91,7 +91,7 @@ char FAST_FUNC get_header_tar(archive_ha
|
||||
|
||||
again_after_align:
|
||||
|
||||
-#if ENABLE_DESKTOP
|
||||
+#if ENABLE_DESKTOP || ENABLE_FEATURE_TAR_AUTODETECT
|
||||
/* to prevent misdetection of bz2 sig */
|
||||
*(uint32_t*)(&tar) = 0;
|
||||
i = full_read(archive_handle->src_fd, &tar, 512);
|
||||
@@ -142,7 +142,7 @@ char FAST_FUNC get_header_tar(archive_ha
|
||||
#if ENABLE_FEATURE_TAR_AUTODETECT
|
||||
char FAST_FUNC (*get_header_ptr)(archive_handle_t *);
|
||||
|
||||
- USE_DESKTOP(autodetect:)
|
||||
+ autodetect:
|
||||
/* tar gz/bz autodetect: check for gz/bz2 magic.
|
||||
* If we see the magic, and it is the very first block,
|
||||
* we can switch to get_header_tar_gz/bz2/lzma().
|
||||
diff -urpN busybox-1.13.3/archival/tar.c busybox-1.13.3-tar/archival/tar.c
|
||||
--- busybox-1.13.3/archival/tar.c 2009-02-26 12:56:00.000000000 +0100
|
||||
+++ busybox-1.13.3-tar/archival/tar.c 2009-04-01 01:15:39.000000000 +0200
|
||||
@@ -934,8 +934,10 @@ int tar_main(int argc UNUSED_PARAM, char
|
||||
tar_handle->src_fd = fileno(tar_stream);
|
||||
tar_handle->seek = seek_by_read;
|
||||
} else {
|
||||
- if (ENABLE_FEATURE_TAR_AUTODETECT && flags == O_RDONLY) {
|
||||
- get_header_ptr = get_header_tar;
|
||||
+ if (ENABLE_FEATURE_TAR_AUTODETECT
|
||||
+ && get_header_ptr == get_header_tar
|
||||
+ && flags == O_RDONLY
|
||||
+ ) {
|
||||
tar_handle->src_fd = open_zipped(tar_filename);
|
||||
if (tar_handle->src_fd < 0)
|
||||
bb_perror_msg_and_die("can't open '%s'", tar_filename);
|
@ -1,18 +0,0 @@
|
||||
diff -urpN busybox-1.13.3/util-linux/volume_id/get_devname.c busybox-1.13.3-volumeid/util-linux/volume_id/get_devname.c
|
||||
--- busybox-1.13.3/util-linux/volume_id/get_devname.c 2009-02-26 12:47:41.000000000 +0100
|
||||
+++ busybox-1.13.3-volumeid/util-linux/volume_id/get_devname.c 2009-03-31 21:46:37.000000000 +0200
|
||||
@@ -223,13 +223,11 @@ void display_uuid_cache(void)
|
||||
char *get_devname_from_label(const char *spec)
|
||||
{
|
||||
struct uuidCache_s *uc;
|
||||
- int spec_len = strlen(spec);
|
||||
|
||||
uuidcache_init();
|
||||
uc = uuidCache;
|
||||
while (uc) {
|
||||
-// FIXME: empty label ("LABEL=") matches anything??!
|
||||
- if (uc->label[0] && strncmp(spec, uc->label, spec_len) == 0) {
|
||||
+ if (uc->label[0] && strcmp(spec, uc->label) == 0) {
|
||||
return xstrdup(uc->device);
|
||||
}
|
||||
uc = uc->next;
|
Loading…
Reference in New Issue
Block a user