diff options
author | jilles <jilles@FreeBSD.org> | 2012-12-12 22:01:10 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2012-12-12 22:01:10 +0000 |
commit | e5dd01ef24d5055696b9f61ddc0ad5e9dd3e6884 (patch) | |
tree | 62b574be073036de48cb7bc28e7e4aa2b57e010d | |
parent | bde43ee183f5f6d6eeb4949510346a87bf3cb414 (diff) | |
download | FreeBSD-src-e5dd01ef24d5055696b9f61ddc0ad5e9dd3e6884.zip FreeBSD-src-e5dd01ef24d5055696b9f61ddc0ad5e9dd3e6884.tar.gz |
sh: Detect and flag write errors on stdout in builtins.
If there is a write error on stdout, a message will be printed (to stderr)
and the exit status will be changed to 2 if it would have been 0 or 1.
PR: bin/158206
-rw-r--r-- | bin/sh/eval.c | 6 | ||||
-rw-r--r-- | bin/sh/output.c | 14 | ||||
-rw-r--r-- | bin/sh/output.h | 2 | ||||
-rw-r--r-- | tools/regression/bin/sh/errors/write-error1.0 | 3 |
4 files changed, 25 insertions, 0 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 8973f69..2e1315e 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -1070,6 +1070,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. @@ -1085,6 +1086,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 |