summaryrefslogtreecommitdiffstats
path: root/Lib/shutil.py
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-02-21 08:07:54 (GMT)
committerGitHub <noreply@github.com>2022-02-21 08:07:54 (GMT)
commit959846be52b03da57f50ebc07f99ec262a86e860 (patch)
tree6b31bd12cd0afaf6f6bc5ca9984a1c54023e3ab1 /Lib/shutil.py
parente7115d53632bebf137ca7245a9ced7107c082e99 (diff)
downloadcpython-959846be52b03da57f50ebc07f99ec262a86e860.zip
cpython-959846be52b03da57f50ebc07f99ec262a86e860.tar.gz
cpython-959846be52b03da57f50ebc07f99ec262a86e860.tar.bz2
bpo-39327: Close file descriptors as soon as possible in shutil.rmtree (GH-31384)
It fixes the "Text File Busy" OSError when using 'rmtree' on a windows-managed filesystem in via the VirtualBox shared folder (and possible other scenarios like a windows-managed network file system). (cherry picked from commit b77158b4da449ec5b8f682816a79d004fd65ed07) Co-authored-by: Lital Natan <litaln@gmail.com>
Diffstat (limited to 'Lib/shutil.py')
-rw-r--r--Lib/shutil.py12
1 files changed, 10 insertions, 2 deletions
diff --git a/Lib/shutil.py b/Lib/shutil.py
index 752900c..c048cdf 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -656,6 +656,7 @@ def _rmtree_safe_fd(topfd, path, onerror):
if is_dir:
try:
dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd)
+ dirfd_closed = False
except OSError:
onerror(os.open, fullname, sys.exc_info())
else:
@@ -663,6 +664,8 @@ def _rmtree_safe_fd(topfd, path, onerror):
if os.path.samestat(orig_st, os.fstat(dirfd)):
_rmtree_safe_fd(dirfd, fullname, onerror)
try:
+ os.close(dirfd)
+ dirfd_closed = True
os.rmdir(entry.name, dir_fd=topfd)
except OSError:
onerror(os.rmdir, fullname, sys.exc_info())
@@ -676,7 +679,8 @@ def _rmtree_safe_fd(topfd, path, onerror):
except OSError:
onerror(os.path.islink, fullname, sys.exc_info())
finally:
- os.close(dirfd)
+ if not dirfd_closed:
+ os.close(dirfd)
else:
try:
os.unlink(entry.name, dir_fd=topfd)
@@ -719,6 +723,7 @@ def rmtree(path, ignore_errors=False, onerror=None):
return
try:
fd = os.open(path, os.O_RDONLY)
+ fd_closed = False
except Exception:
onerror(os.open, path, sys.exc_info())
return
@@ -726,6 +731,8 @@ def rmtree(path, ignore_errors=False, onerror=None):
if os.path.samestat(orig_st, os.fstat(fd)):
_rmtree_safe_fd(fd, path, onerror)
try:
+ os.close(fd)
+ fd_closed = True
os.rmdir(path)
except OSError:
onerror(os.rmdir, path, sys.exc_info())
@@ -736,7 +743,8 @@ def rmtree(path, ignore_errors=False, onerror=None):
except OSError:
onerror(os.path.islink, path, sys.exc_info())
finally:
- os.close(fd)
+ if not fd_closed:
+ os.close(fd)
else:
try:
if _rmtree_islink(path):