[PATCH 1 of 1] util.rename: use stronger temporary file names

Sune Foldager cryo at cyanite.org
Tue Apr 28 07:03:25 CDT 2009


# HG changeset patch
# User Sune Foldager <sune.foldager at edlund.dk>
# Date 1240919523 -7200
# Node ID a77913eb5b904d8cee2ca5db6bedcfb8243904f0
# Parent  655c435efe92c2457894e86fb62621a41f8c17a2
util.rename: use stronger temporary file names

On Windows, a temporary file name is used to force the rename, since the target
file is not allowed to exist. Previously, this name was fixed, which can lead to
serious corruption issues if the file somehow gets stuck. Since tempfile.mktemp
is deprecated, we introduce a simple version of it tailored to our needs.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -15,7 +15,7 @@
 
 from i18n import _
 import cStringIO, errno, re, shutil, sys, tempfile, traceback, error
-import os, stat, threading, time, calendar, glob, osutil
+import os, stat, threading, time, calendar, glob, osutil, random
 import imp
 
 # Python compatibility
@@ -625,6 +625,16 @@
         return False
     return True
 
+
+def tempfilename(prefix='tmp'):
+    chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
+    for tries in xrange(1000):
+        suffix = ''.join([random.choice(chars) for i in xrange(10)])
+        name = prefix + '-' + suffix
+        if not os.path.exists(name):
+            return name
+    raise IOError, (_errno.EEXIST, "No usable temporary filename found")
+
 def rename(src, dst):
     """forcibly rename a file"""
     try:
@@ -636,7 +646,7 @@
         # happens immediately even for open files, so we rename
         # destination to a temporary name, then delete that. then
         # rename is safe to do.
-        temp = dst + "-force-rename"
+        temp = tempfilename(dst)
         os.rename(dst, temp)
         os.unlink(temp)
         os.rename(src, dst)


More information about the Mercurial-devel mailing list