diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 44 | ||||
-rw-r--r-- | shell/ash_test/ash-redir/redirA.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-redir/redirA.tests | 11 | ||||
-rw-r--r-- | shell/shell_common.c | 5 | ||||
-rw-r--r-- | shell/shell_common.h | 2 |
5 files changed, 46 insertions, 18 deletions
diff --git a/shell/ash.c b/shell/ash.c index f7c12f8e1..46bf6ed49 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -37,8 +37,9 @@ | |||
37 | * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) | 37 | * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) |
38 | * define DEBUG=2 to compile in and turn on debugging. | 38 | * define DEBUG=2 to compile in and turn on debugging. |
39 | * | 39 | * |
40 | * When debugging is on, debugging info will be written to ./trace and | 40 | * When debugging is on (DEBUG is 1 and "set -o debug" was executed), |
41 | * a quit signal will generate a core dump. | 41 | * debugging info will be written to ./trace and a quit signal |
42 | * will generate a core dump. | ||
42 | */ | 43 | */ |
43 | #define DEBUG 0 | 44 | #define DEBUG 0 |
44 | /* Tweak debug output verbosity here */ | 45 | /* Tweak debug output verbosity here */ |
@@ -1955,6 +1956,10 @@ static const struct { | |||
1955 | const char *var_text; | 1956 | const char *var_text; |
1956 | void (*var_func)(const char *) FAST_FUNC; | 1957 | void (*var_func)(const char *) FAST_FUNC; |
1957 | } varinit_data[] = { | 1958 | } varinit_data[] = { |
1959 | /* | ||
1960 | * Note: VEXPORT would not work correctly here for NOFORK applets: | ||
1961 | * some environment strings may be constant. | ||
1962 | */ | ||
1958 | { VSTRFIXED|VTEXTFIXED , defifsvar , NULL }, | 1963 | { VSTRFIXED|VTEXTFIXED , defifsvar , NULL }, |
1959 | #if ENABLE_ASH_MAIL | 1964 | #if ENABLE_ASH_MAIL |
1960 | { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL" , changemail }, | 1965 | { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL" , changemail }, |
@@ -5401,14 +5406,15 @@ openredirect(union node *redir) | |||
5401 | char *fname; | 5406 | char *fname; |
5402 | int f; | 5407 | int f; |
5403 | 5408 | ||
5409 | fname = redir->nfile.expfname; | ||
5404 | #if ENABLE_PLATFORM_MINGW32 | 5410 | #if ENABLE_PLATFORM_MINGW32 |
5405 | /* Support for /dev/null */ | 5411 | /* Support for /dev/null */ |
5406 | switch (redir->nfile.type) { | 5412 | switch (redir->nfile.type) { |
5407 | case NFROM: | 5413 | case NFROM: |
5408 | if (!strcmp(redir->nfile.expfname, "/dev/null")) | 5414 | if (!strcmp(fname, "/dev/null")) |
5409 | return open("nul",O_RDWR); | 5415 | return open("nul",O_RDWR); |
5410 | if (!strncmp(redir->nfile.expfname, "/dev/", 5)) { | 5416 | if (!strncmp(fname, "/dev/", 5)) { |
5411 | ash_msg("Unhandled device %s\n", redir->nfile.expfname); | 5417 | ash_msg("Unhandled device %s\n", fname); |
5412 | return -1; | 5418 | return -1; |
5413 | } | 5419 | } |
5414 | break; | 5420 | break; |
@@ -5417,10 +5423,10 @@ openredirect(union node *redir) | |||
5417 | case NTO: | 5423 | case NTO: |
5418 | case NCLOBBER: | 5424 | case NCLOBBER: |
5419 | case NAPPEND: | 5425 | case NAPPEND: |
5420 | if (!strcmp(redir->nfile.expfname, "/dev/null")) | 5426 | if (!strcmp(fname, "/dev/null")) |
5421 | return open("nul",O_RDWR); | 5427 | return open("nul",O_RDWR); |
5422 | if (!strncmp(redir->nfile.expfname, "/dev/", 5)) { | 5428 | if (!strncmp(fname, "/dev/", 5)) { |
5423 | ash_msg("Unhandled device %s\n", redir->nfile.expfname); | 5429 | ash_msg("Unhandled device %s\n", fname); |
5424 | return -1; | 5430 | return -1; |
5425 | } | 5431 | } |
5426 | break; | 5432 | break; |
@@ -5428,13 +5434,11 @@ openredirect(union node *redir) | |||
5428 | #endif | 5434 | #endif |
5429 | switch (redir->nfile.type) { | 5435 | switch (redir->nfile.type) { |
5430 | case NFROM: | 5436 | case NFROM: |
5431 | fname = redir->nfile.expfname; | ||
5432 | f = open(fname, O_RDONLY); | 5437 | f = open(fname, O_RDONLY); |
5433 | if (f < 0) | 5438 | if (f < 0) |
5434 | goto eopen; | 5439 | goto eopen; |
5435 | break; | 5440 | break; |
5436 | case NFROMTO: | 5441 | case NFROMTO: |
5437 | fname = redir->nfile.expfname; | ||
5438 | f = open(fname, O_RDWR|O_CREAT, 0666); | 5442 | f = open(fname, O_RDWR|O_CREAT, 0666); |
5439 | if (f < 0) | 5443 | if (f < 0) |
5440 | goto ecreate; | 5444 | goto ecreate; |
@@ -5445,7 +5449,6 @@ openredirect(union node *redir) | |||
5445 | #endif | 5449 | #endif |
5446 | /* Take care of noclobber mode. */ | 5450 | /* Take care of noclobber mode. */ |
5447 | if (Cflag) { | 5451 | if (Cflag) { |
5448 | fname = redir->nfile.expfname; | ||
5449 | f = noclobberopen(fname); | 5452 | f = noclobberopen(fname); |
5450 | if (f < 0) | 5453 | if (f < 0) |
5451 | goto ecreate; | 5454 | goto ecreate; |
@@ -5453,13 +5456,11 @@ openredirect(union node *redir) | |||
5453 | } | 5456 | } |
5454 | /* FALLTHROUGH */ | 5457 | /* FALLTHROUGH */ |
5455 | case NCLOBBER: | 5458 | case NCLOBBER: |
5456 | fname = redir->nfile.expfname; | ||
5457 | f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); | 5459 | f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); |
5458 | if (f < 0) | 5460 | if (f < 0) |
5459 | goto ecreate; | 5461 | goto ecreate; |
5460 | break; | 5462 | break; |
5461 | case NAPPEND: | 5463 | case NAPPEND: |
5462 | fname = redir->nfile.expfname; | ||
5463 | f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666); | 5464 | f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666); |
5464 | if (f < 0) | 5465 | if (f < 0) |
5465 | goto ecreate; | 5466 | goto ecreate; |
@@ -6491,7 +6492,9 @@ argstr(char *p, int flags, struct strlist *var_str_list) | |||
6491 | length++; | 6492 | length++; |
6492 | goto addquote; | 6493 | goto addquote; |
6493 | case CTLVAR: | 6494 | case CTLVAR: |
6495 | TRACE(("argstr: evalvar('%s')\n", p)); | ||
6494 | p = evalvar(p, flags, var_str_list); | 6496 | p = evalvar(p, flags, var_str_list); |
6497 | TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock())); | ||
6495 | goto start; | 6498 | goto start; |
6496 | case CTLBACKQ: | 6499 | case CTLBACKQ: |
6497 | c = '\0'; | 6500 | c = '\0'; |
@@ -7199,8 +7202,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
7199 | patloc = expdest - (char *)stackblock(); | 7202 | patloc = expdest - (char *)stackblock(); |
7200 | if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, | 7203 | if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, |
7201 | startloc, varflags, | 7204 | startloc, varflags, |
7202 | //TODO: | EXP_REDIR too? All other such places do it too | 7205 | /* quotes: */ flags & (EXP_FULL | EXP_CASE | EXP_REDIR), |
7203 | /* quotes: */ flags & (EXP_FULL | EXP_CASE), | ||
7204 | var_str_list) | 7206 | var_str_list) |
7205 | ) { | 7207 | ) { |
7206 | int amount = expdest - ( | 7208 | int amount = expdest - ( |
@@ -7602,6 +7604,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
7602 | STARTSTACKSTR(expdest); | 7604 | STARTSTACKSTR(expdest); |
7603 | ifsfirst.next = NULL; | 7605 | ifsfirst.next = NULL; |
7604 | ifslastp = NULL; | 7606 | ifslastp = NULL; |
7607 | TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag)); | ||
7605 | argstr(arg->narg.text, flag, | 7608 | argstr(arg->narg.text, flag, |
7606 | /* var_str_list: */ arglist ? arglist->list : NULL); | 7609 | /* var_str_list: */ arglist ? arglist->list : NULL); |
7607 | p = _STPUTC('\0', expdest); | 7610 | p = _STPUTC('\0', expdest); |
@@ -7610,6 +7613,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
7610 | return; /* here document expanded */ | 7613 | return; /* here document expanded */ |
7611 | } | 7614 | } |
7612 | p = grabstackstr(p); | 7615 | p = grabstackstr(p); |
7616 | TRACE(("expandarg: p:'%s'\n", p)); | ||
7613 | exparg.lastp = &exparg.list; | 7617 | exparg.lastp = &exparg.list; |
7614 | /* | 7618 | /* |
7615 | * TODO - EXP_REDIR | 7619 | * TODO - EXP_REDIR |
@@ -7620,8 +7624,10 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
7620 | exparg.lastp = &exparg.list; | 7624 | exparg.lastp = &exparg.list; |
7621 | expandmeta(exparg.list /*, flag*/); | 7625 | expandmeta(exparg.list /*, flag*/); |
7622 | } else { | 7626 | } else { |
7623 | if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ | 7627 | if (flag & EXP_REDIR) { /*XXX - for now, just remove escapes */ |
7624 | rmescapes(p, 0); | 7628 | rmescapes(p, 0); |
7629 | TRACE(("expandarg: rmescapes:'%s'\n", p)); | ||
7630 | } | ||
7625 | sp = stzalloc(sizeof(*sp)); | 7631 | sp = stzalloc(sizeof(*sp)); |
7626 | sp->text = p; | 7632 | sp->text = p; |
7627 | *exparg.lastp = sp; | 7633 | *exparg.lastp = sp; |
@@ -9090,6 +9096,7 @@ expredir(union node *n) | |||
9090 | case NCLOBBER: | 9096 | case NCLOBBER: |
9091 | case NAPPEND: | 9097 | case NAPPEND: |
9092 | expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); | 9098 | expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); |
9099 | TRACE(("expredir expanded to '%s'\n", fn.list->text)); | ||
9093 | #if ENABLE_ASH_BASH_COMPAT | 9100 | #if ENABLE_ASH_BASH_COMPAT |
9094 | store_expfname: | 9101 | store_expfname: |
9095 | #endif | 9102 | #endif |
@@ -13343,6 +13350,10 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13343 | } | 13350 | } |
13344 | } | 13351 | } |
13345 | 13352 | ||
13353 | /* "read -s" needs to save/restore termios, can't allow ^C | ||
13354 | * to jump out of it. | ||
13355 | */ | ||
13356 | INT_OFF; | ||
13346 | r = shell_builtin_read(setvar2, | 13357 | r = shell_builtin_read(setvar2, |
13347 | argptr, | 13358 | argptr, |
13348 | bltinlookup("IFS"), /* can be NULL */ | 13359 | bltinlookup("IFS"), /* can be NULL */ |
@@ -13352,6 +13363,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13352 | opt_t, | 13363 | opt_t, |
13353 | opt_u | 13364 | opt_u |
13354 | ); | 13365 | ); |
13366 | INT_ON; | ||
13355 | 13367 | ||
13356 | if ((uintptr_t)r > 1) | 13368 | if ((uintptr_t)r > 1) |
13357 | ash_msg_and_raise_error(r); | 13369 | ash_msg_and_raise_error(r); |
diff --git a/shell/ash_test/ash-redir/redirA.right b/shell/ash_test/ash-redir/redirA.right new file mode 100644 index 000000000..31406e336 --- /dev/null +++ b/shell/ash_test/ash-redir/redirA.right | |||
@@ -0,0 +1,2 @@ | |||
1 | tmp11 | ||
2 | tmp11 | ||
diff --git a/shell/ash_test/ash-redir/redirA.tests b/shell/ash_test/ash-redir/redirA.tests new file mode 100755 index 000000000..56833f938 --- /dev/null +++ b/shell/ash_test/ash-redir/redirA.tests | |||
@@ -0,0 +1,11 @@ | |||
1 | x="tmp11:tmp22" | ||
2 | |||
3 | # Bug was incorrectly expanding variables in >redir | ||
4 | echo "${x%:*}" >"${x%:*}" | ||
5 | echo tmp1* | ||
6 | rm tmp1* | ||
7 | |||
8 | # Also try unquoted | ||
9 | echo "${x%:*}" >${x%:*} | ||
10 | echo tmp1* | ||
11 | rm tmp1* | ||
diff --git a/shell/shell_common.c b/shell/shell_common.c index 0ffe21e0b..f7503cac5 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
@@ -18,6 +18,9 @@ | |||
18 | */ | 18 | */ |
19 | #include "libbb.h" | 19 | #include "libbb.h" |
20 | #include "shell_common.h" | 20 | #include "shell_common.h" |
21 | #if !ENABLE_PLATFORM_MINGW32 | ||
22 | #include <sys/resource.h> /* getrlimit */ | ||
23 | #endif | ||
21 | 24 | ||
22 | const char defifsvar[] ALIGN1 = "IFS= \t\n"; | 25 | const char defifsvar[] ALIGN1 = "IFS= \t\n"; |
23 | 26 | ||
@@ -169,7 +172,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), | |||
169 | int timeout; | 172 | int timeout; |
170 | 173 | ||
171 | if ((bufpos & 0xff) == 0) | 174 | if ((bufpos & 0xff) == 0) |
172 | buffer = xrealloc(buffer, bufpos + 0x100); | 175 | buffer = xrealloc(buffer, bufpos + 0x101); |
173 | 176 | ||
174 | timeout = -1; | 177 | timeout = -1; |
175 | if (end_ms) { | 178 | if (end_ms) { |
diff --git a/shell/shell_common.h b/shell/shell_common.h index f06bc4120..993ed5951 100644 --- a/shell/shell_common.h +++ b/shell/shell_common.h | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | 22 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN |
23 | 23 | ||
24 | extern const char defifsvar[]; /* "IFS= \t\n" */ | 24 | extern const char defifsvar[] ALIGN1; /* "IFS= \t\n" */ |
25 | #define defifs (defifsvar + 4) | 25 | #define defifs (defifsvar + 4) |
26 | 26 | ||
27 | int FAST_FUNC is_well_formed_var_name(const char *s, char terminator); | 27 | int FAST_FUNC is_well_formed_var_name(const char *s, char terminator); |