Skip to content

Commit b77158b

Browse files
authored
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).
1 parent a3fcca4 commit b77158b

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

Lib/shutil.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,13 +648,16 @@ def _rmtree_safe_fd(topfd, path, onerror):
648648
if is_dir:
649649
try:
650650
dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd)
651+
dirfd_closed = False
651652
except OSError:
652653
onerror(os.open, fullname, sys.exc_info())
653654
else:
654655
try:
655656
if os.path.samestat(orig_st, os.fstat(dirfd)):
656657
_rmtree_safe_fd(dirfd, fullname, onerror)
657658
try:
659+
os.close(dirfd)
660+
dirfd_closed = True
658661
os.rmdir(entry.name, dir_fd=topfd)
659662
except OSError:
660663
onerror(os.rmdir, fullname, sys.exc_info())
@@ -668,7 +671,8 @@ def _rmtree_safe_fd(topfd, path, onerror):
668671
except OSError:
669672
onerror(os.path.islink, fullname, sys.exc_info())
670673
finally:
671-
os.close(dirfd)
674+
if not dirfd_closed:
675+
os.close(dirfd)
672676
else:
673677
try:
674678
os.unlink(entry.name, dir_fd=topfd)
@@ -711,13 +715,16 @@ def onerror(*args):
711715
return
712716
try:
713717
fd = os.open(path, os.O_RDONLY)
718+
fd_closed = False
714719
except Exception:
715720
onerror(os.open, path, sys.exc_info())
716721
return
717722
try:
718723
if os.path.samestat(orig_st, os.fstat(fd)):
719724
_rmtree_safe_fd(fd, path, onerror)
720725
try:
726+
os.close(fd)
727+
fd_closed = True
721728
os.rmdir(path)
722729
except OSError:
723730
onerror(os.rmdir, path, sys.exc_info())
@@ -728,7 +735,8 @@ def onerror(*args):
728735
except OSError:
729736
onerror(os.path.islink, path, sys.exc_info())
730737
finally:
731-
os.close(fd)
738+
if not fd_closed:
739+
os.close(fd)
732740
else:
733741
try:
734742
if _rmtree_islink(path):

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ Caleb Deveraux
429429
Catherine Devlin
430430
Scott Dial
431431
Alon Diamant
432+
Lital Natan
432433
Toby Dickenson
433434
Mark Dickinson
434435
Jack Diederich
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:func:`shutil.rmtree` can now work with VirtualBox shared folders when
2+
running from the guest operating-system.

0 commit comments

Comments
 (0)