Mercurial > hg-stable
changeset 9549:8b8920209317
util: move rename into posix.py and windows.py
author | Adrian Buehlmann <adrian@cadifra.com> |
---|---|
date | Wed, 07 Oct 2009 20:32:07 +0200 |
parents | 7732606b0767 |
children | 3bcb28131bab |
files | mercurial/posix.py mercurial/util.py mercurial/windows.py |
diffstat | 3 files changed, 41 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/posix.py Wed Oct 07 20:16:43 2009 +0200 +++ b/mercurial/posix.py Wed Oct 07 20:32:07 2009 +0200 @@ -13,6 +13,7 @@ nulldev = '/dev/null' normpath = os.path.normpath samestat = os.path.samestat +rename = os.rename expandglobs = False umask = os.umask(0)
--- a/mercurial/util.py Wed Oct 07 20:16:43 2009 +0200 +++ b/mercurial/util.py Wed Oct 07 20:32:07 2009 +0200 @@ -16,7 +16,7 @@ from i18n import _ import error, osutil, encoding import cStringIO, errno, re, shutil, sys, tempfile, traceback -import os, stat, time, calendar, random, textwrap +import os, stat, time, calendar, textwrap import imp # Python compatibility @@ -399,44 +399,6 @@ return False return True -def rename(src, dst): - '''atomically rename file src to dst, replacing dst if it exists''' - try: - os.rename(src, dst) - except OSError, err: # FIXME: check err (EEXIST ?) - - # On windows, rename to existing file is not allowed, so we - # must delete destination first. But if a file is open, unlink - # schedules it for delete but does not delete it. Rename - # happens immediately even for open files, so we rename - # destination to a temporary name, then delete that. Then - # rename is safe to do. - # The temporary name is chosen at random to avoid the situation - # where a file is left lying around from a previous aborted run. - # The usual race condition this introduces can't be avoided as - # we need the name to rename into, and not the file itself. Due - # to the nature of the operation however, any races will at worst - # lead to the rename failing and the current operation aborting. - - def tempname(prefix): - for tries in xrange(10): - temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff)) - if not os.path.exists(temp): - return temp - raise IOError, (errno.EEXIST, "No usable temporary filename found") - - temp = tempname(dst) - os.rename(dst, temp) - try: - os.unlink(temp) - except: - # Some rude AV-scanners on Windows may cause the unlink to - # fail. Not aborting here just leaks the temp file, whereas - # aborting at this point may leave serious inconsistencies. - # Ideally, we would notify the user here. - pass - os.rename(src, dst) - def unlink(f): """unlink and remove the directory if it is empty""" os.unlink(f)
--- a/mercurial/windows.py Wed Oct 07 20:16:43 2009 +0200 +++ b/mercurial/windows.py Wed Oct 07 20:32:07 2009 +0200 @@ -7,7 +7,7 @@ from i18n import _ import osutil, error -import errno, msvcrt, os, re, sys +import errno, msvcrt, os, re, sys, random nulldev = 'NUL:' umask = 002 @@ -283,6 +283,44 @@ except OSError: pass +def rename(src, dst): + '''atomically rename file src to dst, replacing dst if it exists''' + try: + os.rename(src, dst) + except OSError, err: # FIXME: check err (EEXIST ?) + + # On windows, rename to existing file is not allowed, so we + # must delete destination first. But if a file is open, unlink + # schedules it for delete but does not delete it. Rename + # happens immediately even for open files, so we rename + # destination to a temporary name, then delete that. Then + # rename is safe to do. + # The temporary name is chosen at random to avoid the situation + # where a file is left lying around from a previous aborted run. + # The usual race condition this introduces can't be avoided as + # we need the name to rename into, and not the file itself. Due + # to the nature of the operation however, any races will at worst + # lead to the rename failing and the current operation aborting. + + def tempname(prefix): + for tries in xrange(10): + temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff)) + if not os.path.exists(temp): + return temp + raise IOError, (errno.EEXIST, "No usable temporary filename found") + + temp = tempname(dst) + os.rename(dst, temp) + try: + os.unlink(temp) + except: + # Some rude AV-scanners on Windows may cause the unlink to + # fail. Not aborting here just leaks the temp file, whereas + # aborting at this point may leave serious inconsistencies. + # Ideally, we would notify the user here. + pass + os.rename(src, dst) + try: # override functions with win32 versions if possible from win32 import *