FWIW, after this patch, it should compile successfully for windows, the later patches only fix remaining behaviours.
This does use backup semantics; see https://reviews.llvm.org/D91141 for the implementation of the WinHandle helper. The flag FILE_FLAG_BACKUP_SEMANTICS is always included, to keep the calling code terse here.
This looks like it'll work just fine, but I've added some inline questions for readability and robustness.
What's the purpose of the + sizeof(wchar_t) here?
This seems like a reasonable time to use const auto *.
I'm wondering whether it's worth doing some bounds checking on out and the offsets and lengths into PathBuffer. Is the data from DeviceIoControl trustworthy? Could somebody create a bad reparse point that would cause this code to access arbitrary data?
I think the answer is probably not.
Does libcxx have a "debug" version with assertions enabled?
const auto &?
Not entirely sure - I based it on this: https://github.com/microsoft/STL/blob/master/stl/inc/filesystem#L3198
So with that in mind, it actually seems incorrect to have it be any larger than MAXIMUM_REPARSE_DATA_BUFFER_SIZE. So I guess I should change it to that. But that use in MS STL seems curious...
Or is that stated from the perspective of the implementation of FSCTL_GET_REPARSE_POINT, saying that the function may only ever set/use up to MAXIMUM_REPARSE_DATA_BUFFER_SIZE bytes of output space, regardless of how large a buffer is allocated?
Sure, will change that
Good point - even in release mode, such checks should be cheap, and the resulting code isn't too bad either.
Yes, I think MAXIMUM_REPARSE_DATA_BUFFER_SIZE is the most it'll ever write to the buffer, no matter how large you say the buffer is. I think the corresponding FSCTL_SET_REPARSE_POINT will actually fail if you try to send too much data.
My guess is that the + sizeof(wchar_t) was so that a zero-terminator could be added should anyone every inadvertently treat the buffer as a string.
So I guess this all works, but I wisth
Rebased, retriggering CI.
Avoid using PATH_MAX (which exists in mingw but not in MSVC) and use MAXIMUM_REPARSE_DATA_BUFFER_SIZE as fixed limit for the statically allocated buffer that is passed to the readlink() function.
(When this was implemented directly in __read_symlink() before, the windows codepath didn't need to concern itself with other fixed limits but just do its own thing and return a std::filesystem::path, but using the same readlink() interface now to keep the implementation out of operations.cpp.)