bug-grep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/4] grep: don't say "write error" over and over


From: Paul Eggert
Subject: [PATCH 1/4] grep: don't say "write error" over and over
Date: Fri, 20 Jan 2012 23:06:24 -0800
User-agent: Mozilla/5.0 (X11; Linux i686; rv:8.0) Gecko/20111124 Thunderbird/8.0

On 01/20/2012 09:52 AM, Paul Eggert wrote:
> Come to think of it, most of the other "error (0, ...)"s are bogus

I took a look and came up with four related patches to fix these.
Here's the first one.  It fixes the originally-reported bug.  I'll
send the other three shortly.

>From 8bc29f7425509e2cd4068171ea52e40a8294558e Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Fri, 20 Jan 2012 22:33:01 -0800
Subject: [PATCH 1/4] grep: don't say "write error" over and over

Problem reported by Travis Gummels in
<https://bugzilla.redhat.com/show_bug.cgi?id=741452>.
* src/main.c (write_error_seen): New static var.
(clean_up_stdout): New function.
(prline): Do not output 'write error' more than once; exit
after the first one.  Use the same wording for the diagnostic
that close_stdout uses.
(main): Clean up with clean_up_stdout, not close_stdout, so that
grep doesn't output multiple "write error" diagnostics.
* tests/Makefile.am (TESTS): Add epipe.
* tests/epipe: New file.
---
 src/main.c        |   17 +++++++++++++++--
 tests/Makefile.am |    1 +
 tests/epipe       |   20 ++++++++++++++++++++
 3 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100755 tests/epipe

diff --git a/src/main.c b/src/main.c
index 51135ad..62ce7e3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -379,6 +379,7 @@ unsigned char eolbyte;
 /* The input file name, or (if standard input) "-" or a --label argument.  */
 static char const *filename;
 static int errseen;
+static int write_error_seen;
 
 enum directories_type
   {
@@ -425,6 +426,15 @@ suppressible_error (char const *mesg, int errnum)
   errseen = 1;
 }
 
+/* If there has already been a write error, don't bother closing
+   standard output, as that might elicit a duplicate diagnostic.  */
+static void
+clean_up_stdout (void)
+{
+  if (! write_error_seen)
+    close_stdout ();
+}
+
 /* Convert STR to a positive integer, storing the result in *OUT.
    STR must be a valid context length argument; report an error if it
    isn't.  */
@@ -881,7 +891,10 @@ prline (char const *beg, char const *lim, int sep)
     fwrite (beg, 1, lim - beg, stdout);
 
   if (ferror (stdout))
-    error (0, errno, _("writing output"));
+    {
+      write_error_seen = 1;
+      error (EXIT_TROUBLE, 0, _("write error"));
+    }
 
   lastout = lim;
 
@@ -1845,7 +1858,7 @@ main (int argc, char **argv)
 #endif
 
   exit_failure = EXIT_TROUBLE;
-  atexit (close_stdout);
+  atexit (clean_up_stdout);
 
   last_recursive = 0;
   prepended = prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 77b670b..571bd1b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -49,6 +49,7 @@ TESTS =                                               \
   dfa-heap-overrun                             \
   dfaexec-multibyte                            \
   empty                                                \
+  epipe                                                \
   equiv-classes                                 \
   ere                                          \
   euc-mb                                       \
diff --git a/tests/epipe b/tests/epipe
new file mode 100755
index 0000000..336d994
--- /dev/null
+++ b/tests/epipe
@@ -0,0 +1,20 @@
+#!/bin/sh
+# Check that a write failure with errno == EPIPE
+# doesn't cause grep to issue multiple "write error" diagnostics.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+if
+   (
+     while :; do echo x; done |
+     (trap '' PIPE; exec grep x 2>&3) |
+     :
+   ) 3>&1 | (
+     read line1 && echo >&2 "$line1" &&
+     read line2 && echo >&2 "$line2"
+   )
+then fail=1
+else fail=0
+fi
+
+Exit $fail
-- 
1.7.6.5





reply via email to

[Prev in Thread] Current Thread [Next in Thread]