hush: fix a bug in argv restoration after sourcing a file
[oweals/busybox.git] / shell / ash.c
index 430e42a7bfc3eac3cb63b6fe1fa0988e373db336..efb4615db10cbf31ff80371089b5277776535411 100644 (file)
 //config:        shell (by Herbert Xu), which was created by porting the 'ash' shell
 //config:        (written by Kenneth Almquist) from NetBSD.
 //config:
+//config:# ash options
+//config:# note: Don't remove !NOMMU part in the next line; it would break
+//config:# menuconfig's indenting.
+//config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH)
+//config:
 //config:config ASH_OPTIMIZE_FOR_SIZE
 //config:      bool "Optimize for size instead of speed"
 //config:      default y
 //config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable "check for new mail" function in the ash shell.
+//config:
+//config:endif # ash options
 
 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
 //applet:IF_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
@@ -1284,6 +1291,8 @@ ash_msg_and_raise_error(const char *msg, ...)
 {
        va_list ap;
 
+       exitstatus = 2;
+
        va_start(ap, msg);
        ash_vmsg_and_raise(EXERROR, msg, ap);
        /* NOTREACHED */
@@ -5424,11 +5433,11 @@ redirect(union node *redir, int flags)
                        /* Careful to not accidentally "save"
                         * to the same fd as right side fd in N>&M */
                        int minfd = right_fd < 10 ? 10 : right_fd + 1;
+#if defined(F_DUPFD_CLOEXEC)
+                       i = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
+#else
                        i = fcntl(fd, F_DUPFD, minfd);
-/* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds
- * are closed in popredir() in the child, preventing them from leaking
- * into child. (popredir() also cleans up the mess in case of failures)
- */
+#endif
                        if (i == -1) {
                                i = errno;
                                if (i != EBADF) {
@@ -5443,6 +5452,9 @@ redirect(union node *redir, int flags)
  remember_to_close:
                                i = CLOSED;
                        } else { /* fd is open, save its copy */
+#if !defined(F_DUPFD_CLOEXEC)
+                               fcntl(i, F_SETFD, FD_CLOEXEC);
+#endif
                                /* "exec fd>&-" should not close fds
                                 * which point to script file(s).
                                 * Force them to be restored afterwards */
@@ -9588,11 +9600,13 @@ evalcommand(union node *cmd, int flags)
        }
 
        if (status) {
+ bail:
+               exitstatus = status;
+
                /* We have a redirection error. */
                if (spclbltin > 0)
                        raise_exception(EXERROR);
- bail:
-               exitstatus = status;
+
                goto out;
        }