Fix for remove_all handling when calling for non-existent or regular file. (#6)

This commit is contained in:
Steffen Schuemann 2019-03-06 00:05:49 +01:00
parent 71d05aa49d
commit 1349d3d5a5
3 changed files with 34 additions and 16 deletions

View File

@ -345,6 +345,16 @@ to the expected behavior.
## Release Notes ## Release Notes
### v1.0.8 (wip)
* Bugfix for ([#6](https://github.com/gulrak/filesystem/issues/6)), where
`ghc::filesystem::remove()` and `ghc::filesystem::remove_all()` both are
now able to remove a single file and both will not raise an error if the
path doesn't exist.
* Merged pull request ([#7](https://github.com/gulrak/filesystem/pull/7)),
a typo leading to setting error code instead of comparing it in
`ghc::filesystem::remove()` under Windows.
### [v1.0.6](https://github.com/gulrak/filesystem/releases/tag/v1.0.6) ### [v1.0.6](https://github.com/gulrak/filesystem/releases/tag/v1.0.6)
* Bugfix for ([#4](https://github.com/gulrak/filesystem/issues/4)), missing error_code * Bugfix for ([#4](https://github.com/gulrak/filesystem/issues/4)), missing error_code

View File

@ -3660,7 +3660,6 @@ inline bool remove(const path& p, std::error_code& ec) noexcept
} }
} }
#else #else
if (::remove(p.c_str()) == -1) { if (::remove(p.c_str()) == -1) {
auto error = errno; auto error = errno;
if (error == ENOENT) { if (error == ENOENT) {
@ -3690,22 +3689,26 @@ inline uintmax_t remove_all(const path& p, std::error_code& ec) noexcept
ec = detail::make_error_code(detail::portable_error::not_supported); ec = detail::make_error_code(detail::portable_error::not_supported);
return static_cast<uintmax_t>(-1); return static_cast<uintmax_t>(-1);
} }
for (auto iter = directory_iterator(p, ec); iter != directory_iterator(); iter.increment(ec)) { std::error_code tec;
if(ec) { auto fs = status(p, tec);
break; if(exists(fs) && is_directory(fs)) {
} for (auto iter = directory_iterator(p, ec); iter != directory_iterator(); iter.increment(ec)) {
if (!iter->is_symlink() && iter->is_directory()) { if(ec) {
count += remove_all(iter->path(), ec); break;
if (ec) {
return static_cast<uintmax_t>(-1);
} }
} if (!iter->is_symlink() && iter->is_directory()) {
else { count += remove_all(iter->path(), ec);
remove(iter->path(), ec); if (ec) {
if (ec) { return static_cast<uintmax_t>(-1);
return static_cast<uintmax_t>(-1); }
}
else {
remove(iter->path(), ec);
if (ec) {
return static_cast<uintmax_t>(-1);
}
++count;
} }
++count;
} }
} }
if(!ec) { if(!ec) {

View File

@ -1984,6 +1984,7 @@ TEST_CASE("30.10.15.30 remove", "[filesystem][operations][fs.op.remove]")
generateFile("foo"); generateFile("foo");
CHECK(fs::remove("foo")); CHECK(fs::remove("foo"));
CHECK(!fs::exists("foo")); CHECK(!fs::exists("foo"));
CHECK(!fs::remove("foo"));
generateFile("foo"); generateFile("foo");
CHECK(fs::remove("foo", ec)); CHECK(fs::remove("foo", ec));
CHECK(!fs::exists("foo")); CHECK(!fs::exists("foo"));
@ -2004,13 +2005,17 @@ TEST_CASE("30.10.15.31 remove_all", "[filesystem][operations][fs.op.remove_all]"
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
generateFile("foo");
CHECK(fs::remove_all("foo", ec) == 1);
CHECK(!ec);
ec.clear();
CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator()); CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator());
fs::create_directories("dir1/dir1a"); fs::create_directories("dir1/dir1a");
fs::create_directories("dir1/dir1b"); fs::create_directories("dir1/dir1b");
generateFile("dir1/dir1a/f1"); generateFile("dir1/dir1a/f1");
generateFile("dir1/dir1b/f2"); generateFile("dir1/dir1b/f2");
CHECK_NOTHROW(fs::remove_all("dir1/non-existing", ec)); CHECK_NOTHROW(fs::remove_all("dir1/non-existing", ec));
CHECK(ec); CHECK(!ec);
CHECK(fs::remove_all("dir1") == 5); CHECK(fs::remove_all("dir1") == 5);
CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator()); CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator());
} }