bug-coreutils
[Top][All Lists]
Advanced

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

Re: [PATCHv2 0/7] Re: temp file suffixes: mktemp DWIM


From: Eric Blake
Subject: Re: [PATCHv2 0/7] Re: temp file suffixes: mktemp DWIM
Date: Thu, 5 Nov 2009 16:07:34 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> On the other hand, aren't there situations with NFS where fflush() will 
succeed 
> at getting the data into a kernel buffer, but fclose() then fails because the 
> kernel was unable to flush its buffers over the network?  Maybe we have to do 
> something like dd, where we keep this location calling close_stream after 
all, 
> then use a custom atexit() hook that decides whether to call close_stdout() 
or 
> just manually handle only stderr?

Like this.  Should I apply it, or is it overkill?

>From 8c3ca5f93304b02bb6e3dd5aa12753e3d8c23b9b Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 5 Nov 2009 09:05:03 -0700
Subject: [PATCH] mktemp: use more robust means to avoid double-close of stdout

* src/mktemp.c (close_stdout_required): New variable.
(maybe_close_stdout): New function, borrowed from dd.c.
(main): Track whether stdout has been closed.
---
 src/mktemp.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/mktemp.c b/src/mktemp.c
index 980ec39..1ba1f19 100644
--- a/src/mktemp.c
+++ b/src/mktemp.c
@@ -128,6 +128,22 @@ mkdtemp_len (char *tmpl, size_t suff_len, size_t x_len, 
bool dry_run)
                            x_len);
 }

+/* True if we need to close standard output.  */
+static bool close_stdout_required = true;
+
+/* Avoid closing stdout twice.  Since we conditionally call
+   close_stream (stdout) in order to clean up a temporary file, the
+   exit hook needs to decide whether to do all of close_stdout or just
+   the stderr half.  */
+static void
+maybe_close_stdout (void)
+{
+  if (close_stdout_required)
+    close_stdout ();
+  else if (close_stream (stderr) != 0)
+    _exit (EXIT_FAILURE);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -153,7 +169,7 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);

-  atexit (close_stdout);
+  atexit (maybe_close_stdout);

   while ((c = getopt_long (argc, argv, "dp:qtuV", longopts, NULL)) != -1)
     {
@@ -325,7 +341,8 @@ main (int argc, char **argv)
       puts (dest_name);
       /* If we created a file, but then failed to output the file
          name, we should clean up the mess before failing.  */
-      if (!dry_run && (ferror (stdout) || fflush (stdout) != 0))
+      if (!dry_run && !(close_stdout_required = false) &&
+          close_stream (stdout) != 0)
         {
           int saved_errno = errno;
           remove (dest_name);
-- 
1.6.4.2








reply via email to

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