From 2cde8d967a7b5b6dbec30cd18d8f7417e4e22d33 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 9 Jan 2026 09:44:39 -0500 Subject: [PATCH 1/2] Fix std::fs::copy on WASI by setting proper OpenOptions flags When PR #147572 switched WASI to use Unix-style filesystem APIs, the open_to_and_set_permissions function for WASI was implemented to call OpenOptions::new().open() without setting any access mode flags. This causes std::fs::copy to fail with the error: "must specify at least one of read, write, or append access" The fix is to explicitly set .write(true), .create(true), and .truncate(true) on the OpenOptions, matching the behavior of the non-WASI Unix implementation but without the permission handling that WASI doesn't support. Minimal reproduction: fn main() { std::fs::write("/src.txt", b"test").unwrap(); match std::fs::copy("/src.txt", "/dst.txt") { Ok(_) => println!("PASS: fs::copy works!"), Err(e) => println!("FAIL: {}", e), } } # Compile and run: rustc +nightly --target wasm32-wasip2 test.rs -o test.wasm wasmtime -S cli --dir . test.wasm # Before fix: FAIL: must specify at least one of read, write, or append access # After fix: PASS: fs::copy works! Note: The existing test library/std/src/fs/tests.rs::copy_file_ok would have caught this regression if the std test suite ran on WASI targets. Currently std tests don't compile for wasm32-wasip2 due to Unix-specific test code in library/std/src/sys/fd/unix/tests.rs. Fixes the regression introduced in nightly-2025-12-10. --- library/std/src/sys/fs/unix.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 327b0eb7468a1..02f733c6e4c1b 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -2296,7 +2296,11 @@ fn open_to_and_set_permissions( _reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; - let writer = OpenOptions::new().open(to)?; + let writer = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(to)?; let writer_metadata = writer.metadata()?; Ok((writer, writer_metadata)) } From 43c1db7d5676ce023f873871cbf6b2c61f1e362d Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 9 Jan 2026 11:51:59 -0500 Subject: [PATCH 2/2] Run clippy --- library/std/src/sys/fs/unix.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 02f733c6e4c1b..bb2ee6ae10ed4 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -2296,11 +2296,7 @@ fn open_to_and_set_permissions( _reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; - let writer = OpenOptions::new() - .write(true) - .create(true) - .truncate(true) - .open(to)?; + let writer = OpenOptions::new().write(true).create(true).truncate(true).open(to)?; let writer_metadata = writer.metadata()?; Ok((writer, writer_metadata)) }