Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2012 22:01:10 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r244162 - in head: bin/sh tools/regression/bin/sh/errors
Message-ID:  <201212122201.qBCM1Aeh059801@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212122201.qBCM1Aeh059801>