gulrak / filesystem

An implementation of C++17 std::filesystem for C++11 /C++14/C++17/C++20 on Windows, macOS, Linux and FreeBSD.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

error_code not cleared in directory_entry::exists?

Alzathar opened this issue · comments

Describe the bug
I use the class filesystem::directory_entry and I am checking some attributes using the methods is_regular_file(), is_directory(), and exists(std::error_code &). For the later, I also check the content of the error_code object. In case, I reuse the same std::error_code object and one of the previous path is not valid, then the content of the reused std::error_code object is always false (i.e. the value() is not equal to 0) for the other paths even if the method exists returns true. Based on C++ reference, the implementation proposed by Visual Studio, or the one included in XCode 11 with macOS 10.15, the error_code object should be cleared. I also checked the document N4687 but it is not mentioned what to do in this case (see 30.10.12.3).

To Reproduce

    std::error_code ec;
    auto d1 = std::filesystem::directory_entry();
    std::cout << d1.exists(ec) << std::endl; // should be false
    std::cout << ec.value() << std::end; // should not be equal to 0
    auto d2 = std::filesystem::directory_entry(std::filesystem::current_path());
    std::cout << d2.exists(ec) << std::endl; // should be true
    std::cout << ec.value() << std::end; // expected to be equal to 0 but this is not!

Expected behavior
The std::error_code object should be cleared if the directory entry exists

Additional context
From my comprehension of the source code, the problem is in the method directory_entry::status(std::error_code &) (see line 4699).

In case, the status' type is not none, then the std::error_code object should be cleared. I proposed the following implementation to fix the issue.

GHC_INLINE file_status directory_entry::status(std::error_code& ec) const noexcept
{
    if (_status.type() != file_type::none) {
        ec.clear();
        return _status;
    }
    return filesystem::status(path(), ec);
}

This works perfectly. Thanks !