From 12ea1e3fb378a653f60840e6d47b790b4bf2689b Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 30 Mar 2026 11:50:03 +0200 Subject: [PATCH 1/2] sort: exclude ctrlc on WASI to support wasm32-wasip1 target The ctrlc crate uses platform-specific signal handling unavailable on WASI. Exclude it and skip signal handler installation on WASI, similar to the existing Redox exclusion. --- Cargo.toml | 1 + src/uu/sort/Cargo.toml | 2 +- src/uu/sort/src/tmp_dir.rs | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4f98541268e..ed76effe1ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -210,6 +210,7 @@ feat_wasm = [ "shred", "shuf", "sleep", + "sort", "sum", "tee", "true", diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index c648763764f..7351a96d29a 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -46,7 +46,7 @@ uucore = { workspace = true, features = [ fluent = { workspace = true } foldhash = { workspace = true } -[target.'cfg(not(target_os = "redox"))'.dependencies] +[target.'cfg(not(any(target_os = "redox", target_os = "wasi")))'.dependencies] ctrlc = { workspace = true } [target.'cfg(unix)'.dependencies] diff --git a/src/uu/sort/src/tmp_dir.rs b/src/uu/sort/src/tmp_dir.rs index a9b93ceb701..cf484e2ff70 100644 --- a/src/uu/sort/src/tmp_dir.rs +++ b/src/uu/sort/src/tmp_dir.rs @@ -54,7 +54,7 @@ fn should_install_signal_handler() -> bool { open_fds.saturating_add(CTRL_C_FDS + RESERVED_FOR_MERGE) <= limit } -#[cfg(not(target_os = "redox"))] +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] fn ensure_signal_handler_installed(state: Arc>) -> UResult<()> { // This shared state must originate from `HANDLER_STATE` so the handler always sees // the current lock/path pair and can clean up the active temp directory on SIGINT. @@ -104,7 +104,7 @@ fn ensure_signal_handler_installed(state: Arc>) -> UR Ok(()) } -#[cfg(target_os = "redox")] +#[cfg(any(target_os = "redox", target_os = "wasi"))] fn ensure_signal_handler_installed(_state: Arc>) -> UResult<()> { Ok(()) } From be3599573f837aef05644c49b2d3493cbc5cd29e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 31 Mar 2026 23:17:07 +0200 Subject: [PATCH 2/2] uucore: add WASI support for FileInformation and io module --- src/uucore/src/lib/features/fs.rs | 42 ++++++++++++++++++++++++++++--- src/uucore/src/lib/mods/io.rs | 9 ++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index 6ef229d175c..e4182a55ec8 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -45,6 +45,7 @@ macro_rules! has { pub struct FileInformation( #[cfg(unix)] nix::sys::stat::FileStat, #[cfg(windows)] winapi_util::file::Information, + #[cfg(target_os = "wasi")] std::fs::Metadata, ); impl FileInformation { @@ -91,6 +92,15 @@ impl FileInformation { let file = open_options.read(true).open(path.as_ref())?; Self::from_file(&file) } + #[cfg(target_os = "wasi")] + { + let metadata = if dereference { + fs::metadata(path.as_ref()) + } else { + fs::symlink_metadata(path.as_ref()) + }?; + Ok(Self(metadata)) + } } pub fn file_size(&self) -> u64 { @@ -103,6 +113,10 @@ impl FileInformation { { self.0.file_size() } + #[cfg(target_os = "wasi")] + { + self.0.len() + } } #[cfg(windows)] @@ -153,6 +167,8 @@ impl FileInformation { return self.0.st_nlink.try_into().unwrap(); #[cfg(windows)] return self.0.number_of_links(); + #[cfg(target_os = "wasi")] + return 1; } #[cfg(unix)] @@ -180,6 +196,13 @@ impl PartialEq for FileInformation { } } +#[cfg(target_os = "wasi")] +impl PartialEq for FileInformation { + fn eq(&self, _other: &Self) -> bool { + false + } +} + impl Eq for FileInformation {} impl Hash for FileInformation { @@ -194,6 +217,11 @@ impl Hash for FileInformation { self.0.volume_serial_number().hash(state); self.0.file_index().hash(state); } + #[cfg(target_os = "wasi")] + { + self.0.len().hash(state); + self.0.file_type().is_dir().hash(state); + } } } @@ -769,7 +797,7 @@ pub fn is_stdin_directory(stdin: &Stdin) -> bool { mode & S_IFMT == S_IFDIR } - #[cfg(windows)] + #[cfg(target_os = "windows")] { use std::os::windows::io::AsRawHandle; let handle = stdin.as_raw_handle(); @@ -778,11 +806,17 @@ pub fn is_stdin_directory(stdin: &Stdin) -> bool { } false } + + #[cfg(target_os = "wasi")] + { + let _ = stdin; + false + } } pub mod sane_blksize { - #[cfg(not(target_os = "windows"))] + #[cfg(unix)] use std::os::unix::fs::MetadataExt; use std::{fs::metadata, path::Path}; @@ -809,12 +843,12 @@ pub mod sane_blksize { #[cfg(unix)] metadata: &std::fs::Metadata, #[cfg(not(unix))] _: &std::fs::Metadata, ) -> u64 { - #[cfg(not(target_os = "windows"))] + #[cfg(unix)] { sane_blksize(metadata.blksize()) } - #[cfg(target_os = "windows")] + #[cfg(not(unix))] { DEFAULT } diff --git a/src/uucore/src/lib/mods/io.rs b/src/uucore/src/lib/mods/io.rs index c83c3d98744..5467b145738 100644 --- a/src/uucore/src/lib/mods/io.rs +++ b/src/uucore/src/lib/mods/io.rs @@ -74,7 +74,14 @@ impl OwnedFileDescriptorOrHandle { /// instantiates a corresponding `Stdio` pub fn into_stdio(self) -> Stdio { - Stdio::from(self.fx) + #[cfg(not(target_os = "wasi"))] + { + Stdio::from(self.fx) + } + #[cfg(target_os = "wasi")] + { + Stdio::from(File::from(self.fx)) + } } /// clones self. useful when needing another