Author: jilles
Date: Wed Dec 12 22:01:10 2012
New Revision: 244162
URL: http://svnweb.freebsd.org/changeset/base/244162

Log:
  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

Added:
  head/tools/regression/bin/sh/errors/write-error1.0   (contents, props changed)
Modified:
  head/bin/sh/eval.c
  head/bin/sh/output.c
  head/bin/sh/output.h

Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c  Wed Dec 12 20:55:30 2012        (r244161)
+++ head/bin/sh/eval.c  Wed Dec 12 22:01:10 2012        (r244162)
@@ -1070,6 +1070,7 @@ evalcommand(union node *cmd, int flags, 
                }
                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, 
                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();

Modified: head/bin/sh/output.c
==============================================================================
--- head/bin/sh/output.c        Wed Dec 12 20:55:30 2012        (r244161)
+++ head/bin/sh/output.c        Wed Dec 12 22:01:10 2012        (r244162)
@@ -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, ...)
 {

Modified: head/bin/sh/output.h
==============================================================================
--- head/bin/sh/output.h        Wed Dec 12 20:55:30 2012        (r244161)
+++ head/bin/sh/output.h        Wed Dec 12 22:01:10 2012        (r244162)
@@ -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);

Added: head/tools/regression/bin/sh/errors/write-error1.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/regression/bin/sh/errors/write-error1.0  Wed Dec 12 22:01:10 
2012        (r244162)
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+! echo >&- 2>/dev/null
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to