aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hush.c30
-rw-r--r--shell/hush.c30
-rw-r--r--tests/sh.testcases29
3 files changed, 61 insertions, 28 deletions
diff --git a/hush.c b/hush.c
index 126f9da89..3b1e53c82 100644
--- a/hush.c
+++ b/hush.c
@@ -1326,19 +1326,18 @@ static int run_pipe_real(struct pipe *pi)
1326 * Builtins within pipes have to fork anyway, and are handled in 1326 * Builtins within pipes have to fork anyway, and are handled in
1327 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. 1327 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either.
1328 */ 1328 */
1329 if (pi->num_progs == 1 && pi->progs[0].argv != NULL) { 1329 if (pi->num_progs == 1) child = & (pi->progs[0]);
1330 child = & (pi->progs[0]); 1330 if (pi->num_progs == 1 && child->group && child->subshell == 0) {
1331 if (child->group && ! child->subshell) { 1331 int squirrel[] = {-1, -1, -1};
1332 int squirrel[] = {-1, -1, -1}; 1332 int rcode;
1333 int rcode; 1333 debug_printf("non-subshell grouping\n");
1334 debug_printf("non-subshell grouping\n"); 1334 setup_redirects(child, squirrel);
1335 setup_redirects(child, squirrel); 1335 /* XXX could we merge code with following builtin case,
1336 /* XXX could we merge code with following builtin case, 1336 * by creating a pseudo builtin that calls run_list_real? */
1337 * by creating a pseudo builtin that calls run_list_real? */ 1337 rcode = run_list_real(child->group);
1338 rcode = run_list_real(child->group); 1338 restore_redirects(squirrel);
1339 restore_redirects(squirrel); 1339 return rcode;
1340 return rcode; 1340 } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
1341 }
1342 for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ } 1341 for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ }
1343 if (i!=0 && child->argv[i]==NULL) { 1342 if (i!=0 && child->argv[i]==NULL) {
1344 /* assignments, but no command: set the local environment */ 1343 /* assignments, but no command: set the local environment */
@@ -1352,7 +1351,8 @@ static int run_pipe_real(struct pipe *pi)
1352 * variable. */ 1351 * variable. */
1353 int export_me=0; 1352 int export_me=0;
1354 char *name, *value; 1353 char *name, *value;
1355 name = strdup(child->argv[i]); 1354 name = xstrdup(child->argv[i]);
1355 debug_printf("Local environment set: %s\n", name);
1356 value = strchr(name, '='); 1356 value = strchr(name, '=');
1357 if (value) 1357 if (value)
1358 *value=0; 1358 *value=0;
@@ -1478,6 +1478,7 @@ static int run_list_real(struct pipe *pi)
1478 if (rmode == RES_ELIF && !if_code) continue; 1478 if (rmode == RES_ELIF && !if_code) continue;
1479 if (pi->num_progs == 0) continue; 1479 if (pi->num_progs == 0) continue;
1480 rcode = run_pipe_real(pi); 1480 rcode = run_pipe_real(pi);
1481 debug_printf("run_pipe_real returned %d\n",rcode);
1481 if (rcode!=-1) { 1482 if (rcode!=-1) {
1482 /* We only ran a builtin: rcode was set by the return value 1483 /* We only ran a builtin: rcode was set by the return value
1483 * of run_pipe_real(), and we don't need to wait for anything. */ 1484 * of run_pipe_real(), and we don't need to wait for anything. */
@@ -1943,6 +1944,7 @@ int reserved_word(o_string *dest, struct p_context *ctx)
1943 debug_printf("pop stack\n"); 1944 debug_printf("pop stack\n");
1944 old = ctx->stack; 1945 old = ctx->stack;
1945 old->child->group = ctx->list_head; 1946 old->child->group = ctx->list_head;
1947 old->child->subshell = 0;
1946 *ctx = *old; /* physical copy */ 1948 *ctx = *old; /* physical copy */
1947 free(old); 1949 free(old);
1948 } 1950 }
diff --git a/shell/hush.c b/shell/hush.c
index 126f9da89..3b1e53c82 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1326,19 +1326,18 @@ static int run_pipe_real(struct pipe *pi)
1326 * Builtins within pipes have to fork anyway, and are handled in 1326 * Builtins within pipes have to fork anyway, and are handled in
1327 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. 1327 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either.
1328 */ 1328 */
1329 if (pi->num_progs == 1 && pi->progs[0].argv != NULL) { 1329 if (pi->num_progs == 1) child = & (pi->progs[0]);
1330 child = & (pi->progs[0]); 1330 if (pi->num_progs == 1 && child->group && child->subshell == 0) {
1331 if (child->group && ! child->subshell) { 1331 int squirrel[] = {-1, -1, -1};
1332 int squirrel[] = {-1, -1, -1}; 1332 int rcode;
1333 int rcode; 1333 debug_printf("non-subshell grouping\n");
1334 debug_printf("non-subshell grouping\n"); 1334 setup_redirects(child, squirrel);
1335 setup_redirects(child, squirrel); 1335 /* XXX could we merge code with following builtin case,
1336 /* XXX could we merge code with following builtin case, 1336 * by creating a pseudo builtin that calls run_list_real? */
1337 * by creating a pseudo builtin that calls run_list_real? */ 1337 rcode = run_list_real(child->group);
1338 rcode = run_list_real(child->group); 1338 restore_redirects(squirrel);
1339 restore_redirects(squirrel); 1339 return rcode;
1340 return rcode; 1340 } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
1341 }
1342 for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ } 1341 for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ }
1343 if (i!=0 && child->argv[i]==NULL) { 1342 if (i!=0 && child->argv[i]==NULL) {
1344 /* assignments, but no command: set the local environment */ 1343 /* assignments, but no command: set the local environment */
@@ -1352,7 +1351,8 @@ static int run_pipe_real(struct pipe *pi)
1352 * variable. */ 1351 * variable. */
1353 int export_me=0; 1352 int export_me=0;
1354 char *name, *value; 1353 char *name, *value;
1355 name = strdup(child->argv[i]); 1354 name = xstrdup(child->argv[i]);
1355 debug_printf("Local environment set: %s\n", name);
1356 value = strchr(name, '='); 1356 value = strchr(name, '=');
1357 if (value) 1357 if (value)
1358 *value=0; 1358 *value=0;
@@ -1478,6 +1478,7 @@ static int run_list_real(struct pipe *pi)
1478 if (rmode == RES_ELIF && !if_code) continue; 1478 if (rmode == RES_ELIF && !if_code) continue;
1479 if (pi->num_progs == 0) continue; 1479 if (pi->num_progs == 0) continue;
1480 rcode = run_pipe_real(pi); 1480 rcode = run_pipe_real(pi);
1481 debug_printf("run_pipe_real returned %d\n",rcode);
1481 if (rcode!=-1) { 1482 if (rcode!=-1) {
1482 /* We only ran a builtin: rcode was set by the return value 1483 /* We only ran a builtin: rcode was set by the return value
1483 * of run_pipe_real(), and we don't need to wait for anything. */ 1484 * of run_pipe_real(), and we don't need to wait for anything. */
@@ -1943,6 +1944,7 @@ int reserved_word(o_string *dest, struct p_context *ctx)
1943 debug_printf("pop stack\n"); 1944 debug_printf("pop stack\n");
1944 old = ctx->stack; 1945 old = ctx->stack;
1945 old->child->group = ctx->list_head; 1946 old->child->group = ctx->list_head;
1947 old->child->subshell = 0;
1946 *ctx = *old; /* physical copy */ 1948 *ctx = *old; /* physical copy */
1947 free(old); 1949 free(old);
1948 } 1950 }
diff --git a/tests/sh.testcases b/tests/sh.testcases
index 88e709f87..e2a75873e 100644
--- a/tests/sh.testcases
+++ b/tests/sh.testcases
@@ -28,6 +28,35 @@ if false; then tr 'A-Z' 'a-z'; else echo bar4; fi <foo
28if true || false; then echo foo; else echo bar5; fi 28if true || false; then echo foo; else echo bar5; fi
29if true && false; then echo bar6; else echo foo; fi 29if true && false; then echo bar6; else echo foo; fi
30 30
31# basic distinction between local and env variables
32unset FOO
33FOO=bar env | grep FOO
34echo "but not here: $FOO"
35FOO=bar
36env | grep FOO
37echo "yes, here: $FOO"
38FOO=
39echo a $FOO b
40echo "a $FOO b"
41
42# not quite so basic variables. Credit to Matt Kraai.
43unset FOO
44FOO=bar
45export FOO
46env | grep FOO
47unset FOO
48export FOO=bar
49FOO=baz
50env | grep FOO
51
52# interaction between environment variables and if/then and subshells
53FOO=default
54if true; then FOO=new; fi
55echo $FOO
56FOO=default
57(FOO=bogus)
58echo $FOO
59
31# make sure we can duplicate file descriptors properly 60# make sure we can duplicate file descriptors properly
32echo replacement >foo 2>&1 61echo replacement >foo 2>&1
33cat foo 62cat foo