mirror of
https://github.com/facebook/sapling.git
synced 2024-12-27 06:52:23 +03:00
win32: when removing file, open it as O_TEMPORARY as a last effort
Summary: When a file is mmap'ed, removing it will always fail, even with all the rename magic. The only option that works is to ask the OS to remove the file when there is no other file handles to it. In Python, we can use the O_TEMPORARY for that. Reviewed By: quark-zju Differential Revision: D22224572 fbshipit-source-id: bee564a3006c8389f506633da5622aa7a27421ac
This commit is contained in:
parent
a935fc38b4
commit
d6ca62a1d7
@ -745,12 +745,17 @@ def unlink(f):
|
||||
try:
|
||||
os.unlink(temp)
|
||||
except OSError:
|
||||
# The unlink might have failed because the READONLY attribute may heave
|
||||
# The unlink might have failed because the READONLY attribute may have
|
||||
# been set on the original file. Rename works fine with READONLY set,
|
||||
# but not os.unlink. Reset all attributes and try again.
|
||||
_kernel32.SetFileAttributesA(temp, _FILE_ATTRIBUTE_NORMAL)
|
||||
try:
|
||||
os.unlink(temp)
|
||||
except OSError:
|
||||
try:
|
||||
# Last effort, open it as a temporary file which will remove it
|
||||
# when it's unmapped.
|
||||
os.open(temp, os.O_TEMPORARY)
|
||||
except OSError:
|
||||
# The unlink might have failed due to some very rude AV-Scanners.
|
||||
# Leaking a tempfile is the lesser evil than aborting here and
|
||||
|
20
eden/scm/tests/test-mmap-unlink.t
Normal file
20
eden/scm/tests/test-mmap-unlink.t
Normal file
@ -0,0 +1,20 @@
|
||||
#chg-compatible
|
||||
|
||||
$ cat <<EOF > mmap-unlink.py
|
||||
> import mmap
|
||||
> import os
|
||||
> import shutil
|
||||
>
|
||||
> from edenscm.mercurial import util
|
||||
>
|
||||
> with util.posixfile("file", "w") as f:
|
||||
> f.write("CONTENT")
|
||||
>
|
||||
> with util.posixfile("file", "r+b") as f:
|
||||
> m = mmap.mmap(f.fileno(), 0)
|
||||
> util.unlink("file")
|
||||
> EOF
|
||||
|
||||
$ hg debugpython -- ./mmap-unlink.py
|
||||
$ ls
|
||||
mmap-unlink.py
|
Loading…
Reference in New Issue
Block a user