From fcabff81dd510ba2d5ab43eb855fef64e513d5b2 Mon Sep 17 00:00:00 2001 From: Eivind Jahren Date: Fri, 13 Feb 2026 14:52:49 +0100 Subject: [PATCH 1/2] Replace util_clear_directory with std::filesystem::remove_all() This is different behavior in the case the function fails to remove a file, before it would silently fail. --- lib/CMakeLists.txt | 2 +- lib/include/ert/util/util.hpp | 1 - lib/util/test_work_area.cpp | 11 +++-- lib/util/util_getuid.cpp | 92 ----------------------------------- 4 files changed, 8 insertions(+), 98 deletions(-) delete mode 100644 lib/util/util_getuid.cpp diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 4a60ff34f5..95fbaf1064 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,5 +1,5 @@ if(ERT_HAVE_GETUID AND ERT_HAVE_OPENDIR) - list(APPEND opt_srcs util/test_work_area.cpp util/util_getuid.cpp) + list(APPEND opt_srcs util/test_work_area.cpp) endif() if(ERT_HAVE_OPENDIR) diff --git a/lib/include/ert/util/util.hpp b/lib/include/ert/util/util.hpp index d5281ae168..ef04aae4a2 100644 --- a/lib/include/ert/util/util.hpp +++ b/lib/include/ert/util/util.hpp @@ -109,7 +109,6 @@ void util_make_path(const char *); double util_file_difftime(const char *, const char *); size_t util_file_size(const char *); size_t util_fd_size(int fd); -void util_clear_directory(const char *path, bool strict_uid, bool unlink_root); void util_strupr(char *); bool util_string_equal(const char *s1, const char *s2); char *util_alloc_strupr_copy(const char *); diff --git a/lib/util/test_work_area.cpp b/lib/util/test_work_area.cpp index 7e90288313..d271abb3f6 100644 --- a/lib/util/test_work_area.cpp +++ b/lib/util/test_work_area.cpp @@ -7,12 +7,12 @@ #include #endif -#include - #include #include #include +#include + #include #include @@ -187,8 +187,11 @@ TestArea::TestArea(const std::string &test_name, bool store_area) } TestArea::~TestArea() { - if (!this->store) - util_clear_directory(this->cwd.c_str(), true, true); + if (!this->store) { + std::error_code ec; + std::filesystem::remove_all(this->cwd, ec); + // silently fail for backwards compatibility + } util_chdir(this->org_cwd.c_str()); } diff --git a/lib/util/util_getuid.cpp b/lib/util/util_getuid.cpp deleted file mode 100644 index bfbb61e69e..0000000000 --- a/lib/util/util_getuid.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include - -#include - -#include -#include -#include - -/** - Only removes the last component in path. -*/ -void static util_clear_directory__(const char *path, bool strict_uid, - bool unlink_root) { - if (util_is_directory(path)) { - DIR *dirH = opendir(path); - - if (dirH != NULL) { - const uid_t uid = getuid(); - struct dirent *dentry; - - while ((dentry = readdir(dirH)) != NULL) { - stat_type buffer; - mode_t mode; - const char *entry_name = dentry->d_name; - if ((strcmp(entry_name, ".") != 0) && - (strcmp(entry_name, "..") != 0)) { - char *full_path = - util_alloc_filename(path, entry_name, NULL); - - if (lstat(full_path, &buffer) == 0) { - mode = buffer.st_mode; - - if (S_ISDIR(mode)) - /* - Recursively descending into sub directory. - */ - util_clear_directory__(full_path, strict_uid, true); - else if (S_ISLNK(mode)) - /* - Symbolic links are unconditionally removed. - */ - unlink(full_path); - else if (S_ISREG(mode)) { - /* - It is a regular file - we remove it (if we own it!). - */ - if ((!strict_uid) || (buffer.st_uid == uid)) { - int unlink_return = unlink(full_path); - if (unlink_return != 0) { - /* Unlink failed */ - } - } - } - } - free(full_path); - } - } - } - closedir(dirH); - - /* Finish with clearing the root directory */ - if (unlink_root) { - int rmdir_return = rmdir(path); - if (rmdir_return != 0) { - /* Unlink failed */ - } - } - } -} - -/** - This function will clear away all the contents (including - subdirectories) in the directory @path. - - If the parameter @strict_uid is set to true, the function will only - attempt to remove entries where the calling uid is also the owner - of the entry. - - If the parameter @unlink_root is true the directory @path will also - be removed, otherwise it will be left as an empty directory. - - The function will just go about deleting as much as it can; errors - are not signalled in any way! - - The function is in util_getuid() because uid_t and getuid() are so - important elements of the function. -*/ - -void util_clear_directory(const char *path, bool strict_uid, bool unlink_root) { - util_clear_directory__(path, strict_uid, unlink_root); -} From 174ecbf076fcc1c5c5969333deb1ba9daf2c78db Mon Sep 17 00:00:00 2001 From: Eivind Jahren Date: Thu, 16 Apr 2026 15:05:34 +0200 Subject: [PATCH 2/2] Move to orig_cwd before cleanup to avoid EBUSY The POSIX standard says that doing rmdir on the current working directory could result in EBUSY, but it is unspecified. So we move to orig_cwd before removing just in case. --- lib/util/test_work_area.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/util/test_work_area.cpp b/lib/util/test_work_area.cpp index d271abb3f6..f207f3c934 100644 --- a/lib/util/test_work_area.cpp +++ b/lib/util/test_work_area.cpp @@ -187,13 +187,12 @@ TestArea::TestArea(const std::string &test_name, bool store_area) } TestArea::~TestArea() { + util_chdir(this->org_cwd.c_str()); if (!this->store) { std::error_code ec; std::filesystem::remove_all(this->cwd, ec); // silently fail for backwards compatibility } - - util_chdir(this->org_cwd.c_str()); } const std::string &TestArea::test_cwd() const { return this->cwd; }