bin/158206: sh(1) doesn't properly return IO errors to
conditionals in a script
Jilles Tjoelker
jilles at stack.nl
Sun Jun 26 10:50:09 UTC 2011
The following reply was made to PR bin/158206; it has been noted by GNATS.
From: Jilles Tjoelker <jilles at stack.nl>
To: bug-followup at FreeBSD.org, culrich at csnstores.com
Cc:
Subject: Re: bin/158206: sh(1) doesn't properly return IO errors to
conditionals in a script
Date: Sun, 26 Jun 2011 12:41:00 +0200
Thank you for your bug report.
The below patch should fix the problem. It applies to 9-current only. It
could be changed to apply to 8-stable but I will not commit this change
to 8-stable anyway. It is even a bit late for 9.x, one week into code
slush.
commit 22f46c6d493531fc8df124675598edbfb9eb8130
Author: Jilles Tjoelker <jilles at stack.nl>
Date: Sun Jun 26 12:25:07 2011 +0200
sh: Detect and flag write errors on stdout in builtins.
PR: bin/158206
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index d5da7d3..8330094 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -1000,6 +1000,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
}
handler = &jmploc;
redirect(cmd->ncmd.redirect, mode);
+ outclearerror(out1);
/*
* If there is no command word, redirection errors should
* not be fatal but assignment errors should.
@@ -1015,6 +1016,11 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
builtin_flags = flags;
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
flushall();
+ if (outiserror(out1)) {
+ warning("write error on stdout");
+ if (exitstatus == 0 || exitstatus == 1)
+ exitstatus = 2;
+ }
cmddone:
if (argc > 0)
bltinunsetlocale();
diff --git a/bin/sh/output.c b/bin/sh/output.c
index b4dab51..d26adce 100644
--- a/bin/sh/output.c
+++ b/bin/sh/output.c
@@ -239,6 +239,20 @@ freestdout(void)
}
+int
+outiserror(struct output *file)
+{
+ return (file->flags & OUTPUT_ERR);
+}
+
+
+void
+outclearerror(struct output *file)
+{
+ file->flags &= ~OUTPUT_ERR;
+}
+
+
void
outfmt(struct output *file, const char *fmt, ...)
{
diff --git a/bin/sh/output.h b/bin/sh/output.h
index 5e3b048..51974d8 100644
--- a/bin/sh/output.h
+++ b/bin/sh/output.h
@@ -66,6 +66,8 @@ void emptyoutbuf(struct output *);
void flushall(void);
void flushout(struct output *);
void freestdout(void);
+int outiserror(struct output *);
+void outclearerror(struct output *);
void outfmt(struct output *, const char *, ...) __printflike(2, 3);
void out1fmt(const char *, ...) __printflike(1, 2);
void out2fmt_flush(const char *, ...) __printflike(1, 2);
diff --git a/tools/regression/bin/sh/errors/write-error1.0 b/tools/regression/bin/sh/errors/write-error1.0
new file mode 100644
index 0000000..fcb52e7
--- /dev/null
+++ b/tools/regression/bin/sh/errors/write-error1.0
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+! echo >&- 2>/dev/null
--
Jilles Tjoelker
More information about the freebsd-bugs
mailing list