diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2022-02-21 08:07:54 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-21 08:07:54 (GMT) |
commit | 959846be52b03da57f50ebc07f99ec262a86e860 (patch) | |
tree | 6b31bd12cd0afaf6f6bc5ca9984a1c54023e3ab1 /Lib | |
parent | e7115d53632bebf137ca7245a9ced7107c082e99 (diff) | |
download | cpython-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')
-rw-r--r-- | Lib/shutil.py | 12 |
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): |