diff --git a/crates/test-programs/wasi-tests/src/bin/path_filestat.rs b/crates/test-programs/wasi-tests/src/bin/path_filestat.rs index 691fc7b97f..efcc6a46fa 100644 --- a/crates/test-programs/wasi-tests/src/bin/path_filestat.rs +++ b/crates/test-programs/wasi-tests/src/bin/path_filestat.rs @@ -46,17 +46,17 @@ unsafe fn test_path_filestat(dir_fd: wasi::Fd) { ); // Check file size - let mut stat = wasi::path_filestat_get(dir_fd, 0, "file").expect("reading file stats"); - assert_eq!(stat.size, 0, "file size should be 0"); + let file_stat = wasi::path_filestat_get(dir_fd, 0, "file").expect("reading file stats"); + assert_eq!(file_stat.size, 0, "file size should be 0"); // Check path_filestat_set_times - let new_mtim = stat.mtim - 100; + let new_mtim = file_stat.mtim - 100; wasi::path_filestat_set_times(dir_fd, 0, "file", 0, new_mtim, wasi::FSTFLAGS_MTIM) .expect("path_filestat_set_times should succeed"); - stat = wasi::path_filestat_get(dir_fd, 0, "file") + let modified_file_stat = wasi::path_filestat_get(dir_fd, 0, "file") .expect("reading file stats after path_filestat_set_times"); - assert_eq!(stat.mtim, new_mtim, "mtim should change"); + assert_eq!(modified_file_stat.mtim, new_mtim, "mtim should change"); assert_eq!( wasi::path_filestat_set_times( @@ -74,10 +74,14 @@ unsafe fn test_path_filestat(dir_fd: wasi::Fd) { ); // check if the times were untouched - stat = wasi::path_filestat_get(dir_fd, 0, "file") + let unmodified_file_stat = wasi::path_filestat_get(dir_fd, 0, "file") .expect("reading file stats after ERRNO_INVAL fd_filestat_set_times"); - assert_eq!(stat.mtim, new_mtim, "mtim should not change"); + assert_eq!( + unmodified_file_stat.mtim, new_mtim, + "mtim should not change" + ); + // Invalid arguments to set_times: assert_eq!( wasi::path_filestat_set_times( dir_fd, @@ -93,46 +97,8 @@ unsafe fn test_path_filestat(dir_fd: wasi::Fd) { "errno should be ERRNO_INVAL" ); - // Create a symlink - wasi::path_symlink("file", dir_fd, "symlink").expect("creating symlink to a file"); - - // Check path_filestat_set_times on the symlink itself - let mut sym_stat = wasi::path_filestat_get(dir_fd, 0, "file").expect("reading file stats"); - - let sym_new_mtim = sym_stat.mtim - 200; - wasi::path_filestat_set_times(dir_fd, 0, "symlink", 0, sym_new_mtim, wasi::FSTFLAGS_MTIM) - .expect("path_filestat_set_times should succeed on symlink"); - - sym_stat = wasi::path_filestat_get(dir_fd, 0, "symlink") - .expect("reading file stats after path_filestat_set_times"); - assert_eq!(sym_stat.mtim, sym_new_mtim, "mtim should change"); - - // Now, dereference the symlink - sym_stat = wasi::path_filestat_get(dir_fd, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, "symlink") - .expect("reading file stats on the dereferenced symlink"); - assert_eq!( - sym_stat.mtim, stat.mtim, - "symlink mtim should be equal to pointee's when dereferenced" - ); - - // Finally, change stat of the original file by dereferencing the symlink - wasi::path_filestat_set_times( - dir_fd, - wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, - "symlink", - 0, - sym_stat.mtim, - wasi::FSTFLAGS_MTIM, - ) - .expect("path_filestat_set_times should succeed on setting stat on original file"); - - stat = wasi::path_filestat_get(dir_fd, 0, "file") - .expect("reading file stats after path_filestat_set_times"); - assert_eq!(stat.mtim, sym_stat.mtim, "mtim should change"); - wasi::fd_close(file_fd).expect("closing a file"); wasi::path_unlink_file(dir_fd, "file").expect("removing a file"); - wasi::path_unlink_file(dir_fd, "symlink").expect("removing a symlink"); } fn main() { let mut args = env::args(); diff --git a/crates/test-programs/wasi-tests/src/bin/symlink_filestat.rs b/crates/test-programs/wasi-tests/src/bin/symlink_filestat.rs new file mode 100644 index 0000000000..52e3116a77 --- /dev/null +++ b/crates/test-programs/wasi-tests/src/bin/symlink_filestat.rs @@ -0,0 +1,99 @@ +use more_asserts::assert_gt; +use std::{env, process}; +use wasi_tests::open_scratch_directory; + +unsafe fn test_path_filestat(dir_fd: wasi::Fd) { + let mut fdstat = wasi::fd_fdstat_get(dir_fd).expect("fd_fdstat_get"); + assert_ne!( + fdstat.fs_rights_base & wasi::RIGHTS_PATH_FILESTAT_GET, + 0, + "the scratch directory should have RIGHT_PATH_FILESTAT_GET as base right", + ); + + // Create a file in the scratch directory. + let file_fd = wasi::path_open( + dir_fd, + 0, + "file", + wasi::OFLAGS_CREAT, + wasi::RIGHTS_FD_READ | wasi::RIGHTS_FD_WRITE | wasi::RIGHTS_PATH_FILESTAT_GET, + 0, + 0, + ) + .expect("opening a file"); + assert_gt!( + file_fd, + libc::STDERR_FILENO as wasi::Fd, + "file descriptor range check", + ); + + // Check file size + let file_stat = wasi::path_filestat_get(dir_fd, 0, "file").expect("reading file stats"); + assert_eq!(file_stat.size, 0, "file size should be 0"); + + // Create a symlink + wasi::path_symlink("file", dir_fd, "symlink").expect("creating symlink to a file"); + + // Check path_filestat_set_times on the symlink itself + let sym_stat = wasi::path_filestat_get(dir_fd, 0, "symlink").expect("reading symlink stats"); + + // Modify mtim of symlink + let sym_new_mtim = sym_stat.mtim - 200; + wasi::path_filestat_set_times(dir_fd, 0, "symlink", 0, sym_new_mtim, wasi::FSTFLAGS_MTIM) + .expect("path_filestat_set_times should succeed on symlink"); + + // Check that mtim motification worked + let modified_sym_stat = wasi::path_filestat_get(dir_fd, 0, "symlink") + .expect("reading file stats after path_filestat_set_times"); + assert_eq!(modified_sym_stat.mtim, sym_new_mtim, "mtim should change"); + + // Now, dereference the symlink + let deref_sym_stat = + wasi::path_filestat_get(dir_fd, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, "symlink") + .expect("reading file stats on the dereferenced symlink"); + assert_eq!( + deref_sym_stat.mtim, file_stat.mtim, + "symlink mtim should be equal to pointee's when dereferenced" + ); + + // Finally, change stat of the original file by dereferencing the symlink + wasi::path_filestat_set_times( + dir_fd, + wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, + "symlink", + 0, + sym_stat.mtim, + wasi::FSTFLAGS_MTIM, + ) + .expect("path_filestat_set_times should succeed on setting stat on original file"); + + let new_file_stat = wasi::path_filestat_get(dir_fd, 0, "file") + .expect("reading file stats after path_filestat_set_times"); + assert_eq!(new_file_stat.mtim, sym_stat.mtim, "mtim should change"); + + wasi::fd_close(file_fd).expect("closing a file"); + wasi::path_unlink_file(dir_fd, "symlink").expect("removing a symlink"); + wasi::path_unlink_file(dir_fd, "file").expect("removing a file"); +} +fn main() { + let mut args = env::args(); + let prog = args.next().unwrap(); + let arg = if let Some(arg) = args.next() { + arg + } else { + eprintln!("usage: {} ", prog); + process::exit(1); + }; + + // Open scratch directory + let dir_fd = match open_scratch_directory(&arg) { + Ok(dir_fd) => dir_fd, + Err(err) => { + eprintln!("{}", err); + process::exit(1) + } + }; + + // Run the tests. + unsafe { test_path_filestat(dir_fd) } +}