Bug 99311

Summary: std::filesystem::exists & std::filesystem::create_directories don't work correctly with UNC paths
Product: gcc Reporter: Moritz Bunkus <moritz>
Component: libstdc++Assignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: normal CC: webrown.cpp
Priority: P3    
Version: 10.2.0   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99333
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Attachments: test case showing the issues

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.