Mercurial > hg
changeset 13775:930efdc6bfa4
windows: move unlink to win32.py
no code change
author | Adrian Buehlmann <adrian@cadifra.com> |
---|---|
date | Sun, 27 Mar 2011 01:17:48 +0100 |
parents | 1ce0e80799c0 |
children | a2f0fdb1e488 |
files | mercurial/win32.py mercurial/windows.py |
diffstat | 2 files changed, 42 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/win32.py Sun Mar 27 12:59:25 2011 +0200 +++ b/mercurial/win32.py Sun Mar 27 01:17:48 2011 +0100 @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. import encoding -import ctypes, errno, os, struct, subprocess +import ctypes, errno, os, struct, subprocess, random _kernel32 = ctypes.windll.kernel32 @@ -316,3 +316,43 @@ raise ctypes.WinError() return pi.dwProcessId + +def unlink(f): + '''try to implement POSIX' unlink semantics on Windows''' + + # POSIX allows to unlink and rename open files. Windows has serious + # problems with doing that: + # - Calling os.unlink (or os.rename) on a file f fails if f or any + # hardlinked copy of f has been opened with Python's open(). There is no + # way such a file can be deleted or renamed on Windows (other than + # scheduling the delete or rename for the next reboot). + # - Calling os.unlink on a file that has been opened with Mercurial's + # posixfile (or comparable methods) will delay the actual deletion of + # the file for as long as the file is held open. The filename is blocked + # during that time and cannot be used for recreating a new file under + # that same name ("zombie file"). Directories containing such zombie files + # cannot be removed or moved. + # A file that has been opened with posixfile can be renamed, so we rename + # f to a random temporary name before calling os.unlink on it. This allows + # callers to recreate f immediately while having other readers do their + # implicit zombie filename blocking on a temporary name. + + for tries in xrange(10): + temp = '%s-%08x' % (f, random.randint(0, 0xffffffff)) + try: + os.rename(f, temp) # raises OSError EEXIST if temp exists + break + except OSError, e: + if e.errno != errno.EEXIST: + raise + else: + raise IOError, (errno.EEXIST, "No usable temporary filename found") + + try: + os.unlink(temp) + except: + # Some very rude AV-scanners on Windows may cause this 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 in this case here. + pass
--- a/mercurial/windows.py Sun Mar 27 12:59:25 2011 +0200 +++ b/mercurial/windows.py Sun Mar 27 01:17:48 2011 +0100 @@ -7,7 +7,7 @@ from i18n import _ import osutil, error -import errno, msvcrt, os, re, sys, random, subprocess +import errno, msvcrt, os, re, sys, subprocess nulldev = 'NUL:' umask = 002 @@ -293,46 +293,6 @@ except OSError: pass -def unlink(f): - '''try to implement POSIX' unlink semantics on Windows''' - - # POSIX allows to unlink and rename open files. Windows has serious - # problems with doing that: - # - Calling os.unlink (or os.rename) on a file f fails if f or any - # hardlinked copy of f has been opened with Python's open(). There is no - # way such a file can be deleted or renamed on Windows (other than - # scheduling the delete or rename for the next reboot). - # - Calling os.unlink on a file that has been opened with Mercurial's - # posixfile (or comparable methods) will delay the actual deletion of - # the file for as long as the file is held open. The filename is blocked - # during that time and cannot be used for recreating a new file under - # that same name ("zombie file"). Directories containing such zombie files - # cannot be removed or moved. - # A file that has been opened with posixfile can be renamed, so we rename - # f to a random temporary name before calling os.unlink on it. This allows - # callers to recreate f immediately while having other readers do their - # implicit zombie filename blocking on a temporary name. - - for tries in xrange(10): - temp = '%s-%08x' % (f, random.randint(0, 0xffffffff)) - try: - os.rename(f, temp) # raises OSError EEXIST if temp exists - break - except OSError, e: - if e.errno != errno.EEXIST: - raise - else: - raise IOError, (errno.EEXIST, "No usable temporary filename found") - - try: - os.unlink(temp) - except: - # Some very rude AV-scanners on Windows may cause this 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 in this case here. - pass - def rename(src, dst): '''atomically rename file src to dst, replacing dst if it exists''' try: