-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Expose correct symlink API on WASI #81542
Conversation
The job Click to see the possible cause of the failure (guessed by this bot)
|
As described in rust-lang#68574, the currently exposed API for symlinks is, in fact, a thin wrapper around the corresponding syscall, and not suitable for public usage. The reason is that the 2nd param in the call is expected to be a handle of a "preopened directory" (a WASI concept for exposing dirs), and the only way to retrieve such handle right now is by tinkering with a private `__wasilibc_find_relpath` API, which is an implementation detail and definitely not something we want users to call directly. Making matters worse, the semantics of this param aren't obvious from its name (`fd`), and easy to misinterpret, resulting in people trying to pass a handle of the target file itself (as in vitiral/path_abs#50), which doesn't work as expected. I did a codesearch among open-source repos, and the usage above is so far the only usage of this API at all, but we should fix it before more people start using it incorrectly. While this is technically a breaking API change, I believe it's a justified one, as 1) it's OS-specific and 2) there was strictly no way to correctly use the previous form of the API, and if someone does use it, they're likely doing it wrong like in the example above. The new API does not lead to the same confusion, as it mirrors `std::os::unix::fs::symlink` and `std::os::windows::fs::symlink_{file,dir}` variants by accepting source/target paths. Fixes rust-lang#68574.
8de0f75
to
5882cce
Compare
My personal thoughts on this issue haven't really changed since last I wrote which is that I think the best option for improving the state of things is to expose a function which, given a path, returns a file descriptor and a relative path. I'm not sure why the If the current signature is being actively misused in the wild then we should likely improve the documentation, add examples, or maybe even tweak the parameter order in the signature. The purpose of this module, however, is to be very close to the system layer, and what we have at the system layer I believe is this API. |
Ah, maybe I misunderstood your comments there, in particular:
seemed to suggest that it would be okay to expose if I make the PR?
I feel like it's singled-out right now instead, compared to all other filesystem methods on one side, and all other OS methods for symlinks on another side. If the goal of the module is to be as close to raw system bindings, I can understand that and yes, this change would make it different. However, it also makes absence of a single I do agree that the idea to "expose a function which, given a path, returns a file descriptor and a relative path" is good and useful too, it just still seems like the APIs as they stand right now are too easy to misunderstand / to misuse for people not familiar with WASI preopen system, which is probably most generic library authors who just want to create a symlink in a cross-platform fashion. Hence, I'd still expose a symlink helper at least under a different name, regardless of the low-level API for splitting paths up. |
What I meant by that is you can always make a PR like this one, but you specifically tagged me for review here and my opinion hasn't changed about this in the meantime. I'm not the only reviewer here, of course though. I think a symlink function under a different name seems reasonable, but the default name I'd leave for the raw WASI operations since that's the purpose of |
Ah, I see, makes sense. I misinterpreted the original phrase as "I don't want to work on this myself, but open to some adding such methods".
That makes sense. I thought that users who want raw WASI access, would be encouraged to use the I'm definitely open to renaming the symlink function above, while keeping original intact. I guess I'll wait for more reviews and suggestions on better naming or namespace meanwhile. |
I think there's definitely a point in the design space for libstd to not really expose much of WASI, especially as WASI grows with more and more features. In that sense it might be the best design for libstd to only expose the conveniences as you say, and otherwise recommend the |
Yeah, if they didn't already exist, I'd be definitely leaning towards this option personally. I'm guessing now it would be too much of a breaking change? Although maybe not really, given that most of other functions also rely on "preopen dir fd", which hasn't been exposed yet. |
AFAIK everything here is unstable, which means we can change it at any time. |
SGTM. What should we do about this PR meanwhile - should I rename the function, wait for more reviewers or abandon in favour of "rewrite all functions to be helpers" style? (I'm assuming the latter needs to be discussed with a wider audience... somewhere though) |
That's up to you, I don't personally have a preference of how best to go about this. |
Ok I went ahead and restored the old I think this is most reasonable approach for now, particularly because the other two APIs - This change is the least invasive way to add such API and can be merged regardless of what we decide to do with syscall-like methods in the future IMO. |
@bors: r+ |
📌 Commit f4b1bef has been approved by |
Expose correct symlink API on WASI As described in rust-lang#68574, the currently exposed API for symlinks is, in fact, a thin wrapper around the corresponding syscall, and not suitable for public usage. The reason is that the 2nd param in the call is expected to be a handle of a "preopened directory" (a WASI concept for exposing dirs), and the only way to retrieve such handle right now is by tinkering with a private `__wasilibc_find_relpath` API, which is an implementation detail and definitely not something we want users to call directly. Making matters worse, the semantics of this param aren't obvious from its name (`fd`), and easy to misinterpret, resulting in people trying to pass a handle of the target file itself (as in vitiral/path_abs#50), which doesn't work as expected. I did a [codesearch among open-source repos](https://sourcegraph.com/search?q=std%3A%3Aos%3A%3Awasi%3A%3Afs%3A%3Asymlink&patternType=literal), and the usage above is so far the only usage of this API at all, but we should fix it before more people start using it incorrectly. While this is technically a breaking API change, I believe it's a justified one, as 1) it's OS-specific and 2) there was strictly no way to correctly use the previous form of the API, and if someone does use it, they're likely doing it wrong like in the example above. The new API does not lead to the same confusion, as it mirrors `std::os::unix::fs::symlink` and `std::os::windows::fs::symlink_{file,dir}` variants by accepting source/target paths. Fixes rust-lang#68574. r? `@alexcrichton`
@alexcrichton Thanks! |
Expose correct symlink API on WASI As described in rust-lang#68574, the currently exposed API for symlinks is, in fact, a thin wrapper around the corresponding syscall, and not suitable for public usage. The reason is that the 2nd param in the call is expected to be a handle of a "preopened directory" (a WASI concept for exposing dirs), and the only way to retrieve such handle right now is by tinkering with a private `__wasilibc_find_relpath` API, which is an implementation detail and definitely not something we want users to call directly. Making matters worse, the semantics of this param aren't obvious from its name (`fd`), and easy to misinterpret, resulting in people trying to pass a handle of the target file itself (as in vitiral/path_abs#50), which doesn't work as expected. I did a [codesearch among open-source repos](https://sourcegraph.com/search?q=std%3A%3Aos%3A%3Awasi%3A%3Afs%3A%3Asymlink&patternType=literal), and the usage above is so far the only usage of this API at all, but we should fix it before more people start using it incorrectly. While this is technically a breaking API change, I believe it's a justified one, as 1) it's OS-specific and 2) there was strictly no way to correctly use the previous form of the API, and if someone does use it, they're likely doing it wrong like in the example above. The new API does not lead to the same confusion, as it mirrors `std::os::unix::fs::symlink` and `std::os::windows::fs::symlink_{file,dir}` variants by accepting source/target paths. Fixes rust-lang#68574. r? `@alexcrichton`
Rollup of 15 pull requests Successful merges: - rust-lang#79554 (Generic associated types in trait paths) - rust-lang#80726 (relax adt unsizing requirements) - rust-lang#81307 (Handle `Span`s for byte and raw strings and add more detail ) - rust-lang#81318 (rustdoc-json: Fix has_body) - rust-lang#81456 (Make remote-test-server easier to use with new targets) - rust-lang#81497 (rustdoc: Move `display_fn` struct inside `display_fn`) - rust-lang#81500 (Remove struct_type from union output) - rust-lang#81542 (Expose correct symlink API on WASI) - rust-lang#81676 (Add more information to the error code for 'crate not found') - rust-lang#81682 (Add additional bitset benchmarks) - rust-lang#81730 (Make `Allocator` object-safe) - rust-lang#81763 (Cleanup rustdoc pass descriptions a bit) - rust-lang#81767 (Update LayoutError/LayoutErr stability attributes) - rust-lang#81771 (Indicate change in RSS from start to end of pass in time-passes output) - rust-lang#81781 (Fix `install-awscli.sh` error in CI) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
As described in vitiral#51, current implementation is incorrect and won't work and, as described in rust-lang/rust#68574, there was no correct way to use that API. I went ahead and added a new API for symlinks in rust-lang/rust#81542, and now that it's landed, it can be used to correctly create symlinks. Fixes vitiral#51.
As described in #51, current implementation is incorrect and won't work and, as described in rust-lang/rust#68574, there was no correct way to use that API. I went ahead and added a new API for symlinks in rust-lang/rust#81542, and now that it's landed, it can be used to correctly create symlinks. Fixes #51.
As described in #68574, the currently exposed API for symlinks is, in fact, a thin wrapper around the corresponding syscall, and not suitable for public usage.
The reason is that the 2nd param in the call is expected to be a handle of a "preopened directory" (a WASI concept for exposing dirs), and the only way to retrieve such handle right now is by tinkering with a private
__wasilibc_find_relpath
API, which is an implementation detail and definitely not something we want users to call directly.Making matters worse, the semantics of this param aren't obvious from its name (
fd
), and easy to misinterpret, resulting in people trying to pass a handle of the target file itself (as in vitiral/path_abs#50), which doesn't work as expected.I did a codesearch among open-source repos, and the usage above is so far the only usage of this API at all, but we should fix it before more people start using it incorrectly.
While this is technically a breaking API change, I believe it's a justified one, as 1) it's OS-specific and 2) there was strictly no way to correctly use the previous form of the API, and if someone does use it, they're likely doing it wrong like in the example above.
The new API does not lead to the same confusion, as it mirrors
std::os::unix::fs::symlink
andstd::os::windows::fs::symlink_{file,dir}
variants by accepting source/target paths.Fixes #68574.
r? @alexcrichton