From 5882cce54ea902c234421c19de0a26a2adcaf6cc Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Sat, 30 Jan 2021 02:12:40 +0000 Subject: [PATCH 1/3] Expose correct symlink API on WASI As described in https://github.com/rust-lang/rust/issues/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 https://github.com/vitiral/path_abs/pull/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 #68574. --- library/std/src/sys/wasi/ext/fs.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 4f7cf6018d90f..36530e4bb35a6 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -504,13 +504,9 @@ pub fn rename, U: AsRef>( /// Create a symbolic link. /// -/// This corresponds to the `path_symlink` syscall. -pub fn symlink, U: AsRef>( - old_path: P, - fd: &File, - new_path: U, -) -> io::Result<()> { - fd.as_inner() - .fd() - .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) +/// This is similar to [`std::os::unix::fs::symlink`] and +/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir) +/// counterparts. +pub fn symlink, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { + crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref()) } From 1578f2e1e8736e4e68f720146247d402bee6c1bf Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 3 Feb 2021 15:45:30 +0000 Subject: [PATCH 2/3] Keep old symlink; expose new symlink_path --- library/std/src/sys/wasi/ext/fs.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 36530e4bb35a6..42adcd777dc63 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -502,11 +502,21 @@ pub fn rename, U: AsRef>( ) } +/// This corresponds to the `path_symlink` syscall. +pub fn symlink, U: AsRef>( + old_path: P, + fd: &File, + new_path: U, +) -> io::Result<()> { + fd.as_inner() + .fd() + .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) +} + /// Create a symbolic link. /// -/// This is similar to [`std::os::unix::fs::symlink`] and -/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir) -/// counterparts. -pub fn symlink, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { +/// This is a convenience API similar to [`std::os::unix::fs::symlink`] and +/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir). +pub fn symlink_path, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref()) } From f4b1bef542b209ba92187b06d19f84374e51a746 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 3 Feb 2021 15:46:57 +0000 Subject: [PATCH 3/3] Restore comment as it was --- library/std/src/sys/wasi/ext/fs.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 42adcd777dc63..a8da003d550ac 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -502,6 +502,8 @@ pub fn rename, U: AsRef>( ) } +/// Create a symbolic link. +/// /// This corresponds to the `path_symlink` syscall. pub fn symlink, U: AsRef>( old_path: P,