aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src/filesystem/operations.cpp
diff options
context:
space:
mode:
authorKonstantin Varlamov <varconst@apple.com>2022-02-28 12:55:27 -0500
committerLouis Dionne <ldionne.2@gmail.com>2022-02-28 12:56:36 -0500
commit3906ebf750b80e36c2d6c52130cf40771e1b55fb (patch)
treeab1011d43c36004f4fb85fe90ca97f69b896fe40 /libcxx/src/filesystem/operations.cpp
parent3104994104f0c2f274acf5e01eb6cc82e9cca06b (diff)
downloadllvm-3906ebf750b80e36c2d6c52130cf40771e1b55fb.zip
llvm-3906ebf750b80e36c2d6c52130cf40771e1b55fb.tar.gz
llvm-3906ebf750b80e36c2d6c52130cf40771e1b55fb.tar.bz2
[libc++] Fix double file closing in `std::filesystem::remove_all()`.
According to Linux documentation (see e.g. https://linux.die.net/man/3/closedir): > A successful call to `closedir()` also closes the underlying file > descriptor associated with `dirp`. Thus, calling `close()` after a successful call to `closedir()` is at best redundant. Worse, should a different thread open a file in-between the calls to `closedir()` and `close()` and get the same file descriptor, the call to `close()` might actually close a different file than was intended. rdar://89251874 Differential Revision: https://reviews.llvm.org/D120453
Diffstat (limited to 'libcxx/src/filesystem/operations.cpp')
-rw-r--r--libcxx/src/filesystem/operations.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 0e2ebdf..7392b83 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -1416,12 +1416,14 @@ uintmax_t remove_all_impl(int parent_directory, const path& p, error_code& ec) {
if (fd != -1) {
// If that worked, iterate over the contents of the directory and
// remove everything in it, recursively.
- scope_exit close_fd([=] { ::close(fd); });
DIR* stream = ::fdopendir(fd);
if (stream == nullptr) {
+ ::close(fd);
ec = detail::capture_errno();
return 0;
}
+ // Note: `::closedir` will also close the associated file descriptor, so
+ // there should be no call to `close(fd)`.
scope_exit close_stream([=] { ::closedir(stream); });
uintmax_t count = 0;