Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/wasi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,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
# arch b2sum cat cksum 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
Expand All @@ -69,6 +69,7 @@ jobs:
UUTESTS_WASM_RUNNER=wasmtime \
cargo test --test tests -- \
test_base32:: test_base64:: test_basenc:: test_basename:: \
test_cp::test_cp_arg_symlink \
test_comm:: test_cut:: test_dirname:: test_echo:: \
test_expand:: test_factor:: test_false:: test_fold:: \
test_head:: test_link:: test_ln:: test_nl:: test_numfmt:: \
Expand Down
3 changes: 3 additions & 0 deletions src/uu/cp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ windows-sys = { workspace = true, features = [
"Win32_Storage_FileSystem",
] }

[target.'cfg(target_os = "wasi")'.dependencies]
rustix = { workspace = true, features = ["fs"] }

[[bin]]
name = "cp"
path = "src/main.rs"
Expand Down
30 changes: 14 additions & 16 deletions src/uu/cp/src/cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1959,18 +1959,8 @@ pub(crate) fn copy_attributes(
fn symlink_file(
source: &Path,
dest: &Path,
#[cfg(not(target_os = "wasi"))] symlinked_files: &mut HashSet<FileInformation>,
#[cfg(target_os = "wasi")] _symlinked_files: &mut HashSet<FileInformation>,
symlinked_files: &mut HashSet<FileInformation>,
) -> CopyResult<()> {
#[cfg(target_os = "wasi")]
{
Err(CpError::IoErrContext(
io::Error::new(io::ErrorKind::Unsupported, "symlinks not supported"),
translate!("cp-error-cannot-create-symlink",
"dest" => get_filename(dest).unwrap_or("?").quote(),
"source" => get_filename(source).unwrap_or("?").quote()),
))
}
#[cfg(not(any(windows, target_os = "wasi")))]
{
std::os::unix::fs::symlink(source, dest).map_err(|e| {
Expand All @@ -1993,13 +1983,21 @@ fn symlink_file(
)
})?;
}
#[cfg(not(target_os = "wasi"))]
#[cfg(target_os = "wasi")]
{
if let Ok(file_info) = FileInformation::from_path(dest, false) {
symlinked_files.insert(file_info);
}
Ok(())
platform::create_symlink(source, dest).map_err(|e| {
CpError::IoErrContext(
e,
translate!("cp-error-cannot-create-symlink",
"dest" => get_filename(dest).unwrap_or("?").quote(),
"source" => get_filename(source).unwrap_or("?").quote()),
)
})?;
}
if let Ok(file_info) = FileInformation::from_path(dest, false) {
symlinked_files.insert(file_info);
}
Ok(())
}

fn context_for(src: &Path, dest: &Path) -> String {
Expand Down
5 changes: 5 additions & 0 deletions src/uu/cp/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ pub(crate) use self::windows::copy_on_write;
mod other;
#[cfg(not(any(unix, target_os = "windows")))]
pub(crate) use self::other::copy_on_write;

#[cfg(target_os = "wasi")]
mod wasi;
#[cfg(target_os = "wasi")]
pub(crate) use self::wasi::create_symlink;
11 changes: 11 additions & 0 deletions src/uu/cp/src/platform/wasi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This file is part of the uutils coreutils package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use std::io;
use std::path::Path;

pub(crate) fn create_symlink(source: &Path, dest: &Path) -> io::Result<()> {
rustix::fs::symlink(source, dest).map_err(io::Error::from)
}
6 changes: 5 additions & 1 deletion tests/by-util/test_cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use std::os::unix::fs::PermissionsExt;
use std::os::unix::fs::{FileTypeExt, MetadataExt};
#[cfg(windows)]
use std::os::windows::fs::symlink_file;
#[cfg(not(windows))]
use std::path::Path;
#[cfg(target_os = "linux")]
use std::path::PathBuf;
Expand Down Expand Up @@ -924,6 +923,11 @@ fn test_cp_arg_symlink() {
.succeeds();

assert!(at.is_symlink(TEST_HELLO_WORLD_DEST));
assert_eq!(
std::fs::read_link(at.plus(TEST_HELLO_WORLD_DEST)).unwrap(),
Path::new(TEST_HELLO_WORLD_SOURCE)
);
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

// Recursively copying a tree that contains a symlink must not run chmod through
Expand Down
Loading