[Top][All Lists]

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

[PATCH] dd: avoid unnecessary, but harmless close_stdout call.

From: Jim Meyering
Subject: [PATCH] dd: avoid unnecessary, but harmless close_stdout call.
Date: Fri, 07 Mar 2008 12:39:58 +0100

Ulrich Drepper reported in http://bugzilla.redhat.com/436368
that dd performs an unnecessary "close" syscall.
While this double close is obviously harmless in dd (no other thread can
open the STDOUT_FILENO file descriptor between the two close calls),
it is unnecessary, and the fix is easy:

        dd: avoid unnecessary, but harmless close_stdout call.
        * src/dd.c (close_stdout_required): New global.
        (maybe_close_stdout): New function.
        (main): Set the global.
        Reported by Ulrich Drepper in http://bugzilla.redhat.com/436368

Signed-off-by: Jim Meyering <address@hidden>
 src/dd.c |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/src/dd.c b/src/dd.c
index c40d0ee..0a7b154 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -392,6 +392,25 @@ static char const ebcdic_to_ascii[] =
   '\070', '\071', '\372', '\373', '\374', '\375', '\376', '\377'

+/* True if we need to close the standard output *stream*.  */
+static bool close_stdout_required = true;
+/* The only reason to close the standard output *stream* is if
+   parse_long_options fails (as it does for --help or --version).
+   In any other case, dd uses only the STDOUT_FILENO file descriptor,
+   and the "cleanup" function calls "close (STDOUT_FILENO)".
+   Closing the file descriptor and then letting the usual atexit-run
+   close_stdout function call "fclose (stdout)" would result in a
+   harmless failure of the close syscall (with errno EBADF).
+   This function serves solely to avoid the unnecessary close_stdout
+   call, once parse_long_options has succeeded.  */
+static void
+maybe_close_stdout (void)
+  if (close_stdout_required)
+    close_stdout ();
 usage (int status)
@@ -1655,12 +1674,14 @@ main (int argc, char **argv)
   textdomain (PACKAGE);

   /* Arrange to close stdout if parse_long_options exits.  */
-  atexit (close_stdout);
+  atexit (maybe_close_stdout);

   page_size = getpagesize ();

   parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, VERSION,
                      usage, AUTHORS, (char const *) NULL);
+  close_stdout_required = false;
   if (getopt_long (argc, argv, "", NULL, NULL) != -1)
     usage (EXIT_FAILURE);


reply via email to

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