Bug 99311 - std::filesystem::exists & std::filesystem::create_directories don't work correctly with UNC paths
Summary: std::filesystem::exists & std::filesystem::create_directories don't work corr...
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 10.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2021-02-28 18:04 UTC by Moritz Bunkus
Modified: 2021-03-02 10:41 UTC (History)
1 user (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:

test case showing the issues (317 bytes, text/x-csrc)
2021-02-28 18:04 UTC, Moritz Bunkus

Note You need to log in before you can comment on or make changes to this bug.
Description Moritz Bunkus 2021-02-28 18:04:49 UTC
Created attachment 50270 [details]
test case showing the issues

These might be two separate issues, but my gut feeling is that they're both due to the same underlying problem, especially if create_directories() uses exists() to determine which components it has to create.

Using std::filesystem::exists on a UNC path with mingw 10.20.0 that points to a share (not a file or directory in a share) returns false. For example:

• exists() for the existing file "\\server\share\this_exists.txt" returns true proving that the share itself exists & the user has access to it. However, exists() on "\\server\share" (retrieved via ".parent_path()" from the full path) returns false. By comparison, boost::filesystem::exists() returns true for both paths.

• Using the same server & same share, trying to create a sub-directory via create_directories() fails. For example, trying to create "\\server\share\this_does_not_exist_yet" fails. Yes, I'm 100% sure that I have write access to the share in question. By comparison, boost::filesystem::create_directories() works fine with such a path.

I'll a sample program that shows the problem. Of course you'll have to adjust server & share names. Compiled with gcc 10.20.0 from the mxe project. Command line:

x86_64-w64-mingw32.static-g++ -std=c++17 -o std_filesystem_exists_and_create_directories.exe std_filesystem_exists_and_create_directories.cpp

The program outputs the following:

sanity check, should be true: 1
should return true but doesn't: 0
directory \\disky\mosu\does-not-exist doesn't exist yet, should be false: 0
tried to create directory \\disky\mosu\does-not-exist, have error code? 1

The first is the check for the existing file. It does return true, showing that exists() works correctly for existing files.

The second line tries exists() for the parent_path() of the file tested in line 1. Of course it should return true, too, but doesn't. The path points to the share.

Line three just establishes that the directory really doesn't exist yet. exists() should return false here and does so. Great.

Line four shows the result of the create_directories() call, or rather, whether the error_code is indicating an error. It does, which it shouldn't.