mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
ln: add WASI support via symlink_path (#11713)
This commit is contained in:
@@ -50,7 +50,7 @@ jobs:
|
||||
# Tests incompatible with WASI are annotated with
|
||||
# #[cfg_attr(wasi_runner, ignore)] in the test source files.
|
||||
# TODO: add integration tests for these tools as WASI support is extended:
|
||||
# arch b2sum cat cksum cp csplit date dir dircolors fmt join ln
|
||||
# arch b2sum cat cksum cp csplit date dir dircolors fmt join
|
||||
# ls md5sum mkdir mv nproc pathchk pr printenv ptx pwd readlink
|
||||
# realpath rm rmdir seq sha1sum sha224sum sha256sum sha384sum
|
||||
# sha512sum shred sleep sort split tail touch tsort uname uniq
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
test_base32:: test_base64:: test_basenc:: test_basename:: \
|
||||
test_comm:: test_cut:: test_dirname:: test_echo:: \
|
||||
test_expand:: test_factor:: test_false:: test_fold:: \
|
||||
test_head:: test_link:: test_nl:: test_numfmt:: \
|
||||
test_head:: test_link:: test_ln:: test_nl:: test_numfmt:: \
|
||||
test_od:: test_paste:: test_printf:: test_shuf:: test_sum:: \
|
||||
test_tee:: test_tr:: test_true:: test_truncate:: \
|
||||
test_unexpand:: test_unlink:: test_wc::
|
||||
|
||||
Generated
+1
@@ -3681,6 +3681,7 @@ version = "0.9.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"fluent",
|
||||
"rustix",
|
||||
"thiserror 2.0.18",
|
||||
"uucore",
|
||||
]
|
||||
|
||||
@@ -6,7 +6,7 @@ To find all annotated tests: `grep -rn 'wasi_runner, ignore' tests/`
|
||||
|
||||
## Tools not yet covered by integration tests
|
||||
|
||||
arch, b2sum, cat, cksum, cp, csplit, date, dir, dircolors, fmt, join, ln, ls, md5sum, mkdir, mv, nproc, pathchk, pr, printenv, ptx, pwd, readlink, realpath, rm, rmdir, seq, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, shred, sleep, sort, split, tail, touch, tsort, uname, uniq, vdir, yes
|
||||
arch, b2sum, cat, cksum, cp, csplit, date, dir, dircolors, fmt, join, ls, md5sum, mkdir, mv, nproc, pathchk, pr, printenv, ptx, pwd, readlink, realpath, rm, rmdir, seq, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, shred, sleep, sort, split, tail, touch, tsort, uname, uniq, vdir, yes
|
||||
|
||||
## WASI sandbox: host paths not visible
|
||||
|
||||
@@ -31,3 +31,7 @@ WASI does not support spawning child processes. Tests that shell out to other co
|
||||
## WASI: stdin file position not preserved through wasmtime
|
||||
|
||||
When stdin is a seekable file, wasmtime does not preserve the file position between the host and guest. Tests that validate stdin offset behavior after `head` reads are skipped.
|
||||
|
||||
## WASI: read_link on absolute paths fails under wasmtime via spawned test harness
|
||||
|
||||
`fs::read_link` on an absolute path inside the sandbox (e.g. `/file2`) returns `EPERM` when the WASI binary is launched through `std::process::Command` from the test harness, even though the same call works when wasmtime is invoked directly. This breaks `uucore::fs::canonicalize` for symlink sources, so tests that rely on following a symlink to compute a relative path are skipped.
|
||||
|
||||
@@ -25,6 +25,9 @@ uucore = { workspace = true, features = ["backup-control", "fs"] }
|
||||
thiserror = { workspace = true }
|
||||
fluent = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "wasi")'.dependencies]
|
||||
rustix = { workspace = true, features = ["fs"] }
|
||||
|
||||
[[bin]]
|
||||
name = "ln"
|
||||
path = "src/main.rs"
|
||||
|
||||
+2
-5
@@ -524,9 +524,6 @@ pub fn symlink<P1: AsRef<Path>, P2: AsRef<Path>>(src: P1, dst: P2) -> io::Result
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
fn symlink<P1: AsRef<Path>, P2: AsRef<Path>>(_src: P1, _dst: P2) -> io::Result<()> {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Unsupported,
|
||||
"symlinks not supported on this platform",
|
||||
))
|
||||
pub fn symlink<P1: AsRef<Path>, P2: AsRef<Path>>(src: P1, dst: P2) -> io::Result<()> {
|
||||
rustix::fs::symlink(src.as_ref(), dst.as_ref()).map_err(io::Error::from)
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ use std::{
|
||||
error::Error,
|
||||
ffi::{OsStr, OsString},
|
||||
fmt::{Debug, Display},
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
@@ -442,7 +443,11 @@ fn numbered_backup_path(path: &Path) -> PathBuf {
|
||||
let mut i: u64 = 1;
|
||||
loop {
|
||||
let new_path = simple_backup_path(path, OsString::from(format!(".~{i}~")));
|
||||
if !new_path.exists() {
|
||||
// Use `symlink_metadata` rather than `exists()` so that a dangling
|
||||
// symlink still counts as an existing backup (avoiding a silent
|
||||
// overwrite), and so we do not report a live symlink as missing when
|
||||
// the target cannot be stat'd.
|
||||
if fs::symlink_metadata(&new_path).is_err() {
|
||||
return new_path;
|
||||
}
|
||||
i += 1;
|
||||
@@ -451,7 +456,7 @@ fn numbered_backup_path(path: &Path) -> PathBuf {
|
||||
|
||||
fn existing_backup_path<S: AsRef<OsStr>>(path: &Path, suffix: S) -> PathBuf {
|
||||
let test_path = simple_backup_path(path, OsString::from(".~1~"));
|
||||
if test_path.exists() {
|
||||
if fs::symlink_metadata(&test_path).is_ok() {
|
||||
return numbered_backup_path(path);
|
||||
}
|
||||
simple_backup_path(path, suffix.as_ref())
|
||||
|
||||
@@ -501,6 +501,7 @@ fn test_symlink_implicit_target_dir() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
|
||||
fn test_symlink_to_dir_2args() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let filename = "test_symlink_to_dir_2args_file";
|
||||
@@ -754,6 +755,10 @@ fn test_relative_dst_already_symlink() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
wasi_runner,
|
||||
ignore = "WASI: read_link on absolute paths fails under wasmtime via spawned test harness"
|
||||
)]
|
||||
fn test_relative_src_already_symlink() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.touch("file1");
|
||||
@@ -967,6 +972,7 @@ fn test_ln_seen_file() {
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")]
|
||||
fn test_ln_non_utf8_paths() {
|
||||
use std::ffi::OsStr;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
Reference in New Issue
Block a user