hush: fix $ expansion in redirections, add testcase for that
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 23 Nov 2007 21:08:38 +0000 (21:08 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 23 Nov 2007 21:08:38 +0000 (21:08 -0000)
shell/README
shell/hush.c
shell/hush_test/hush-vars/var_expand_in_redir.right [new file with mode: 0644]
shell/hush_test/hush-vars/var_expand_in_redir.tests [new file with mode: 0755]
shell/hush_test/run-all

index b86f96cf4dc6d80ae5b23f87e72641803793d9f0..f78ed9d18bf0602f734682ac8f6f6c41c3c5cd26 100644 (file)
@@ -1,5 +1,8 @@
 Various bits of what is known about busybox shells, in no particular order.
 
+2007-11-23
+hush: fixed bogus glob handling; fixed exec <"$1"; added test and echo builtins
+
 2007-06-13
 hush: exec <"$1" doesn't do parameter subst
 
index 04afbfd9a248cb86dac8bd1139e99155661c15dd..912cbb5d9c3bd5c464f2a7ebeca272bcfad6707a 100644 (file)
@@ -1361,8 +1361,11 @@ static int setup_redirects(struct child_prog *prog, int squirrel[])
                        continue;
                }
                if (redir->dup == -1) {
+                       char *p;
                        mode = redir_table[redir->type].mode;
-                       openfd = open_or_warn(redir->glob_word[0], mode);
+                       p = expand_string_to_string(redir->glob_word[0]);
+                       openfd = open_or_warn(p, mode);
+                       free(p);
                        if (openfd < 0) {
                        /* this could get lost if stderr has been redirected, but
                           bash and ash both lose it as well (though zsh doesn't!) */
@@ -2579,7 +2582,7 @@ static int expand_vars_to_list(char **list, int n, char **posp, char *arg, char
                                }
                        } else
                        /* If or_mask is nonzero, we handle assignment 'a=....$@.....'
-                        * and in this case should theat it like '$*' */
+                        * and in this case should treat it like '$*' - see 'else...' below */
                        if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
                                while (1) {
                                        strcpy(pos, global_argv[i]);
@@ -2593,10 +2596,10 @@ static int expand_vars_to_list(char **list, int n, char **posp, char *arg, char
                                        list[n++] = pos;
                                }
                        } else { /* quoted $*: add as one word */
-                               while (1) {
+                               if (global_argv[i]) while (1) {
                                        strcpy(pos, global_argv[i]);
                                        pos += strlen(global_argv[i]);
-                                       if (++i >= global_argc)
+                                       if (!global_argv[++i])
                                                break;
                                        if (ifs[0])
                                                *pos++ = ifs[0];
diff --git a/shell/hush_test/hush-vars/var_expand_in_redir.right b/shell/hush_test/hush-vars/var_expand_in_redir.right
new file mode 100644 (file)
index 0000000..423299c
--- /dev/null
@@ -0,0 +1,3 @@
+TEST1
+TEST2
+TEST3
diff --git a/shell/hush_test/hush-vars/var_expand_in_redir.tests b/shell/hush_test/hush-vars/var_expand_in_redir.tests
new file mode 100755 (executable)
index 0000000..bda6bdd
--- /dev/null
@@ -0,0 +1,13 @@
+if test $# = 0; then
+    exec "$THIS_SH" "$0" abc "d e"
+fi
+
+echo TEST1 >"$1.out"
+echo TEST2 >"$2.out"
+# bash says: "$@.out": ambiguous redirect
+# ash handles it as if it is '$*' - we do the same
+echo TEST3 >"$@.out"
+
+cat abc.out "d e.out" "abc d e.out"
+
+rm abc.out "d e.out" "abc d e.out"
index 0d40ae6dfe9cf5434f4da233842532dff2086e99..c75d81e55b7ed792ae6c5c9972034f8e5f96ff17 100755 (executable)
@@ -11,6 +11,7 @@ export THIS_SH
 do_test()
 {
     test -d "$1" || return 0
+#   echo Running tests in directory "$1"
     (
     cd "$1" || { echo "cannot cd $1!"; exit 1; }
     for x in run-*; do