aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c44
-rw-r--r--shell/ash_test/ash-redir/redirA.right2
-rwxr-xr-xshell/ash_test/ash-redir/redirA.tests11
-rw-r--r--shell/shell_common.c5
-rw-r--r--shell/shell_common.h2
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 @@
1tmp11
2tmp11
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 @@
1x="tmp11:tmp22"
2
3# Bug was incorrectly expanding variables in >redir
4echo "${x%:*}" >"${x%:*}"
5echo tmp1*
6rm tmp1*
7
8# Also try unquoted
9echo "${x%:*}" >${x%:*}
10echo tmp1*
11rm 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
22const char defifsvar[] ALIGN1 = "IFS= \t\n"; 25const 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
22PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 22PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
23 23
24extern const char defifsvar[]; /* "IFS= \t\n" */ 24extern const char defifsvar[] ALIGN1; /* "IFS= \t\n" */
25#define defifs (defifsvar + 4) 25#define defifs (defifsvar + 4)
26 26
27int FAST_FUNC is_well_formed_var_name(const char *s, char terminator); 27int FAST_FUNC is_well_formed_var_name(const char *s, char terminator);