##// END OF EJS Templates
windows: move unlink to win32.py...
Adrian Buehlmann -
r13775:930efdc6 default
parent child Browse files
Show More
@@ -6,7 +6,7 b''
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import encoding
8 import encoding
9 import ctypes, errno, os, struct, subprocess
9 import ctypes, errno, os, struct, subprocess, random
10
10
11 _kernel32 = ctypes.windll.kernel32
11 _kernel32 = ctypes.windll.kernel32
12
12
@@ -316,3 +316,43 b' def spawndetached(args):'
316 raise ctypes.WinError()
316 raise ctypes.WinError()
317
317
318 return pi.dwProcessId
318 return pi.dwProcessId
319
320 def unlink(f):
321 '''try to implement POSIX' unlink semantics on Windows'''
322
323 # POSIX allows to unlink and rename open files. Windows has serious
324 # problems with doing that:
325 # - Calling os.unlink (or os.rename) on a file f fails if f or any
326 # hardlinked copy of f has been opened with Python's open(). There is no
327 # way such a file can be deleted or renamed on Windows (other than
328 # scheduling the delete or rename for the next reboot).
329 # - Calling os.unlink on a file that has been opened with Mercurial's
330 # posixfile (or comparable methods) will delay the actual deletion of
331 # the file for as long as the file is held open. The filename is blocked
332 # during that time and cannot be used for recreating a new file under
333 # that same name ("zombie file"). Directories containing such zombie files
334 # cannot be removed or moved.
335 # A file that has been opened with posixfile can be renamed, so we rename
336 # f to a random temporary name before calling os.unlink on it. This allows
337 # callers to recreate f immediately while having other readers do their
338 # implicit zombie filename blocking on a temporary name.
339
340 for tries in xrange(10):
341 temp = '%s-%08x' % (f, random.randint(0, 0xffffffff))
342 try:
343 os.rename(f, temp) # raises OSError EEXIST if temp exists
344 break
345 except OSError, e:
346 if e.errno != errno.EEXIST:
347 raise
348 else:
349 raise IOError, (errno.EEXIST, "No usable temporary filename found")
350
351 try:
352 os.unlink(temp)
353 except:
354 # Some very rude AV-scanners on Windows may cause this unlink to fail.
355 # Not aborting here just leaks the temp file, whereas aborting at this
356 # point may leave serious inconsistencies. Ideally, we would notify
357 # the user in this case here.
358 pass
@@ -7,7 +7,7 b''
7
7
8 from i18n import _
8 from i18n import _
9 import osutil, error
9 import osutil, error
10 import errno, msvcrt, os, re, sys, random, subprocess
10 import errno, msvcrt, os, re, sys, subprocess
11
11
12 nulldev = 'NUL:'
12 nulldev = 'NUL:'
13 umask = 002
13 umask = 002
@@ -293,46 +293,6 b' def unlinkpath(f):'
293 except OSError:
293 except OSError:
294 pass
294 pass
295
295
296 def unlink(f):
297 '''try to implement POSIX' unlink semantics on Windows'''
298
299 # POSIX allows to unlink and rename open files. Windows has serious
300 # problems with doing that:
301 # - Calling os.unlink (or os.rename) on a file f fails if f or any
302 # hardlinked copy of f has been opened with Python's open(). There is no
303 # way such a file can be deleted or renamed on Windows (other than
304 # scheduling the delete or rename for the next reboot).
305 # - Calling os.unlink on a file that has been opened with Mercurial's
306 # posixfile (or comparable methods) will delay the actual deletion of
307 # the file for as long as the file is held open. The filename is blocked
308 # during that time and cannot be used for recreating a new file under
309 # that same name ("zombie file"). Directories containing such zombie files
310 # cannot be removed or moved.
311 # A file that has been opened with posixfile can be renamed, so we rename
312 # f to a random temporary name before calling os.unlink on it. This allows
313 # callers to recreate f immediately while having other readers do their
314 # implicit zombie filename blocking on a temporary name.
315
316 for tries in xrange(10):
317 temp = '%s-%08x' % (f, random.randint(0, 0xffffffff))
318 try:
319 os.rename(f, temp) # raises OSError EEXIST if temp exists
320 break
321 except OSError, e:
322 if e.errno != errno.EEXIST:
323 raise
324 else:
325 raise IOError, (errno.EEXIST, "No usable temporary filename found")
326
327 try:
328 os.unlink(temp)
329 except:
330 # Some very rude AV-scanners on Windows may cause this unlink to fail.
331 # Not aborting here just leaks the temp file, whereas aborting at this
332 # point may leave serious inconsistencies. Ideally, we would notify
333 # the user in this case here.
334 pass
335
336 def rename(src, dst):
296 def rename(src, dst):
337 '''atomically rename file src to dst, replacing dst if it exists'''
297 '''atomically rename file src to dst, replacing dst if it exists'''
338 try:
298 try:
General Comments 0
You need to be logged in to leave comments. Login now