-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
implement nt path conversion for windows #7664
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
Conversation
ba5677a
to
344553f
Compare
/// The error type for `removeDotDirsSanitized` | ||
pub const RemoveDotDirsError = error { TooManyParentDirs }; | ||
|
||
/// Removes '.' and '..' path components from a "sanitized relative path". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function looks like it belongs in std.fs.path. it might be a duple of resolveWindows
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's specific to windows...only works with backslashes. We could also make it work with forward slashes but I think posix has other better ways to perform this operation. resolveWindows
does alot more than this function, it uses CWD
and touches the filesystem (and I think resolves symlinks). This function does none of that, it just removes the .
and ..
directories from the path name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's specific to windows...only works with backslashes
Os-specific code is all over the standard library: it doesn't need to all get dumped into os/windows.zig.
344553f
to
1a0cd6c
Compare
1a0cd6c
to
03fc47a
Compare
lib/std/mem.zig
Outdated
} | ||
|
||
/// Collapse consecutive duplicate elements into one entry. | ||
pub fn collapseRepeats(comptime T: type, slice: []T, needle: T) usize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not much of a needle, it's more a elem
ent no?
And given it squishes slice
contents it makes sense for this to return a slice of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed needle
to elem
.
As for returning a slice, such an interface could be supported with a wrapper function at no runtime cost. In the current uses, only the resulting size is used and this same interface is propagated in a handful of places which makes the code simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can get the old behaviour by simply adding a .len
at the end.
Returning a slice makes the API much easier to use as f(collapseRepeats(..))
, throwing indices around is error-prone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning a slice makes the API much easier to use
In some cases yes. If such a use case comes up we can add a wrapper function that does this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be the other way around, returning a slice returns a pointer and the adjusted length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be the other way around, returning a slice returns a pointer and the adjusted length.
My philosphy is to do less, and then only do more if you need to. Going the other way around means always doing more even if you don't need to, and then undoing what you don't need.
I believe my pattern here is also already established in other functions in this codebase, so I don't think I'm alone in this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another example of an API that uses this methodology is the Allocator resizeFn
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're adding new public-facing APIs you can't just think in terms of "do less" or think of your single use-case.
Returning the length makes using this function with sliced inputs hard to use, consider the following example:
const x = collapseRepeats(foo[bar..Baz], ...)
If you return a sub-slice the user is able to quickly use the modified chunk of input, while if the length is returned instead another slicing operation is required.
But given that opinions are like assholes I'll rest my case, I'm getting too old for this shit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok the fact that this is a public facing "general" function is a good point. How about creating a collapseRepeatsLen
that only returns the length and collapseRepeats
that wraps it?
f90bc87
to
cd84d96
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch. This solution involves manipulating path strings, however Windows has symlinks, and on other platforms, when opening files with std.fs
, ".." path components respect symlinks, so we need to do it here, too.
// If you're looking to contribute to zig and fix this, see here for an example of how to | ||
// implement this: https://git.midipix.org/ntapi/tree/src/fs/ntapi_tt_open_physical_parent_directory.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this addressed in the PR description - did you look into using this technique to resolve ..
in a way that respects following symlinks?
Related: NtQueryObject #1840
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On windows symlinks are resolved after resolving ".." (#7751)
11162fa
to
b11bb6e
Compare
813ce22
to
d68ea4a
Compare
d3a81ba
to
b0116af
Compare
These tests check that . and .. are able to be handled by the std.fs functions. Before ziglang#7664, these tests would have failed on Windows. Closes ziglang#4659
Added in ziglang#4655/ziglang#5187, obsoleted by ziglang#7664
Nice work @marler8997! This hugely improves |
Thanks for the clean-up PRs @squeek502! |
Second attempt to fix #6044 (previous attempt #7537)
The first attempt leveraged the functionality in
ntdll
to perform the Dos to NT path conversion, however, that API requires heap allocation which @andrewrk has indicated we don't want (see #7537 (comment)).So this PR implements the logic to convert a DOS file path into an NT-compatible path in Zig's std lib.