[libcxx-commits] [libcxx] [libc++] Fix filesystem::remove_all bug with read-only nested directory (PR #197104)

Jake Egan via libcxx-commits libcxx-commits at lists.llvm.org
Fri May 15 07:59:12 PDT 2026


https://github.com/jakeegan updated https://github.com/llvm/llvm-project/pull/197104

>From a429230b2471fa6ff4b84d83fc60dcc40b109dc7 Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Tue, 12 May 2026 00:14:03 -0400
Subject: [PATCH 1/2] [libc++] Fix filesystem::remove_all bug with read-only
 nested directory

---
 libcxx/src/filesystem/operations.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 745db87ce3736..6afcec07b374d 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -904,6 +904,9 @@ uintmax_t remove_all_impl(int parent_directory, const path& p, error_code& ec) {
         break; // we're done iterating through the directory
       } else {
         count += remove_all_impl(fd, str, ec);
+        // If there's an error removing the child, return immediately to preserve the error code.
+        if (ec)
+          return count;
       }
     }
 

>From 9c04e74b3a2d7cd5116798e3035be53de332e920 Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Fri, 15 May 2026 10:58:36 -0400
Subject: [PATCH 2/2] Add test

---
 .../bad_perms_parent.pass.cpp                 | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 libcxx/test/libcxx/input.output/filesystems/fs.op.funcs/fs.op.remove_all/bad_perms_parent.pass.cpp

diff --git a/libcxx/test/libcxx/input.output/filesystems/fs.op.funcs/fs.op.remove_all/bad_perms_parent.pass.cpp b/libcxx/test/libcxx/input.output/filesystems/fs.op.funcs/fs.op.remove_all/bad_perms_parent.pass.cpp
new file mode 100644
index 0000000000000..1c129e9c08c39
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/filesystems/fs.op.funcs/fs.op.remove_all/bad_perms_parent.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: no-filesystem
+
+// Verify that remove_all reports the correct error (permission_denied)
+// when the parent directory has insufficient permissions.
+
+// <filesystem>
+
+#include <filesystem>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.h"
+namespace fs = std::filesystem;
+using namespace fs;
+
+int main(int, char**) {
+    scoped_test_env env;
+
+    const path parent_dir = env.create_dir("parent");
+    const path child_dir = env.create_dir(parent_dir / "child");
+    permissions(parent_dir, perms::owner_read | perms::owner_write);
+
+    const auto BadRet = static_cast<std::uintmax_t>(-1);
+    std::error_code ec;
+    assert(fs::remove_all(parent_dir, ec) == BadRet);
+    assert(ec == std::errc::permission_denied);
+
+    permissions(parent_dir, perms::owner_all);
+    return 0;
+}



More information about the libcxx-commits mailing list