mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
[3.11] bpo-35332: Handle os.close() errors in shutil.rmtree() (GH-23766) (GH-112764)
* Ignore os.close() errors when ignore_errors is True.
* Pass os.close() errors to the error handler if specified.
* os.close no longer retried after error.
(cherry picked from commit 11d88a178b
)
Co-authored-by: Zackery Spytz <zspytz@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
23920a0843
commit
54ca4c64d0
3 changed files with 56 additions and 2 deletions
|
@ -660,7 +660,12 @@ def _rmtree_safe_fd(topfd, path, onerror):
|
|||
_rmtree_safe_fd(dirfd, fullname, onerror)
|
||||
try:
|
||||
os.close(dirfd)
|
||||
except OSError:
|
||||
# close() should not be retried after an error.
|
||||
dirfd_closed = True
|
||||
onerror(os.close, fullname, sys.exc_info())
|
||||
dirfd_closed = True
|
||||
try:
|
||||
os.rmdir(entry.name, dir_fd=topfd)
|
||||
except OSError:
|
||||
onerror(os.rmdir, fullname, sys.exc_info())
|
||||
|
@ -675,7 +680,10 @@ def _rmtree_safe_fd(topfd, path, onerror):
|
|||
onerror(os.path.islink, fullname, sys.exc_info())
|
||||
finally:
|
||||
if not dirfd_closed:
|
||||
os.close(dirfd)
|
||||
try:
|
||||
os.close(dirfd)
|
||||
except OSError:
|
||||
onerror(os.close, fullname, sys.exc_info())
|
||||
else:
|
||||
try:
|
||||
os.unlink(entry.name, dir_fd=topfd)
|
||||
|
@ -732,7 +740,12 @@ def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None):
|
|||
_rmtree_safe_fd(fd, path, onerror)
|
||||
try:
|
||||
os.close(fd)
|
||||
except OSError:
|
||||
# close() should not be retried after an error.
|
||||
fd_closed = True
|
||||
onerror(os.close, path, sys.exc_info())
|
||||
fd_closed = True
|
||||
try:
|
||||
os.rmdir(path, dir_fd=dir_fd)
|
||||
except OSError:
|
||||
onerror(os.rmdir, path, sys.exc_info())
|
||||
|
@ -744,7 +757,10 @@ def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None):
|
|||
onerror(os.path.islink, path, sys.exc_info())
|
||||
finally:
|
||||
if not fd_closed:
|
||||
os.close(fd)
|
||||
try:
|
||||
os.close(fd)
|
||||
except OSError:
|
||||
onerror(os.close, path, sys.exc_info())
|
||||
else:
|
||||
if dir_fd is not None:
|
||||
raise NotImplementedError("dir_fd unavailable on this platform")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue