Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<filesystem> support junctions in read_symlink #2877

Merged
merged 6 commits into from
Jul 28, 2022

Conversation

strega-nil-ms
Copy link
Contributor

@strega-nil-ms strega-nil-ms commented Jul 18, 2022

  • is_symlink(junction) is still false
  • read_symlink(junction) works and does the obvious thing
  • copy_symlink(junction) doesn't work - creating a directory symlink is bad, and creating a junction is not really supported by the windows API (and also a junction is not a symlink)
  • copy(junction) works and does the obvious thing

Fixes #2818

* `is_symlink(junction) -> true`
* `read_symlink(junction)` works
* `copy_symlink(junction)` works
@strega-nil-ms strega-nil-ms marked this pull request as ready for review July 18, 2022 20:59
@strega-nil-ms strega-nil-ms requested a review from a team as a code owner July 18, 2022 20:59
@strega-nil-ms strega-nil-ms changed the title <filesystem> support junctions in *_symlink <filesystem> support junctions in *_symlink Jul 18, 2022
@strega-nil-ms strega-nil-ms added bug Something isn't working filesystem C++17 filesystem labels Jul 18, 2022
@StephanTLavavej
Copy link
Member

P0218R1_filesystem is failing with:

test_status @ 2885: check failed: is_other(file_status{file_type::junction})
Assertion failed: pass, file C:\a\1\s\tests\std\tests\P0218R1_filesystem\test.cpp, line 4044
abort() has been called

EXPECT(is_other(file_status{file_type::junction}));

Ideally, it's best to run a full test pass for x64 before submitting a PR. (For maintainers, if your local machine is slow, you can create a VM internally to run tests.) At a minimum, strongly related tests should be run, which will take just a few minutes. For example:

C:\GitHub\STL\tests\std\tests>dir /b *filesystem*
Dev11_1066931_filesystem_rename_noop
Dev11_1180290_filesystem_error_code
GH_001010_filesystem_error_encoding
P0218R1_filesystem
VSO_0121275_filesystem_canonical_should_handle_many_double_dots

@cpplearner
Copy link
Contributor

I'm all for treating junctions as symlinks, but I'm not sure about some details.

  1. The standard says ([fs.op.is.symlink]):

    bool filesystem::is_symlink(file_status s) noexcept;
    Returns: s.type() == file_­type​::​symlink.

    But this PR makes is_symlink return something different.

  2. IIUC this PR makes copy_symlink create a symlink (as opposed to a junction) if the source is a junction. Since copy calls copy_symlink if is_symlink returns true, this means copy (still) will not make a faithful copy of a junction.

@strega-nil-ms
Copy link
Contributor Author

@cpplearner you're absolutely correct, thanks for pointing that out.

@strega-nil-ms strega-nil-ms changed the title <filesystem> support junctions in *_symlink <filesystem> support junctions in read_symlink Jul 19, 2022
* `is_symlink(junction) = false`
* `copy_symlink(junction)` fails
* `copy(junction)` succeeds and creates a junction
* `read_symlink(junction)` correctly reads a junction
@strega-nil-ms
Copy link
Contributor Author

Waiting on LWG issue to link.

@strega-nil-ms strega-nil-ms added the blocked on LWG Waiting for WG21 to tell us what to do label Jul 20, 2022
@strega-nil-ms strega-nil-ms removed the blocked on LWG Waiting for WG21 to tell us what to do label Jul 25, 2022
@strega-nil-ms
Copy link
Contributor Author

We now have a LWG issue - LWG-3744!

stl/inc/filesystem Outdated Show resolved Hide resolved
stl/inc/filesystem Outdated Show resolved Hide resolved
stl/inc/filesystem Outdated Show resolved Hide resolved
stl/inc/filesystem Outdated Show resolved Hide resolved
stl/inc/xfilesystem_abi.h Outdated Show resolved Hide resolved
stl/inc/xfilesystem_abi.h Outdated Show resolved Hide resolved
stl/inc/filesystem Outdated Show resolved Hide resolved
@StephanTLavavej
Copy link
Member

Thanks for fixing this bug! I pushed minor stylistic changes, nothing should be controversial but please meow if you have concerns. 😺

@StephanTLavavej StephanTLavavej removed their assignment Jul 26, 2022
@strega-nil-ms
Copy link
Contributor Author

LGTM!
image

@StephanTLavavej StephanTLavavej self-assigned this Jul 27, 2022
@StephanTLavavej
Copy link
Member

I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.

@StephanTLavavej StephanTLavavej merged commit a0b84e0 into microsoft:main Jul 28, 2022
@StephanTLavavej
Copy link
Member

Thanks for yet another <filesystem> improvement for Windows! 💾 📀 📂

@strega-nil strega-nil deleted the fix-2818 branch August 10, 2022 20:35
fsb4000 pushed a commit to fsb4000/STL that referenced this pull request Aug 13, 2022
Co-authored-by: nicole mazzuca <mazzucan@outlook.com>
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
@LewisPringle
Copy link

I'm confused about the reasoning for is_symlink () returning false for juntions.

How is one to know to call read_symlink?

https://en.cppreference.com/w/cpp/filesystem/read_symlink says its an error to call read_symlink for soemthing that isn't a symlink.

My code:
if (filesystem::is_symlink (p)) {
p = filesystem_read_symlink(p);
}

doesn't work with our chosen fix. Not sure why the above should not work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working filesystem C++17 filesystem
Projects
None yet
Development

Successfully merging this pull request may close these issues.

<filesystem>: filesystem::read_symlink ignores junctions
5 participants