autoconf
[Top][All Lists]
Advanced

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

atomic replacement of autom4te's output file


From: Ben Pfaff
Subject: atomic replacement of autom4te's output file
Date: Thu, 25 May 2006 13:13:14 -0700
User-agent: Gnus/5.110004 (No Gnus v0.4) Emacs/21.4 (gnu/linux)

A long time ago, a Debian user submitted the following bug
report (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=221483):

    I noticed that if I ctrl-c autoconf, it can leave a partially written,
    executable configure script. I was lucky enough to get a configure
    script that exited with a shell parse error, but if I had been unlucky,
    it might have exited 0 without doing all the tests I expected it to do.
    That would have sucked to ship to users.

    There are many ways to update a file in a way that is not prone to these
    problems, and I suggest that autoconf adopt one of them.

Since that time, I've been carrying along the following as a
Debian-specific patch.  I'd appreciate feedback on whether it, or
something that achieves the same effect, is suitable for
commitment upstream.

--- autoconf-2.59.cvs.2006.05.25.orig/bin/autom4te.in
+++ autoconf-2.59.cvs.2006.05.25/bin/autom4te.in
@@ -540,13 +540,21 @@
   # stdout is to be handled by hand :(.  Don't use fdopen as it means
   # we will close STDOUT, which we already do in END.
   my $out = new Autom4te::XFile;
-  if ($output eq '-')
+  my $atomic_replace;
+  if ($output eq '-' || (-e $output && ! -f _))
     {
       $out->open (">$output");
+      $atomic_replace = 0;
     }
   else
     {
-      $out->open($output, O_CREAT | O_WRONLY | O_TRUNC, oct ($mode));
+      $out->open("$output.tmp", O_CREAT | O_WRONLY | O_TRUNC, oct ($mode));
+      if ($out) {
+        $atomic_replace = 1;
+      } else {
+        $out->open($output, O_CREAT | O_WRONLY | O_TRUNC, oct ($mode));
+        $atomic_replace = 0;
+      }
     }
   fatal "cannot create $output: $!"
     unless $out;
@@ -581,6 +589,11 @@
       print $out "$res\n";
     }
 
+  if ($atomic_replace && !rename("$output.tmp", "$output")) {
+    move ("${output}.tmp", "$output")
+      or fatal "cannot rename ${output}.tmp as $output: $!";
+  }
+
   # If no forbidden words, we're done.
   return
     if ! %prohibited;

-- 
Ben Pfaff 
email: address@hidden
web: http://benpfaff.org




reply via email to

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