ash: fix "(cat < file)" hang introduced by rev 22944.
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 16 Aug 2008 11:48:02 +0000 (11:48 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 16 Aug 2008 11:48:02 +0000 (11:48 -0000)
shell/ash.c
shell/ash_test/ash-redir/redir6.right [new file with mode: 0644]
shell/ash_test/ash-redir/redir6.tests [new file with mode: 0755]

index 3a1e1d797ca1275b6f9ae02b783a9c698710daa6..d63acc2c84b5cdcd33a9a958bbacbf07ab09b6c4 100644 (file)
@@ -4905,7 +4905,11 @@ static int need_to_remember(struct redirtab *rp, int fd)
 static int is_hidden_fd(struct redirtab *rp, int fd)
 {
        int i;
-       struct parsefile *pf = g_parsefile;
+       struct parsefile *pf;
+
+       if (fd == -1)
+               return 0;
+       pf = g_parsefile;
        while (pf) {
                if (fd == pf->fd) {
                        return 1;
@@ -5048,7 +5052,7 @@ redirect(union node *redir, int flags)
  * Undo the effects of the last redirection.
  */
 static void
-popredir(int drop)
+popredir(int drop, int restore)
 {
        struct redirtab *rp;
        int i;
@@ -5066,7 +5070,7 @@ popredir(int drop)
                        continue;
                }
                if (copy != EMPTY) {
-                       if (!drop || (copy & COPYFD_RESTORE)) {
+                       if (!drop || (restore && (copy & COPYFD_RESTORE))) {
                                copy &= ~COPYFD_RESTORE;
                                /*close(fd);*/
                                copyfd(copy, fd | COPYFD_EXACT);
@@ -5094,7 +5098,7 @@ clearredir(int drop)
                g_nullredirs = 0;
                if (!redirlist)
                        break;
-               popredir(drop);
+               popredir(drop, /*restore:*/ 0);
        }
 }
 
@@ -7016,7 +7020,7 @@ shellexec(char **argv, const char *path, int idx)
        int applet_no = -1;
 #endif
 
-       clearredir(1);
+       clearredir(/*drop:*/ 1);
        envp = listvars(VEXPORT, VUNSET, 0);
        if (strchr(argv[0], '/') != NULL
 #if ENABLE_FEATURE_SH_STANDALONE
@@ -7926,7 +7930,7 @@ evaltree(union node *n, int flags)
                        evaltree(n->nredir.n, flags & EV_TESTED);
                        status = exitstatus;
                }
-               popredir(0);
+               popredir(/*drop:*/ 0, /*restore:*/ 0 /* not sure */);
                goto setstatus;
        case NCMD:
                evalfn = evalcommand;
@@ -8707,11 +8711,11 @@ evalcommand(union node *cmd, int flags)
        char *lastarg;
        const char *path;
        int spclbltin;
-       int cmd_is_exec;
        int status;
        char **nargv;
        struct builtincmd *bcmd;
-       int pseudovarflag = 0;
+       smallint cmd_is_exec;
+       smallint pseudovarflag = 0;
 
        /* First expand the arguments. */
        TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
@@ -8822,7 +8826,7 @@ evalcommand(union node *cmd, int flags)
                        if (spclbltin < 0)
                                spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
                        if (cmdentry.u.cmd == EXECCMD)
-                               cmd_is_exec++;
+                               cmd_is_exec = 1;
 #if ENABLE_ASH_CMDCMD
                        if (cmdentry.u.cmd == COMMANDCMD) {
                                path = oldpath;
@@ -8917,7 +8921,7 @@ evalcommand(union node *cmd, int flags)
        }
 
  out:
-       popredir(cmd_is_exec);
+       popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec);
        if (lastarg) {
                /* dsl: I think this is intended to be used to support
                 * '_' in 'vi' command mode during line editing...
@@ -13485,7 +13489,7 @@ reset(void)
        tokpushback = 0;
        checkkwd = 0;
        /* from redir.c: */
-       clearredir(0);
+       clearredir(/*drop:*/ 0);
 }
 
 #if PROFILE
diff --git a/shell/ash_test/ash-redir/redir6.right b/shell/ash_test/ash-redir/redir6.right
new file mode 100644 (file)
index 0000000..ed754df
--- /dev/null
@@ -0,0 +1,2 @@
+Hello
+OK
diff --git a/shell/ash_test/ash-redir/redir6.tests b/shell/ash_test/ash-redir/redir6.tests
new file mode 100755 (executable)
index 0000000..33b6d4c
--- /dev/null
@@ -0,0 +1,3 @@
+# we had a bug where this would hang
+(head -n 1 <redir6.right)
+echo OK