diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index 90ec5eda5..f63a5a4c3 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -414,7 +414,7 @@ void recursiveSync(const Path & path) } -static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, uint64_t & bytesFreed) +static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, uint64_t & bytesFreed, std::exception_ptr & ex) { #ifndef _WIN32 checkInterrupt(); @@ -472,7 +472,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, checkInterrupt(); std::string childName = dirent->d_name; if (childName == "." || childName == "..") continue; - _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed); + _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed, ex); } if (errno) throw SysError("reading directory %1%", path); } @@ -480,7 +480,14 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, int flags = S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0; if (unlinkat(parentfd, name.c_str(), flags) == -1) { if (errno == ENOENT) return; - throw SysError("cannot unlink %1%", path); + try { + throw SysError("cannot unlink %1%", path); + } catch (...) { + if (!ex) + ex = std::current_exception(); + else + ignoreExceptionExceptInterrupt(); + } } #else // TODO implement @@ -500,7 +507,12 @@ static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFree throw SysError("opening directory '%1%'", path); } - _deletePath(dirfd.get(), path, bytesFreed); + std::exception_ptr ex; + + _deletePath(dirfd.get(), path, bytesFreed, ex); + + if (ex) + std::rethrow_exception(ex); }