about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/builtin.c10
-rw-r--r--Src/exec.c22
2 files changed, 23 insertions, 9 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index a85a49a20..aa87dfb7d 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4821,8 +4821,14 @@ bin_dot(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	freearray(pparams);
 	pparams = old;
     }
-    if (ret == SOURCE_NOT_FOUND)
-	zwarnnam(name, "%e: %s", errno, enam);
+    if (ret == SOURCE_NOT_FOUND) {
+	if (isset(POSIXBUILTINS)) {
+	    /* hard error in POSIX (we'll exit later) */
+	    zerrnam(name, "%e: %s", errno, enam);
+	} else {
+	    zwarnnam(name, "%e: %s", errno, enam);
+	}
+    }
     zsfree(arg0);
     if (old0) {
 	zsfree(argzero);
diff --git a/Src/exec.c b/Src/exec.c
index da67465d8..25a2eee38 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2416,6 +2416,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		checked = !(cflags & BINF_BUILTIN);
 		break;
 	    }
+	    cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
+	    cflags |= hn->flags;
 	    if (!(hn->flags & BINF_PREFIX)) {
 		is_builtin = 1;
 
@@ -2425,8 +2427,6 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		assign = (hn->flags & BINF_MAGICEQUALS);
 		break;
 	    }
-	    cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
-	    cflags |= hn->flags;
 	    checked = 0;
 	    if ((cflags & BINF_COMMAND) && nextnode(firstnode(args))) {
 		/* check for options to command builtin */
@@ -3297,12 +3297,20 @@ execcmd(Estate state, int input, int output, int how, int last1)
     fixfds(save);
 
  done:
-    if (redir_err && isset(POSIXBUILTINS)) {
-	if (!isset(INTERACTIVE)) {
-	    /* We've already _exit'ed if forked */
-	    exit(1);
+    if (isset(POSIXBUILTINS) &&
+	(cflags & (BINF_PSPECIAL|BINF_EXEC))) {
+	/*
+	 * For POSIX-compatibile behaviour with special
+	 * builtins (including exec which we don't usually
+	 * classify as a builtin, we treat all errors as fatal.
+	 */
+	if (redir_err || errflag) {
+	    if (!isset(INTERACTIVE)) {
+		/* We've already _exit'ed if forked */
+		exit(1);
+	    }
+	    errflag = 1;
 	}
-	errflag = 1;
     }
     if (newxtrerr) {
 	fil = fileno(newxtrerr);