Merge wasi-common into wasmtime
This commit merges [CraneStation/wasi-common] repo as a subdir of this repo while preserving **all** of git history. There is an initiative to pull `wasi-common` into [CraneStation/wasmtime], and [CraneStation/wasmtime] becoming a monorepo. This came about for several reasons with a common theme of convenience, namely, having a monorepo: 1. cleans up the problem of dependencies (as we have seen first hand with dependabot enabled, it can cause some grief) 2. completely removes the problem of syncing the closely dependent repos (e.g., updating `wasi-common` with say a bugfix generally implies creating a "sync" commit for pulling in the changes into the "parent" repo, in this case, `wasmtime`) 3. mainly for the two reasons above, makes publishing to crates.io easier 4. hopefully streamlines the process of getting the community involved in contributing to `wasi-common` as now everything is one place [CraneStation/wasi-common]: https://github.com/CraneStation/wasi-common [CraneStation/wasmtime]: https://github.com/CraneStation/wasmtime
This commit is contained in:
18
wasi-common/wasi-misc-tests/src/bin/big_random_buf.rs
Normal file
18
wasi-common/wasi-misc-tests/src/bin/big_random_buf.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
use wasi::wasi_unstable;
|
||||
|
||||
fn test_big_random_buf() {
|
||||
let mut buf = Vec::new();
|
||||
buf.resize(1024, 0);
|
||||
assert!(
|
||||
wasi_unstable::random_get(&mut buf).is_ok(),
|
||||
"calling get_random on a large buffer"
|
||||
);
|
||||
// Chances are pretty good that at least *one* byte will be non-zero in
|
||||
// any meaningful random function producing 1024 u8 values.
|
||||
assert!(buf.iter().any(|x| *x != 0), "random_get returned all zeros");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Run the tests.
|
||||
test_big_random_buf()
|
||||
}
|
||||
37
wasi-common/wasi-misc-tests/src/bin/clock_time_get.rs
Normal file
37
wasi-common/wasi-misc-tests/src/bin/clock_time_get.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use more_asserts::assert_le;
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_clock_time_get;
|
||||
|
||||
unsafe fn test_clock_time_get() {
|
||||
// Test that clock_time_get succeeds. Even in environments where it's not
|
||||
// desirable to expose high-precision timers, it should still succeed.
|
||||
// clock_res_get is where information about precision can be provided.
|
||||
let mut time: wasi_unstable::Timestamp = 0;
|
||||
let status = wasi_clock_time_get(wasi_unstable::CLOCK_MONOTONIC, 1, &mut time);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"clock_time_get with a precision of 1"
|
||||
);
|
||||
|
||||
let status = wasi_clock_time_get(wasi_unstable::CLOCK_MONOTONIC, 0, &mut time);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"clock_time_get with a precision of 0"
|
||||
);
|
||||
let first_time = time;
|
||||
|
||||
let status = wasi_clock_time_get(wasi_unstable::CLOCK_MONOTONIC, 0, &mut time);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"clock_time_get with a precision of 0"
|
||||
);
|
||||
assert_le!(first_time, time, "CLOCK_MONOTONIC should be monotonic");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Run the tests.
|
||||
unsafe { test_clock_time_get() }
|
||||
}
|
||||
83
wasi-common/wasi-misc-tests/src/bin/close_preopen.rs
Normal file
83
wasi-common/wasi-misc-tests/src/bin/close_preopen.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, mem, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_fd_fdstat_get;
|
||||
|
||||
unsafe fn test_close_preopen(dir_fd: wasi_unstable::Fd) {
|
||||
let pre_fd: wasi_unstable::Fd = (libc::STDERR_FILENO + 1) as wasi_unstable::Fd;
|
||||
|
||||
assert_gt!(dir_fd, pre_fd, "dir_fd number");
|
||||
|
||||
// Try to close a preopened directory handle.
|
||||
assert_eq!(
|
||||
wasi_unstable::fd_close(pre_fd),
|
||||
Err(wasi_unstable::ENOTSUP),
|
||||
"closing a preopened file descriptor",
|
||||
);
|
||||
|
||||
// Try to renumber over a preopened directory handle.
|
||||
assert_eq!(
|
||||
wasi_unstable::fd_renumber(dir_fd, pre_fd),
|
||||
Err(wasi_unstable::ENOTSUP),
|
||||
"renumbering over a preopened file descriptor",
|
||||
);
|
||||
|
||||
// Ensure that dir_fd is still open.
|
||||
let mut dir_fdstat: wasi_unstable::FdStat = mem::zeroed();
|
||||
let mut status = wasi_fd_fdstat_get(dir_fd, &mut dir_fdstat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"calling fd_fdstat on the scratch directory"
|
||||
);
|
||||
assert_eq!(
|
||||
dir_fdstat.fs_filetype,
|
||||
wasi_unstable::FILETYPE_DIRECTORY,
|
||||
"expected the scratch directory to be a directory",
|
||||
);
|
||||
|
||||
// Try to renumber a preopened directory handle.
|
||||
assert_eq!(
|
||||
wasi_unstable::fd_renumber(pre_fd, dir_fd),
|
||||
Err(wasi_unstable::ENOTSUP),
|
||||
"renumbering over a preopened file descriptor",
|
||||
);
|
||||
|
||||
// Ensure that dir_fd is still open.
|
||||
status = wasi_fd_fdstat_get(dir_fd, &mut dir_fdstat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"calling fd_fdstat on the scratch directory"
|
||||
);
|
||||
assert_eq!(
|
||||
dir_fdstat.fs_filetype,
|
||||
wasi_unstable::FILETYPE_DIRECTORY,
|
||||
"expected the scratch directory to be a directory",
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_close_preopen(dir_fd) }
|
||||
}
|
||||
62
wasi-common/wasi-misc-tests/src/bin/dangling_symlink.rs
Normal file
62
wasi-common/wasi-misc-tests/src/bin/dangling_symlink.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::cleanup_file;
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_path_open, wasi_path_symlink};
|
||||
|
||||
unsafe fn test_dangling_symlink(dir_fd: wasi_unstable::Fd) {
|
||||
// First create a dangling symlink.
|
||||
assert!(
|
||||
wasi_path_symlink("target", dir_fd, "symlink").is_ok(),
|
||||
"creating a symlink"
|
||||
);
|
||||
|
||||
// Try to open it as a directory with O_NOFOLLOW.
|
||||
let mut file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"symlink",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ELOOP,
|
||||
"opening a dangling symlink as a directory",
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Clean up.
|
||||
cleanup_file(dir_fd, "symlink");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_dangling_symlink(dir_fd) }
|
||||
}
|
||||
90
wasi-common/wasi-misc-tests/src/bin/directory_seek.rs
Normal file
90
wasi-common/wasi-misc-tests/src/bin/directory_seek.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, mem, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_dir, close_fd, create_dir};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_fdstat_get, wasi_fd_seek, wasi_path_open};
|
||||
|
||||
unsafe fn test_directory_seek(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a directory in the scratch directory.
|
||||
create_dir(dir_fd, "dir");
|
||||
|
||||
// Open the directory and attempt to request rights for seeking.
|
||||
let mut fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"dir",
|
||||
0,
|
||||
wasi_unstable::RIGHT_FD_SEEK,
|
||||
0,
|
||||
0,
|
||||
&mut fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Attempt to seek.
|
||||
let mut newoffset = 1;
|
||||
status = wasi_fd_seek(fd, 0, wasi_unstable::WHENCE_CUR, &mut newoffset);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTCAPABLE,
|
||||
"seek on a directory"
|
||||
);
|
||||
|
||||
// Check if we obtained the right to seek.
|
||||
let mut fdstat: wasi_unstable::FdStat = mem::zeroed();
|
||||
status = wasi_fd_fdstat_get(fd, &mut fdstat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"calling fd_fdstat on a directory"
|
||||
);
|
||||
assert_eq!(
|
||||
fdstat.fs_filetype,
|
||||
wasi_unstable::FILETYPE_DIRECTORY,
|
||||
"expected the scratch directory to be a directory",
|
||||
);
|
||||
assert_eq!(
|
||||
(fdstat.fs_rights_base & wasi_unstable::RIGHT_FD_SEEK),
|
||||
0,
|
||||
"directory has the seek right",
|
||||
);
|
||||
|
||||
// Clean up.
|
||||
close_fd(fd);
|
||||
cleanup_dir(dir_fd, "dir");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_directory_seek(dir_fd) }
|
||||
}
|
||||
98
wasi-common/wasi-misc-tests/src/bin/fd_advise.rs
Normal file
98
wasi-common/wasi-misc-tests/src/bin/fd_advise.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_advise, wasi_fd_filestat_get, wasi_path_open};
|
||||
|
||||
unsafe fn test_fd_advise(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Check file size
|
||||
let mut stat = wasi_unstable::FileStat {
|
||||
st_dev: 0,
|
||||
st_ino: 0,
|
||||
st_filetype: 0,
|
||||
st_nlink: 0,
|
||||
st_size: 0,
|
||||
st_atim: 0,
|
||||
st_mtim: 0,
|
||||
st_ctim: 0,
|
||||
};
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats"
|
||||
);
|
||||
assert_eq!(stat.st_size, 0, "file size should be 0");
|
||||
|
||||
// Allocate some size
|
||||
assert!(
|
||||
wasi_unstable::fd_allocate(file_fd, 0, 100).is_ok(),
|
||||
"allocating size"
|
||||
);
|
||||
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after initial allocation"
|
||||
);
|
||||
assert_eq!(stat.st_size, 100, "file size should be 100");
|
||||
|
||||
// Advise the kernel
|
||||
let status = wasi_fd_advise(file_fd, 10, 50, wasi_unstable::ADVICE_NORMAL);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"advising the kernel"
|
||||
);
|
||||
|
||||
close_fd(file_fd);
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_fd_advise(dir_fd) }
|
||||
}
|
||||
120
wasi-common/wasi-misc-tests/src/bin/fd_filestat_set.rs
Normal file
120
wasi-common/wasi-misc-tests/src/bin/fd_filestat_set.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_filestat_get, wasi_path_open};
|
||||
|
||||
unsafe fn test_fd_filestat_set(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Check file size
|
||||
let mut stat = wasi_unstable::FileStat {
|
||||
st_dev: 0,
|
||||
st_ino: 0,
|
||||
st_filetype: 0,
|
||||
st_nlink: 0,
|
||||
st_size: 0,
|
||||
st_atim: 0,
|
||||
st_mtim: 0,
|
||||
st_ctim: 0,
|
||||
};
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats"
|
||||
);
|
||||
assert_eq!(stat.st_size, 0, "file size should be 0");
|
||||
|
||||
// Check fd_filestat_set_size
|
||||
assert!(
|
||||
wasi_unstable::fd_filestat_set_size(file_fd, 100).is_ok(),
|
||||
"fd_filestat_set_size"
|
||||
);
|
||||
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after fd_filestat_set_size"
|
||||
);
|
||||
assert_eq!(stat.st_size, 100, "file size should be 100");
|
||||
|
||||
// Check fd_filestat_set_times
|
||||
let old_atim = stat.st_atim;
|
||||
let new_mtim = stat.st_mtim - 100;
|
||||
assert!(
|
||||
wasi_unstable::fd_filestat_set_times(
|
||||
file_fd,
|
||||
new_mtim,
|
||||
new_mtim,
|
||||
wasi_unstable::FILESTAT_SET_MTIM,
|
||||
)
|
||||
.is_ok(),
|
||||
"fd_filestat_set_times"
|
||||
);
|
||||
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after fd_filestat_set_times"
|
||||
);
|
||||
assert_eq!(
|
||||
stat.st_size, 100,
|
||||
"file size should remain unchanged at 100"
|
||||
);
|
||||
assert_eq!(stat.st_mtim, new_mtim, "mtim should change");
|
||||
assert_eq!(stat.st_atim, old_atim, "atim should not change");
|
||||
|
||||
// let status = wasi_fd_filestat_set_times(file_fd, new_mtim, new_mtim, wasi_unstable::FILESTAT_SET_MTIM | wasi_unstable::FILESTAT_SET_MTIM_NOW);
|
||||
// assert_eq!(status, wasi_unstable::EINVAL, "ATIM & ATIM_NOW can't both be set");
|
||||
|
||||
close_fd(file_fd);
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_fd_filestat_set(dir_fd) }
|
||||
}
|
||||
189
wasi-common/wasi-misc-tests/src/bin/fd_readdir.rs
Normal file
189
wasi-common/wasi-misc-tests/src/bin/fd_readdir.rs
Normal file
@@ -0,0 +1,189 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{cmp::min, env, mem, process, slice, str};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_filestat_get, wasi_fd_readdir, wasi_path_open};
|
||||
|
||||
const BUF_LEN: usize = 256;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DirEntry {
|
||||
dirent: wasi_unstable::Dirent,
|
||||
name: String,
|
||||
}
|
||||
|
||||
// Manually reading the output from fd_readdir is tedious and repetitive,
|
||||
// so encapsulate it into an iterator
|
||||
struct ReadDir<'a> {
|
||||
buf: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> ReadDir<'a> {
|
||||
fn from_slice(buf: &'a [u8]) -> Self {
|
||||
Self { buf }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ReadDir<'a> {
|
||||
type Item = DirEntry;
|
||||
|
||||
fn next(&mut self) -> Option<DirEntry> {
|
||||
unsafe {
|
||||
if self.buf.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Read the data
|
||||
let dirent_ptr = self.buf.as_ptr() as *const wasi_unstable::Dirent;
|
||||
let dirent = *dirent_ptr;
|
||||
let name_ptr = dirent_ptr.offset(1) as *const u8;
|
||||
// NOTE Linux syscall returns a NULL-terminated name, but WASI doesn't
|
||||
let namelen = dirent.d_namlen as usize;
|
||||
let slice = slice::from_raw_parts(name_ptr, namelen);
|
||||
let name = str::from_utf8(slice).expect("invalid utf8").to_owned();
|
||||
|
||||
// Update the internal state
|
||||
let delta = mem::size_of_val(&dirent) + namelen;
|
||||
self.buf = &self.buf[delta..];
|
||||
|
||||
DirEntry { dirent, name }.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn exec_fd_readdir(
|
||||
fd: wasi_unstable::Fd,
|
||||
cookie: wasi_unstable::DirCookie,
|
||||
) -> Vec<DirEntry> {
|
||||
let mut buf: [u8; BUF_LEN] = [0; BUF_LEN];
|
||||
let mut bufused = 0;
|
||||
let status = wasi_fd_readdir(fd, &mut buf, BUF_LEN, cookie, &mut bufused);
|
||||
assert_eq!(status, wasi_unstable::raw::__WASI_ESUCCESS, "fd_readdir");
|
||||
|
||||
let sl = slice::from_raw_parts(buf.as_ptr(), min(BUF_LEN, bufused));
|
||||
let dirs: Vec<_> = ReadDir::from_slice(sl).collect();
|
||||
dirs
|
||||
}
|
||||
|
||||
unsafe fn test_fd_readdir(dir_fd: wasi_unstable::Fd) {
|
||||
let mut stat: wasi_unstable::FileStat = mem::zeroed();
|
||||
let status = wasi_fd_filestat_get(dir_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading scratch directory stats"
|
||||
);
|
||||
|
||||
// Check the behavior in an empty directory
|
||||
let mut dirs = exec_fd_readdir(dir_fd, wasi_unstable::DIRCOOKIE_START);
|
||||
dirs.sort_by_key(|d| d.name.clone());
|
||||
assert_eq!(dirs.len(), 2, "expected two entries in an empty directory");
|
||||
let mut dirs = dirs.into_iter();
|
||||
|
||||
// the first entry should be `.`
|
||||
let dir = dirs.next().expect("first entry is None");
|
||||
assert_eq!(dir.name, ".", "first name");
|
||||
assert_eq!(
|
||||
dir.dirent.d_type,
|
||||
wasi_unstable::FILETYPE_DIRECTORY,
|
||||
"first type"
|
||||
);
|
||||
assert_eq!(dir.dirent.d_ino, stat.st_ino);
|
||||
assert_eq!(dir.dirent.d_namlen, 1);
|
||||
|
||||
// the second entry should be `..`
|
||||
let dir = dirs.next().expect("second entry is None");
|
||||
assert_eq!(dir.name, "..", "second name");
|
||||
assert_eq!(
|
||||
dir.dirent.d_type,
|
||||
wasi_unstable::FILETYPE_DIRECTORY,
|
||||
"second type"
|
||||
);
|
||||
|
||||
assert!(
|
||||
dirs.next().is_none(),
|
||||
"the directory should be seen as empty"
|
||||
);
|
||||
|
||||
// Add a file and check the behavior
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats"
|
||||
);
|
||||
|
||||
// Execute another readdir
|
||||
let mut dirs = exec_fd_readdir(dir_fd, wasi_unstable::DIRCOOKIE_START);
|
||||
assert_eq!(dirs.len(), 3, "expected three entries");
|
||||
// Save the data about the last entry. We need to do it before sorting.
|
||||
let lastfile_cookie = dirs[1].dirent.d_next;
|
||||
let lastfile_name = dirs[2].name.clone();
|
||||
dirs.sort_by_key(|d| d.name.clone());
|
||||
let mut dirs = dirs.into_iter();
|
||||
|
||||
let dir = dirs.next().expect("first entry is None");
|
||||
assert_eq!(dir.name, ".", "first name");
|
||||
let dir = dirs.next().expect("second entry is None");
|
||||
assert_eq!(dir.name, "..", "second name");
|
||||
let dir = dirs.next().expect("third entry is None");
|
||||
// check the file info
|
||||
assert_eq!(dir.name, "file", "file name doesn't match");
|
||||
assert_eq!(
|
||||
dir.dirent.d_type,
|
||||
wasi_unstable::FILETYPE_REGULAR_FILE,
|
||||
"type for the real file"
|
||||
);
|
||||
assert_eq!(dir.dirent.d_ino, stat.st_ino);
|
||||
|
||||
// check if cookie works as expected
|
||||
let dirs = exec_fd_readdir(dir_fd, lastfile_cookie);
|
||||
assert_eq!(dirs.len(), 1, "expected one entry");
|
||||
assert_eq!(dirs[0].name, lastfile_name, "name of the only entry");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_fd_readdir(dir_fd) }
|
||||
}
|
||||
125
wasi-common/wasi-misc-tests/src/bin/file_allocate.rs
Normal file
125
wasi-common/wasi-misc-tests/src/bin/file_allocate.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_filestat_get, wasi_path_open};
|
||||
|
||||
unsafe fn test_file_allocate(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Check file size
|
||||
let mut stat = wasi_unstable::FileStat {
|
||||
st_dev: 0,
|
||||
st_ino: 0,
|
||||
st_filetype: 0,
|
||||
st_nlink: 0,
|
||||
st_size: 0,
|
||||
st_atim: 0,
|
||||
st_mtim: 0,
|
||||
st_ctim: 0,
|
||||
};
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats"
|
||||
);
|
||||
assert_eq!(stat.st_size, 0, "file size should be 0");
|
||||
|
||||
// Allocate some size
|
||||
assert!(
|
||||
wasi_unstable::fd_allocate(file_fd, 0, 100).is_ok(),
|
||||
"allocating size"
|
||||
);
|
||||
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after initial allocation"
|
||||
);
|
||||
assert_eq!(stat.st_size, 100, "file size should be 100");
|
||||
|
||||
// Allocate should not modify if less than current size
|
||||
assert!(
|
||||
wasi_unstable::fd_allocate(file_fd, 10, 10).is_ok(),
|
||||
"allocating size less than current size"
|
||||
);
|
||||
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after additional allocation was not required"
|
||||
);
|
||||
assert_eq!(
|
||||
stat.st_size, 100,
|
||||
"file size should remain unchanged at 100"
|
||||
);
|
||||
|
||||
// Allocate should modify if offset+len > current_len
|
||||
assert!(
|
||||
wasi_unstable::fd_allocate(file_fd, 90, 20).is_ok(),
|
||||
"allocating size larger than current size"
|
||||
);
|
||||
|
||||
let status = wasi_fd_filestat_get(file_fd, &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after additional allocation was required"
|
||||
);
|
||||
assert_eq!(
|
||||
stat.st_size, 110,
|
||||
"file size should increase from 100 to 110"
|
||||
);
|
||||
|
||||
close_fd(file_fd);
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_file_allocate(dir_fd) }
|
||||
}
|
||||
131
wasi-common/wasi-misc-tests/src/bin/file_pread_pwrite.rs
Normal file
131
wasi-common/wasi-misc-tests/src/bin/file_pread_pwrite.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_pread, wasi_fd_pwrite, wasi_path_open};
|
||||
|
||||
unsafe fn test_file_pread_pwrite(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
let contents = &[0u8, 1, 2, 3];
|
||||
let ciovec = wasi_unstable::CIoVec {
|
||||
buf: contents.as_ptr() as *const libc::c_void,
|
||||
buf_len: contents.len(),
|
||||
};
|
||||
let mut nwritten = 0;
|
||||
status = wasi_fd_pwrite(file_fd, &mut [ciovec], 0, &mut nwritten);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"writing bytes at offset 0"
|
||||
);
|
||||
assert_eq!(nwritten, 4, "nwritten bytes check");
|
||||
|
||||
let contents = &mut [0u8; 4];
|
||||
let iovec = wasi_unstable::IoVec {
|
||||
buf: contents.as_mut_ptr() as *mut libc::c_void,
|
||||
buf_len: contents.len(),
|
||||
};
|
||||
let mut nread = 0;
|
||||
status = wasi_fd_pread(file_fd, &[iovec], 0, &mut nread);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading bytes at offset 0"
|
||||
);
|
||||
assert_eq!(nread, 4, "nread bytes check");
|
||||
assert_eq!(contents, &[0u8, 1, 2, 3], "written bytes equal read bytes");
|
||||
|
||||
let contents = &mut [0u8; 4];
|
||||
let iovec = wasi_unstable::IoVec {
|
||||
buf: contents.as_mut_ptr() as *mut libc::c_void,
|
||||
buf_len: contents.len(),
|
||||
};
|
||||
let mut nread = 0;
|
||||
status = wasi_fd_pread(file_fd, &[iovec], 2, &mut nread);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading bytes at offset 2"
|
||||
);
|
||||
assert_eq!(nread, 2, "nread bytes check");
|
||||
assert_eq!(contents, &[2u8, 3, 0, 0], "file cursor was overwritten");
|
||||
|
||||
let contents = &[1u8, 0];
|
||||
let ciovec = wasi_unstable::CIoVec {
|
||||
buf: contents.as_ptr() as *const libc::c_void,
|
||||
buf_len: contents.len(),
|
||||
};
|
||||
let mut nwritten = 0;
|
||||
status = wasi_fd_pwrite(file_fd, &mut [ciovec], 2, &mut nwritten);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"writing bytes at offset 2"
|
||||
);
|
||||
assert_eq!(nwritten, 2, "nwritten bytes check");
|
||||
|
||||
let contents = &mut [0u8; 4];
|
||||
let iovec = wasi_unstable::IoVec {
|
||||
buf: contents.as_mut_ptr() as *mut libc::c_void,
|
||||
buf_len: contents.len(),
|
||||
};
|
||||
let mut nread = 0;
|
||||
status = wasi_fd_pread(file_fd, &[iovec], 0, &mut nread);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading bytes at offset 0"
|
||||
);
|
||||
assert_eq!(nread, 4, "nread bytes check");
|
||||
assert_eq!(contents, &[0u8, 1, 1, 0], "file cursor was overwritten");
|
||||
|
||||
close_fd(file_fd);
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_file_pread_pwrite(dir_fd) }
|
||||
}
|
||||
133
wasi-common/wasi-misc-tests/src/bin/file_seek_tell.rs
Normal file
133
wasi-common/wasi-misc-tests/src/bin/file_seek_tell.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_seek, wasi_fd_tell, wasi_fd_write, wasi_path_open};
|
||||
|
||||
unsafe fn test_file_seek_tell(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Check current offset
|
||||
let mut offset: wasi_unstable::FileSize = 0;
|
||||
status = wasi_fd_tell(file_fd, &mut offset);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"getting initial file offset"
|
||||
);
|
||||
assert_eq!(offset, 0, "current offset should be 0");
|
||||
|
||||
// Write to file
|
||||
let buf = &[0u8; 100];
|
||||
let iov = wasi_unstable::CIoVec {
|
||||
buf: buf.as_ptr() as *const _,
|
||||
buf_len: buf.len(),
|
||||
};
|
||||
let iovs = &[iov];
|
||||
let mut nwritten = 0;
|
||||
status = wasi_fd_write(file_fd, iovs, &mut nwritten);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"writing to a file"
|
||||
);
|
||||
assert_eq!(nwritten, 100, "should write 100 bytes to file");
|
||||
|
||||
// Check current offset
|
||||
status = wasi_fd_tell(file_fd, &mut offset);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"getting file offset after writing"
|
||||
);
|
||||
assert_eq!(offset, 100, "offset after writing should be 100");
|
||||
|
||||
// Seek to middle of the file
|
||||
let mut newoffset = 1;
|
||||
status = wasi_fd_seek(file_fd, -50, wasi_unstable::WHENCE_CUR, &mut newoffset);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"seeking to the middle of a file"
|
||||
);
|
||||
assert_eq!(
|
||||
newoffset, 50,
|
||||
"offset after seeking to the middle should be at 50"
|
||||
);
|
||||
|
||||
// Seek to the beginning of the file
|
||||
status = wasi_fd_seek(file_fd, 0, wasi_unstable::WHENCE_SET, &mut newoffset);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"seeking to the beginning of the file"
|
||||
);
|
||||
assert_eq!(
|
||||
newoffset, 0,
|
||||
"offset after seeking to the beginning of the file should be at 0"
|
||||
);
|
||||
|
||||
// Seek beyond the file should be possible
|
||||
status = wasi_fd_seek(file_fd, 1000, wasi_unstable::WHENCE_CUR, &mut newoffset);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"seeking beyond the end of the file"
|
||||
);
|
||||
|
||||
// Seek before byte 0 is an error though
|
||||
status = wasi_fd_seek(file_fd, -2000, wasi_unstable::WHENCE_CUR, &mut newoffset);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_EINVAL,
|
||||
"seeking before byte 0 is an error"
|
||||
);
|
||||
|
||||
close_fd(file_fd);
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_file_seek_tell(dir_fd) }
|
||||
}
|
||||
116
wasi-common/wasi-misc-tests/src/bin/file_unbuffered_write.rs
Normal file
116
wasi-common/wasi-misc-tests/src/bin/file_unbuffered_write.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_read, wasi_fd_write, wasi_path_open};
|
||||
|
||||
unsafe fn test_file_unbuffered_write(dir_fd: wasi_unstable::Fd) {
|
||||
// Create file
|
||||
create_file(dir_fd, "file");
|
||||
|
||||
// Open file for reading
|
||||
let mut fd_read = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
0,
|
||||
wasi_unstable::RIGHT_FD_READ,
|
||||
0,
|
||||
0,
|
||||
&mut fd_read,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
fd_read,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Open the same file but for writing
|
||||
let mut fd_write = wasi_unstable::Fd::max_value() - 1;
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
0,
|
||||
wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut fd_write,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
fd_write,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Write to file
|
||||
let contents = &[1u8];
|
||||
let ciovec = wasi_unstable::CIoVec {
|
||||
buf: contents.as_ptr() as *const libc::c_void,
|
||||
buf_len: contents.len(),
|
||||
};
|
||||
let mut nwritten = 0;
|
||||
status = wasi_fd_write(fd_write, &[ciovec], &mut nwritten);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"writing byte to file"
|
||||
);
|
||||
assert_eq!(nwritten, 1, "nwritten bytes check");
|
||||
|
||||
// Read from file
|
||||
let contents = &mut [0u8; 1];
|
||||
let iovec = wasi_unstable::IoVec {
|
||||
buf: contents.as_mut_ptr() as *mut libc::c_void,
|
||||
buf_len: contents.len(),
|
||||
};
|
||||
let mut nread = 0;
|
||||
status = wasi_fd_read(fd_read, &[iovec], &mut nread);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading bytes from file"
|
||||
);
|
||||
assert_eq!(nread, 1, "nread bytes check");
|
||||
assert_eq!(contents, &[1u8], "written bytes equal read bytes");
|
||||
|
||||
// Clean up
|
||||
close_fd(fd_write);
|
||||
close_fd(fd_read);
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_file_unbuffered_write(dir_fd) }
|
||||
}
|
||||
173
wasi-common/wasi-misc-tests/src/bin/interesting_paths.rs
Normal file
173
wasi-common/wasi-misc-tests/src/bin/interesting_paths.rs
Normal file
@@ -0,0 +1,173 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{close_fd, create_dir, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::{
|
||||
wasi_path_open, wasi_path_remove_directory, wasi_path_unlink_file,
|
||||
};
|
||||
|
||||
unsafe fn test_interesting_paths(dir_fd: wasi_unstable::Fd, arg: &str) {
|
||||
// Create a directory in the scratch directory.
|
||||
create_dir(dir_fd, "dir");
|
||||
|
||||
// Create a directory in the directory we just created.
|
||||
create_dir(dir_fd, "dir/nested");
|
||||
|
||||
// Create a file in the nested directory.
|
||||
create_file(dir_fd, "dir/nested/file");
|
||||
|
||||
// Now open it with an absolute path.
|
||||
let mut file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(dir_fd, 0, "/dir/nested/file", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTCAPABLE,
|
||||
"opening a file with an absolute path"
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Now open it with a path containing "..".
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"dir/.//nested/../../dir/nested/../nested///./file",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file with \"..\" in the path"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
close_fd(file_fd);
|
||||
|
||||
// Now open it with a trailing NUL.
|
||||
status = wasi_path_open(dir_fd, 0, "dir/nested/file\0", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_EILSEQ,
|
||||
"opening a file with a trailing NUL"
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Now open it with a trailing slash.
|
||||
status = wasi_path_open(dir_fd, 0, "dir/nested/file/", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTDIR,
|
||||
"opening a file with a trailing slash"
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Now open it with trailing slashes.
|
||||
status = wasi_path_open(dir_fd, 0, "dir/nested/file///", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTDIR,
|
||||
"opening a file with trailing slashes"
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Now open the directory with a trailing slash.
|
||||
status = wasi_path_open(dir_fd, 0, "dir/nested/", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a directory with a trailing slash"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
close_fd(file_fd);
|
||||
|
||||
// Now open the directory with trailing slashes.
|
||||
status = wasi_path_open(dir_fd, 0, "dir/nested///", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a directory with trailing slashes"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
close_fd(file_fd);
|
||||
|
||||
// Now open it with a path containing too many ".."s.
|
||||
let bad_path = format!("dir/nested/../../../{}/dir/nested/file", arg);
|
||||
status = wasi_path_open(dir_fd, 0, &bad_path, 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTCAPABLE,
|
||||
"opening a file with too many \"..\"s in the path"
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
assert!(
|
||||
wasi_path_unlink_file(dir_fd, "dir/nested/file").is_ok(),
|
||||
"unlink_file on a symlink should succeed"
|
||||
);
|
||||
assert!(
|
||||
wasi_path_remove_directory(dir_fd, "dir/nested").is_ok(),
|
||||
"remove_directory on a directory should succeed"
|
||||
);
|
||||
assert!(
|
||||
wasi_path_remove_directory(dir_fd, "dir").is_ok(),
|
||||
"remove_directory on a directory should succeed"
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_interesting_paths(dir_fd, &arg) }
|
||||
}
|
||||
63
wasi-common/wasi-misc-tests/src/bin/isatty.rs
Normal file
63
wasi-common/wasi-misc-tests/src/bin/isatty.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd};
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_path_open;
|
||||
|
||||
unsafe fn test_isatty(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory and test if it's a tty.
|
||||
let mut file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
assert_eq!(
|
||||
libc::isatty(file_fd as std::os::raw::c_int),
|
||||
0,
|
||||
"file is a tty"
|
||||
);
|
||||
close_fd(file_fd);
|
||||
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_isatty(dir_fd) }
|
||||
}
|
||||
177
wasi-common/wasi-misc-tests/src/bin/nofollow_errors.rs
Normal file
177
wasi-common/wasi-misc-tests/src/bin/nofollow_errors.rs
Normal file
@@ -0,0 +1,177 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd, create_dir, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::{
|
||||
wasi_path_open, wasi_path_remove_directory, wasi_path_symlink,
|
||||
};
|
||||
|
||||
unsafe fn test_nofollow_errors(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a directory for the symlink to point to.
|
||||
create_dir(dir_fd, "target");
|
||||
|
||||
// Create a symlink.
|
||||
assert!(
|
||||
wasi_path_symlink("target", dir_fd, "symlink").is_ok(),
|
||||
"creating a symlink"
|
||||
);
|
||||
|
||||
// Try to open it as a directory with O_NOFOLLOW again.
|
||||
let mut file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"symlink",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ELOOP,
|
||||
"opening a directory symlink as a directory",
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Try to open it with just O_NOFOLLOW.
|
||||
status = wasi_path_open(dir_fd, 0, "symlink", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ELOOP,
|
||||
"opening a symlink with O_NOFOLLOW should return ELOOP",
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Try to open it as a directory without O_NOFOLLOW.
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
wasi_unstable::LOOKUP_SYMLINK_FOLLOW,
|
||||
"symlink",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a symlink as a directory"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
close_fd(file_fd);
|
||||
|
||||
// Replace the target directory with a file.
|
||||
cleanup_file(dir_fd, "symlink");
|
||||
|
||||
assert!(
|
||||
wasi_path_remove_directory(dir_fd, "target").is_ok(),
|
||||
"remove_directory on a directory should succeed"
|
||||
);
|
||||
create_file(dir_fd, "target");
|
||||
|
||||
assert!(
|
||||
wasi_path_symlink("target", dir_fd, "symlink").is_ok(),
|
||||
"creating a symlink"
|
||||
);
|
||||
|
||||
// Try to open it as a directory with O_NOFOLLOW again.
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"symlink",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ELOOP,
|
||||
"opening a directory symlink as a directory",
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Try to open it with just O_NOFOLLOW.
|
||||
status = wasi_path_open(dir_fd, 0, "symlink", 0, 0, 0, 0, &mut file_fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ELOOP,
|
||||
"opening a symlink with O_NOFOLLOW should return ELOOP",
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Try to open it as a directory without O_NOFOLLOW.
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
wasi_unstable::LOOKUP_SYMLINK_FOLLOW,
|
||||
"symlink",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTDIR,
|
||||
"opening a symlink to a file as a directory",
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Clean up.
|
||||
cleanup_file(dir_fd, "target");
|
||||
cleanup_file(dir_fd, "symlink");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_nofollow_errors(dir_fd) }
|
||||
}
|
||||
184
wasi-common/wasi-misc-tests/src/bin/path_filestat.rs
Normal file
184
wasi-common/wasi-misc-tests/src/bin/path_filestat.rs
Normal file
@@ -0,0 +1,184 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd};
|
||||
use wasi_misc_tests::wasi_wrappers::{
|
||||
wasi_fd_fdstat_get, wasi_path_filestat_get, wasi_path_filestat_set_times, wasi_path_open,
|
||||
};
|
||||
|
||||
unsafe fn test_path_filestat(dir_fd: wasi_unstable::Fd) {
|
||||
let mut fdstat: wasi_unstable::FdStat = std::mem::zeroed();
|
||||
let status = wasi_fd_fdstat_get(dir_fd, &mut fdstat);
|
||||
assert_eq!(status, wasi_unstable::raw::__WASI_ESUCCESS, "fd_fdstat_get");
|
||||
|
||||
assert_ne!(
|
||||
fdstat.fs_rights_base & wasi_unstable::RIGHT_PATH_FILESTAT_GET,
|
||||
0,
|
||||
"the scratch directory should have RIGHT_PATH_FILESTAT_GET as base right",
|
||||
);
|
||||
assert_ne!(
|
||||
fdstat.fs_rights_inheriting & wasi_unstable::RIGHT_PATH_FILESTAT_GET,
|
||||
0,
|
||||
"the scratch directory should have RIGHT_PATH_FILESTAT_GET as base right",
|
||||
);
|
||||
|
||||
// Create a file in the scratch directory.
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let filename = "file";
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
filename,
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ
|
||||
| wasi_unstable::RIGHT_FD_WRITE
|
||||
| wasi_unstable::RIGHT_PATH_FILESTAT_GET,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
let status = wasi_fd_fdstat_get(file_fd, &mut fdstat);
|
||||
assert_eq!(status, wasi_unstable::raw::__WASI_ESUCCESS, "fd_fdstat_get");
|
||||
|
||||
assert_eq!(
|
||||
fdstat.fs_rights_base & wasi_unstable::RIGHT_PATH_FILESTAT_GET,
|
||||
0,
|
||||
"files shouldn't have rights for path_* syscalls even if manually given",
|
||||
);
|
||||
assert_eq!(
|
||||
fdstat.fs_rights_inheriting & wasi_unstable::RIGHT_PATH_FILESTAT_GET,
|
||||
0,
|
||||
"files shouldn't have rights for path_* syscalls even if manually given",
|
||||
);
|
||||
|
||||
// Check file size
|
||||
let mut stat = wasi_unstable::FileStat {
|
||||
st_dev: 0,
|
||||
st_ino: 0,
|
||||
st_filetype: 0,
|
||||
st_nlink: 0,
|
||||
st_size: 0,
|
||||
st_atim: 0,
|
||||
st_mtim: 0,
|
||||
st_ctim: 0,
|
||||
};
|
||||
let status = wasi_path_filestat_get(dir_fd, 0, filename, filename.len(), &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats"
|
||||
);
|
||||
assert_eq!(stat.st_size, 0, "file size should be 0");
|
||||
|
||||
// Check path_filestat_set_times
|
||||
let old_atim = stat.st_atim;
|
||||
let new_mtim = stat.st_mtim - 100;
|
||||
assert!(
|
||||
wasi_path_filestat_set_times(
|
||||
dir_fd,
|
||||
0,
|
||||
filename,
|
||||
// on purpose: the syscall should not touch atim, because
|
||||
// neither of the ATIM flags is set
|
||||
new_mtim,
|
||||
new_mtim,
|
||||
wasi_unstable::FILESTAT_SET_MTIM,
|
||||
)
|
||||
.is_ok(),
|
||||
"path_filestat_set_times should succeed"
|
||||
);
|
||||
|
||||
let status = wasi_path_filestat_get(dir_fd, 0, filename, filename.len(), &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after path_filestat_set_times"
|
||||
);
|
||||
assert_eq!(stat.st_mtim, new_mtim, "mtim should change");
|
||||
assert_eq!(stat.st_atim, old_atim, "atim should not change");
|
||||
|
||||
assert_eq!(
|
||||
wasi_path_filestat_set_times(
|
||||
dir_fd,
|
||||
0,
|
||||
filename,
|
||||
new_mtim,
|
||||
new_mtim,
|
||||
wasi_unstable::FILESTAT_SET_MTIM | wasi_unstable::FILESTAT_SET_MTIM_NOW,
|
||||
),
|
||||
Err(wasi_unstable::EINVAL),
|
||||
"MTIM & MTIM_NOW can't both be set"
|
||||
);
|
||||
|
||||
// check if the times were untouched
|
||||
let status = wasi_path_filestat_get(dir_fd, 0, filename, filename.len(), &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after EINVAL fd_filestat_set_times"
|
||||
);
|
||||
assert_eq!(stat.st_mtim, new_mtim, "mtim should not change");
|
||||
assert_eq!(stat.st_atim, old_atim, "atim should not change");
|
||||
|
||||
let new_atim = old_atim - 100;
|
||||
assert_eq!(
|
||||
wasi_path_filestat_set_times(
|
||||
dir_fd,
|
||||
0,
|
||||
filename,
|
||||
new_atim,
|
||||
new_atim,
|
||||
wasi_unstable::FILESTAT_SET_ATIM | wasi_unstable::FILESTAT_SET_ATIM_NOW,
|
||||
),
|
||||
Err(wasi_unstable::EINVAL),
|
||||
"ATIM & ATIM_NOW can't both be set"
|
||||
);
|
||||
|
||||
// check if the times were untouched
|
||||
let status = wasi_path_filestat_get(dir_fd, 0, filename, filename.len(), &mut stat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading file stats after EINVAL path_filestat_set_times"
|
||||
);
|
||||
assert_eq!(stat.st_mtim, new_mtim, "mtim should not change");
|
||||
assert_eq!(stat.st_atim, old_atim, "atim should not change");
|
||||
|
||||
close_fd(file_fd);
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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) }
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::close_fd;
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_path_open;
|
||||
|
||||
unsafe fn test_dirfd_not_dir(dir_fd: wasi_unstable::Fd) {
|
||||
// Open a file.
|
||||
let mut file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
|
||||
// Now try to open a file underneath it as if it were a directory.
|
||||
let mut new_file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
status = wasi_path_open(
|
||||
file_fd,
|
||||
0,
|
||||
"foo",
|
||||
wasi_unstable::O_CREAT,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut new_file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTDIR,
|
||||
"non-directory base fd should get ENOTDIR"
|
||||
);
|
||||
close_fd(file_fd);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_dirfd_not_dir(dir_fd) }
|
||||
}
|
||||
259
wasi-common/wasi-misc-tests/src/bin/path_rename.rs
Normal file
259
wasi-common/wasi-misc-tests/src/bin/path_rename.rs
Normal file
@@ -0,0 +1,259 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_dir, cleanup_file, close_fd, create_dir, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_path_open, wasi_path_rename};
|
||||
|
||||
unsafe fn test_path_rename(dir_fd: wasi_unstable::Fd) {
|
||||
// First, try renaming a dir to nonexistent path
|
||||
// Create source directory
|
||||
create_dir(dir_fd, "source");
|
||||
|
||||
// Try renaming the directory
|
||||
assert!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target").is_ok(),
|
||||
"renaming a directory"
|
||||
);
|
||||
|
||||
// Check that source directory doesn't exist anymore
|
||||
let mut fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"source",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOENT,
|
||||
"opening a nonexistent path as a directory"
|
||||
);
|
||||
assert_eq!(
|
||||
fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Check that target directory exists
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"target",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening renamed path as a directory"
|
||||
);
|
||||
assert_gt!(
|
||||
fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
close_fd(fd);
|
||||
cleanup_dir(dir_fd, "target");
|
||||
|
||||
// Now, try renaming renaming a dir to existing empty dir
|
||||
create_dir(dir_fd, "source");
|
||||
create_dir(dir_fd, "target");
|
||||
|
||||
assert!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target").is_ok(),
|
||||
"renaming a directory"
|
||||
);
|
||||
|
||||
// Check that source directory doesn't exist anymore
|
||||
fd = wasi_unstable::Fd::max_value() - 1;
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"source",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOENT,
|
||||
"opening a nonexistent path as a directory"
|
||||
);
|
||||
assert_eq!(
|
||||
fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Check that target directory exists
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"target",
|
||||
wasi_unstable::O_DIRECTORY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening renamed path as a directory"
|
||||
);
|
||||
assert_gt!(
|
||||
fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
close_fd(fd);
|
||||
cleanup_dir(dir_fd, "target");
|
||||
|
||||
// Now, try renaming a dir to existing non-empty dir
|
||||
create_dir(dir_fd, "source");
|
||||
create_dir(dir_fd, "target");
|
||||
create_file(dir_fd, "target/file");
|
||||
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target"),
|
||||
Err(wasi_unstable::ENOTEMPTY),
|
||||
"renaming directory to a nonempty directory"
|
||||
);
|
||||
|
||||
// Try renaming dir to a file
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target/file"),
|
||||
Err(wasi_unstable::ENOTDIR),
|
||||
"renaming directory to a file"
|
||||
);
|
||||
|
||||
cleanup_file(dir_fd, "target/file");
|
||||
cleanup_dir(dir_fd, "target");
|
||||
cleanup_dir(dir_fd, "source");
|
||||
|
||||
// Now, try renaming a file to a nonexistent path
|
||||
create_file(dir_fd, "source");
|
||||
|
||||
assert!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target").is_ok(),
|
||||
"renaming a file"
|
||||
);
|
||||
|
||||
// Check that source file doesn't exist anymore
|
||||
fd = wasi_unstable::Fd::max_value() - 1;
|
||||
status = wasi_path_open(dir_fd, 0, "source", 0, 0, 0, 0, &mut fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOENT,
|
||||
"opening a nonexistent path"
|
||||
);
|
||||
assert_eq!(
|
||||
fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Check that target file exists
|
||||
status = wasi_path_open(dir_fd, 0, "target", 0, 0, 0, 0, &mut fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening renamed path"
|
||||
);
|
||||
assert_gt!(
|
||||
fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
close_fd(fd);
|
||||
cleanup_file(dir_fd, "target");
|
||||
|
||||
// Now, try renaming file to an existing file
|
||||
create_file(dir_fd, "source");
|
||||
create_file(dir_fd, "target");
|
||||
|
||||
assert!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target").is_ok(),
|
||||
"renaming file to another existing file"
|
||||
);
|
||||
|
||||
// Check that source file doesn't exist anymore
|
||||
fd = wasi_unstable::Fd::max_value() - 1;
|
||||
status = wasi_path_open(dir_fd, 0, "source", 0, 0, 0, 0, &mut fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOENT,
|
||||
"opening a nonexistent path"
|
||||
);
|
||||
assert_eq!(
|
||||
fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
|
||||
// Check that target file exists
|
||||
status = wasi_path_open(dir_fd, 0, "target", 0, 0, 0, 0, &mut fd);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening renamed path"
|
||||
);
|
||||
assert_gt!(
|
||||
fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
close_fd(fd);
|
||||
cleanup_file(dir_fd, "target");
|
||||
|
||||
// Try renaming to an (empty) directory instead
|
||||
create_file(dir_fd, "source");
|
||||
create_dir(dir_fd, "target");
|
||||
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target"),
|
||||
Err(wasi_unstable::EISDIR),
|
||||
"renaming file to existing directory"
|
||||
);
|
||||
|
||||
cleanup_dir(dir_fd, "target");
|
||||
cleanup_file(dir_fd, "source");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_rename(dir_fd) }
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_dir, cleanup_file, create_dir, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_path_rename;
|
||||
|
||||
unsafe fn test_path_rename_trailing_slashes(dir_fd: wasi_unstable::Fd) {
|
||||
// Test renaming a file with a trailing slash in the name.
|
||||
create_file(dir_fd, "source");
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source/", dir_fd, "target"),
|
||||
Err(wasi_unstable::ENOTDIR),
|
||||
"renaming a file with a trailing slash in the source name"
|
||||
);
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source", dir_fd, "target/"),
|
||||
Err(wasi_unstable::ENOTDIR),
|
||||
"renaming a file with a trailing slash in the destination name"
|
||||
);
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source/", dir_fd, "target/"),
|
||||
Err(wasi_unstable::ENOTDIR),
|
||||
"renaming a file with a trailing slash in the source and destination names"
|
||||
);
|
||||
cleanup_file(dir_fd, "source");
|
||||
|
||||
// Test renaming a directory with a trailing slash in the name.
|
||||
create_dir(dir_fd, "source");
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source/", dir_fd, "target"),
|
||||
Ok(()),
|
||||
"renaming a directory with a trailing slash in the source name"
|
||||
);
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "target", dir_fd, "source/"),
|
||||
Ok(()),
|
||||
"renaming a directory with a trailing slash in the destination name"
|
||||
);
|
||||
assert_eq!(
|
||||
wasi_path_rename(dir_fd, "source/", dir_fd, "target/"),
|
||||
Ok(()),
|
||||
"renaming a directory with a trailing slash in the source and destination names"
|
||||
);
|
||||
cleanup_dir(dir_fd, "target");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_rename_trailing_slashes(dir_fd) }
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_dir, cleanup_file, create_dir, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_path_symlink;
|
||||
|
||||
unsafe fn test_path_symlink_trailing_slashes(dir_fd: wasi_unstable::Fd) {
|
||||
// Link destination shouldn't end with a slash.
|
||||
assert_eq!(
|
||||
wasi_path_symlink("source", dir_fd, "target/"),
|
||||
Err(wasi_unstable::ENOENT),
|
||||
"link destination ending with a slash"
|
||||
);
|
||||
|
||||
// Without the trailing slash, this should succeed.
|
||||
assert_eq!(
|
||||
wasi_path_symlink("source", dir_fd, "target"),
|
||||
Ok(()),
|
||||
"link destination ending with a slash"
|
||||
);
|
||||
cleanup_file(dir_fd, "target");
|
||||
|
||||
// Link destination already exists, target has trailing slash.
|
||||
create_dir(dir_fd, "target");
|
||||
assert_eq!(
|
||||
wasi_path_symlink("source", dir_fd, "target/"),
|
||||
Err(wasi_unstable::EEXIST),
|
||||
"link destination already exists"
|
||||
);
|
||||
cleanup_dir(dir_fd, "target");
|
||||
|
||||
// Link destination already exists, target has no trailing slash.
|
||||
create_dir(dir_fd, "target");
|
||||
assert_eq!(
|
||||
wasi_path_symlink("source", dir_fd, "target"),
|
||||
Err(wasi_unstable::EEXIST),
|
||||
"link destination already exists"
|
||||
);
|
||||
cleanup_dir(dir_fd, "target");
|
||||
|
||||
// Link destination already exists, target has trailing slash.
|
||||
create_file(dir_fd, "target");
|
||||
assert_eq!(
|
||||
wasi_path_symlink("source", dir_fd, "target/"),
|
||||
Err(wasi_unstable::EEXIST),
|
||||
"link destination already exists"
|
||||
);
|
||||
cleanup_file(dir_fd, "target");
|
||||
|
||||
// Link destination already exists, target has no trailing slash.
|
||||
create_file(dir_fd, "target");
|
||||
assert_eq!(
|
||||
wasi_path_symlink("source", dir_fd, "target"),
|
||||
Err(wasi_unstable::EEXIST),
|
||||
"link destination already exists"
|
||||
);
|
||||
cleanup_file(dir_fd, "target");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_symlink_trailing_slashes(dir_fd) }
|
||||
}
|
||||
271
wasi-common/wasi-misc-tests/src/bin/poll_oneoff.rs
Normal file
271
wasi-common/wasi-misc-tests/src/bin/poll_oneoff.rs
Normal file
@@ -0,0 +1,271 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, mem::MaybeUninit, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::{
|
||||
open_scratch_directory,
|
||||
utils::{cleanup_file, close_fd},
|
||||
wasi_wrappers::wasi_path_open,
|
||||
};
|
||||
|
||||
const CLOCK_ID: wasi_unstable::Userdata = 0x0123_45678;
|
||||
|
||||
unsafe fn poll_oneoff_impl(
|
||||
in_: &[wasi_unstable::Subscription],
|
||||
nexpected: usize,
|
||||
) -> Vec<wasi_unstable::Event> {
|
||||
let mut out: Vec<wasi_unstable::Event> = Vec::new();
|
||||
out.resize_with(in_.len(), || {
|
||||
MaybeUninit::<wasi_unstable::Event>::zeroed().assume_init()
|
||||
});
|
||||
let res = wasi_unstable::poll_oneoff(&in_, out.as_mut_slice());
|
||||
let res = res.expect("poll_oneoff should succeed");
|
||||
assert_eq!(
|
||||
res, nexpected,
|
||||
"poll_oneoff should return {} events",
|
||||
nexpected
|
||||
);
|
||||
out
|
||||
}
|
||||
|
||||
unsafe fn test_timeout() {
|
||||
let clock = wasi_unstable::raw::__wasi_subscription_u_clock_t {
|
||||
identifier: CLOCK_ID,
|
||||
clock_id: wasi_unstable::CLOCK_MONOTONIC,
|
||||
timeout: 5_000_000u64, // 5 milliseconds
|
||||
precision: 0,
|
||||
flags: 0,
|
||||
};
|
||||
let in_ = [wasi_unstable::Subscription {
|
||||
userdata: CLOCK_ID,
|
||||
type_: wasi_unstable::EVENTTYPE_CLOCK,
|
||||
u: wasi_unstable::raw::__wasi_subscription_u { clock },
|
||||
}];
|
||||
let out = poll_oneoff_impl(&in_, 1);
|
||||
let event = &out[0];
|
||||
assert_eq!(
|
||||
event.userdata, CLOCK_ID,
|
||||
"the event.userdata should contain clock_id specified by the user"
|
||||
);
|
||||
assert_eq!(
|
||||
event.error,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"the event.error should be set to ESUCCESS"
|
||||
);
|
||||
assert_eq!(
|
||||
event.type_,
|
||||
wasi_unstable::EVENTTYPE_CLOCK,
|
||||
"the event.type_ should equal clock"
|
||||
);
|
||||
}
|
||||
|
||||
unsafe fn test_stdin_read() {
|
||||
let clock = wasi_unstable::raw::__wasi_subscription_u_clock_t {
|
||||
identifier: CLOCK_ID,
|
||||
clock_id: wasi_unstable::CLOCK_MONOTONIC,
|
||||
timeout: 5_000_000u64, // 5 milliseconds
|
||||
precision: 0,
|
||||
flags: 0,
|
||||
};
|
||||
let fd_readwrite = wasi_unstable::raw::__wasi_subscription_u_fd_readwrite_t {
|
||||
fd: wasi_unstable::STDIN_FD,
|
||||
};
|
||||
let in_ = [
|
||||
wasi_unstable::Subscription {
|
||||
userdata: CLOCK_ID,
|
||||
type_: wasi_unstable::EVENTTYPE_CLOCK,
|
||||
u: wasi_unstable::raw::__wasi_subscription_u { clock },
|
||||
},
|
||||
wasi_unstable::Subscription {
|
||||
userdata: 1,
|
||||
type_: wasi_unstable::EVENTTYPE_FD_READ,
|
||||
u: wasi_unstable::raw::__wasi_subscription_u { fd_readwrite },
|
||||
},
|
||||
];
|
||||
let out = poll_oneoff_impl(&in_, 1);
|
||||
let event = &out[0];
|
||||
assert_eq!(
|
||||
event.userdata, CLOCK_ID,
|
||||
"the event.userdata should contain clock_id specified by the user"
|
||||
);
|
||||
assert_eq!(
|
||||
event.error,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"the event.error should be set to ESUCCESS"
|
||||
);
|
||||
assert_eq!(
|
||||
event.type_,
|
||||
wasi_unstable::EVENTTYPE_CLOCK,
|
||||
"the event.type_ should equal clock"
|
||||
);
|
||||
}
|
||||
|
||||
unsafe fn test_stdout_stderr_write() {
|
||||
let stdout_readwrite = wasi_unstable::raw::__wasi_subscription_u_fd_readwrite_t {
|
||||
fd: wasi_unstable::STDOUT_FD,
|
||||
};
|
||||
let stderr_readwrite = wasi_unstable::raw::__wasi_subscription_u_fd_readwrite_t {
|
||||
fd: wasi_unstable::STDERR_FD,
|
||||
};
|
||||
let in_ = [
|
||||
wasi_unstable::Subscription {
|
||||
userdata: 1,
|
||||
type_: wasi_unstable::EVENTTYPE_FD_WRITE,
|
||||
u: wasi_unstable::raw::__wasi_subscription_u {
|
||||
fd_readwrite: stdout_readwrite,
|
||||
},
|
||||
},
|
||||
wasi_unstable::Subscription {
|
||||
userdata: 2,
|
||||
type_: wasi_unstable::EVENTTYPE_FD_WRITE,
|
||||
u: wasi_unstable::raw::__wasi_subscription_u {
|
||||
fd_readwrite: stderr_readwrite,
|
||||
},
|
||||
},
|
||||
];
|
||||
let out = poll_oneoff_impl(&in_, 2);
|
||||
assert_eq!(
|
||||
out[0].userdata, 1,
|
||||
"the event.userdata should contain fd userdata specified by the user"
|
||||
);
|
||||
assert_eq!(
|
||||
out[0].error,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"the event.error should be set to {}",
|
||||
wasi_unstable::raw::__WASI_ESUCCESS
|
||||
);
|
||||
assert_eq!(
|
||||
out[0].type_,
|
||||
wasi_unstable::EVENTTYPE_FD_WRITE,
|
||||
"the event.type_ should equal FD_WRITE"
|
||||
);
|
||||
assert_eq!(
|
||||
out[1].userdata, 2,
|
||||
"the event.userdata should contain fd userdata specified by the user"
|
||||
);
|
||||
assert_eq!(
|
||||
out[1].error,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"the event.error should be set to {}",
|
||||
wasi_unstable::raw::__WASI_ESUCCESS
|
||||
);
|
||||
assert_eq!(
|
||||
out[1].type_,
|
||||
wasi_unstable::EVENTTYPE_FD_WRITE,
|
||||
"the event.type_ should equal FD_WRITE"
|
||||
);
|
||||
}
|
||||
|
||||
unsafe fn test_fd_readwrite(fd: wasi_unstable::Fd, error_code: wasi_unstable::raw::__wasi_errno_t) {
|
||||
let fd_readwrite = wasi_unstable::raw::__wasi_subscription_u_fd_readwrite_t { fd };
|
||||
let in_ = [
|
||||
wasi_unstable::Subscription {
|
||||
userdata: 1,
|
||||
type_: wasi_unstable::EVENTTYPE_FD_READ,
|
||||
u: wasi_unstable::raw::__wasi_subscription_u { fd_readwrite },
|
||||
},
|
||||
wasi_unstable::Subscription {
|
||||
userdata: 2,
|
||||
type_: wasi_unstable::EVENTTYPE_FD_WRITE,
|
||||
u: wasi_unstable::raw::__wasi_subscription_u { fd_readwrite },
|
||||
},
|
||||
];
|
||||
let out = poll_oneoff_impl(&in_, 2);
|
||||
assert_eq!(
|
||||
out[0].userdata, 1,
|
||||
"the event.userdata should contain fd userdata specified by the user"
|
||||
);
|
||||
assert_eq!(
|
||||
out[0].error, error_code,
|
||||
"the event.error should be set to {}",
|
||||
error_code
|
||||
);
|
||||
assert_eq!(
|
||||
out[0].type_,
|
||||
wasi_unstable::EVENTTYPE_FD_READ,
|
||||
"the event.type_ should equal FD_READ"
|
||||
);
|
||||
assert_eq!(
|
||||
out[1].userdata, 2,
|
||||
"the event.userdata should contain fd userdata specified by the user"
|
||||
);
|
||||
assert_eq!(
|
||||
out[1].error, error_code,
|
||||
"the event.error should be set to {}",
|
||||
error_code
|
||||
);
|
||||
assert_eq!(
|
||||
out[1].type_,
|
||||
wasi_unstable::EVENTTYPE_FD_WRITE,
|
||||
"the event.type_ should equal FD_WRITE"
|
||||
);
|
||||
}
|
||||
|
||||
unsafe fn test_fd_readwrite_valid_fd(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
test_fd_readwrite(file_fd, wasi_unstable::raw::__WASI_ESUCCESS);
|
||||
|
||||
close_fd(file_fd);
|
||||
cleanup_file(dir_fd, "file");
|
||||
}
|
||||
|
||||
unsafe fn test_fd_readwrite_invalid_fd() {
|
||||
test_fd_readwrite(
|
||||
wasi_unstable::Fd::max_value(),
|
||||
wasi_unstable::raw::__WASI_EBADF,
|
||||
)
|
||||
}
|
||||
|
||||
unsafe fn test_poll_oneoff(dir_fd: wasi_unstable::Fd) {
|
||||
test_timeout();
|
||||
// NB we assume that stdin/stdout/stderr are valid and open
|
||||
// for the duration of the test case
|
||||
test_stdin_read();
|
||||
test_stdout_stderr_write();
|
||||
test_fd_readwrite_valid_fd(dir_fd);
|
||||
test_fd_readwrite_invalid_fd();
|
||||
}
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_poll_oneoff(dir_fd) }
|
||||
}
|
||||
72
wasi-common/wasi-misc-tests/src/bin/readlink.rs
Normal file
72
wasi-common/wasi-misc-tests/src/bin/readlink.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_path_readlink, wasi_path_symlink};
|
||||
|
||||
unsafe fn test_readlink(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
create_file(dir_fd, "target");
|
||||
|
||||
// Create a symlink
|
||||
assert!(
|
||||
wasi_path_symlink("target", dir_fd, "symlink").is_ok(),
|
||||
"creating a symlink"
|
||||
);
|
||||
|
||||
// Read link into the buffer
|
||||
let buf = &mut [0u8; 10];
|
||||
let mut bufused: usize = 0;
|
||||
let mut status = wasi_path_readlink(dir_fd, "symlink", buf, &mut bufused);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"readlink should succeed"
|
||||
);
|
||||
assert_eq!(bufused, 6, "should use 6 bytes of the buffer");
|
||||
assert_eq!(&buf[..6], b"target", "buffer should contain 'target'");
|
||||
assert_eq!(
|
||||
&buf[6..],
|
||||
&[0u8; 4],
|
||||
"the remaining bytes should be untouched"
|
||||
);
|
||||
|
||||
// Read link into smaller buffer than the actual link's length
|
||||
let buf = &mut [0u8; 4];
|
||||
let mut bufused: usize = 0;
|
||||
status = wasi_path_readlink(dir_fd, "symlink", buf, &mut bufused);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"readlink should succeed"
|
||||
);
|
||||
assert_eq!(bufused, 4, "should use all 4 bytes of the buffer");
|
||||
assert_eq!(buf, b"targ", "buffer should contain 'targ'");
|
||||
|
||||
// Clean up.
|
||||
cleanup_file(dir_fd, "target");
|
||||
cleanup_file(dir_fd, "symlink");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_readlink(dir_fd) }
|
||||
}
|
||||
51
wasi-common/wasi-misc-tests/src/bin/readlink_no_buffer.rs
Normal file
51
wasi-common/wasi-misc-tests/src/bin/readlink_no_buffer.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::cleanup_file;
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_path_readlink, wasi_path_symlink};
|
||||
|
||||
unsafe fn test_readlink_no_buffer(dir_fd: wasi_unstable::Fd) {
|
||||
// First create a dangling symlink.
|
||||
assert!(
|
||||
wasi_path_symlink("target", dir_fd, "symlink").is_ok(),
|
||||
"creating a symlink"
|
||||
);
|
||||
|
||||
// Readlink it into a non-existent buffer.
|
||||
let mut bufused: usize = 1;
|
||||
let status = wasi_path_readlink(dir_fd, "symlink", &mut [], &mut bufused);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"readlink with a 0-sized buffer should succeed"
|
||||
);
|
||||
assert_eq!(
|
||||
bufused, 0,
|
||||
"readlink with a 0-sized buffer should return 'bufused' 0"
|
||||
);
|
||||
|
||||
// Clean up.
|
||||
cleanup_file(dir_fd, "symlink");
|
||||
}
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_readlink_no_buffer(dir_fd) }
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, create_dir, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_path_remove_directory;
|
||||
|
||||
unsafe fn test_remove_directory_trailing_slashes(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a directory in the scratch directory.
|
||||
create_dir(dir_fd, "dir");
|
||||
|
||||
// Test that removing it succeeds.
|
||||
assert_eq!(
|
||||
wasi_path_remove_directory(dir_fd, "dir"),
|
||||
Ok(()),
|
||||
"remove_directory on a directory should succeed"
|
||||
);
|
||||
|
||||
create_dir(dir_fd, "dir");
|
||||
|
||||
// Test that removing it with a trailing flash succeeds.
|
||||
assert_eq!(
|
||||
wasi_path_remove_directory(dir_fd, "dir/"),
|
||||
Ok(()),
|
||||
"remove_directory with a trailing slash on a directory should succeed"
|
||||
);
|
||||
|
||||
// Create a temporary file.
|
||||
create_file(dir_fd, "file");
|
||||
|
||||
// Test that removing it with no trailing flash fails.
|
||||
assert_eq!(
|
||||
wasi_path_remove_directory(dir_fd, "file"),
|
||||
Err(wasi_unstable::ENOTDIR),
|
||||
"remove_directory without a trailing slash on a file should fail"
|
||||
);
|
||||
|
||||
// Test that removing it with a trailing flash fails.
|
||||
assert_eq!(
|
||||
wasi_path_remove_directory(dir_fd, "file/"),
|
||||
Err(wasi_unstable::ENOTDIR),
|
||||
"remove_directory with a trailing slash on a file should fail"
|
||||
);
|
||||
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_remove_directory_trailing_slashes(dir_fd) }
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_dir, create_dir};
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_path_remove_directory;
|
||||
|
||||
unsafe fn test_remove_nonempty_directory(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a directory in the scratch directory.
|
||||
create_dir(dir_fd, "dir");
|
||||
|
||||
// Create a directory in the directory we just created.
|
||||
create_dir(dir_fd, "dir/nested");
|
||||
|
||||
// Test that attempting to unlink the first directory returns the expected error code.
|
||||
assert_eq!(
|
||||
wasi_path_remove_directory(dir_fd, "dir"),
|
||||
Err(wasi_unstable::ENOTEMPTY),
|
||||
"remove_directory on a directory should return ENOTEMPTY",
|
||||
);
|
||||
|
||||
// Removing the directories.
|
||||
assert!(
|
||||
wasi_path_remove_directory(dir_fd, "dir/nested").is_ok(),
|
||||
"remove_directory on a nested directory should succeed",
|
||||
);
|
||||
cleanup_dir(dir_fd, "dir");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_remove_nonempty_directory(dir_fd) }
|
||||
}
|
||||
131
wasi-common/wasi-misc-tests/src/bin/renumber.rs
Normal file
131
wasi-common/wasi-misc-tests/src/bin/renumber.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use libc;
|
||||
use more_asserts::assert_gt;
|
||||
use std::{env, mem, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::close_fd;
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_fdstat_get, wasi_path_open};
|
||||
|
||||
unsafe fn test_renumber(dir_fd: wasi_unstable::Fd) {
|
||||
let pre_fd: wasi_unstable::Fd = (libc::STDERR_FILENO + 1) as wasi_unstable::Fd;
|
||||
|
||||
assert_gt!(dir_fd, pre_fd, "dir_fd number");
|
||||
|
||||
// Create a file in the scratch directory.
|
||||
let mut fd_from = wasi_unstable::Fd::max_value() - 1;
|
||||
let mut status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file1",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut fd_from,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
fd_from,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Get fd_from fdstat attributes
|
||||
let mut fdstat_from: wasi_unstable::FdStat = mem::zeroed();
|
||||
status = wasi_fd_fdstat_get(fd_from, &mut fdstat_from);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"calling fd_fdstat on the open file descriptor"
|
||||
);
|
||||
|
||||
// Create another file in the scratch directory.
|
||||
let mut fd_to = wasi_unstable::Fd::max_value() - 1;
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file2",
|
||||
wasi_unstable::O_CREAT,
|
||||
wasi_unstable::RIGHT_FD_READ | wasi_unstable::RIGHT_FD_WRITE,
|
||||
0,
|
||||
0,
|
||||
&mut fd_to,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"opening a file"
|
||||
);
|
||||
assert_gt!(
|
||||
fd_to,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
|
||||
// Renumber fd of file1 into fd of file2
|
||||
assert!(
|
||||
wasi_unstable::fd_renumber(fd_from, fd_to).is_ok(),
|
||||
"renumbering two descriptors",
|
||||
);
|
||||
|
||||
// Ensure that fd_from is closed
|
||||
assert_eq!(
|
||||
wasi_unstable::fd_close(fd_from),
|
||||
Err(wasi_unstable::EBADF),
|
||||
"closing already closed file descriptor"
|
||||
);
|
||||
|
||||
// Ensure that fd_to is still open.
|
||||
let mut fdstat_to: wasi_unstable::FdStat = mem::zeroed();
|
||||
status = wasi_fd_fdstat_get(fd_to, &mut fdstat_to);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"calling fd_fdstat on the open file descriptor"
|
||||
);
|
||||
assert_eq!(
|
||||
fdstat_from.fs_filetype, fdstat_to.fs_filetype,
|
||||
"expected fd_to have the same fdstat as fd_from"
|
||||
);
|
||||
assert_eq!(
|
||||
fdstat_from.fs_flags, fdstat_to.fs_flags,
|
||||
"expected fd_to have the same fdstat as fd_from"
|
||||
);
|
||||
assert_eq!(
|
||||
fdstat_from.fs_rights_base, fdstat_to.fs_rights_base,
|
||||
"expected fd_to have the same fdstat as fd_from"
|
||||
);
|
||||
assert_eq!(
|
||||
fdstat_from.fs_rights_inheriting, fdstat_to.fs_rights_inheriting,
|
||||
"expected fd_to have the same fdstat as fd_from"
|
||||
);
|
||||
|
||||
close_fd(fd_to);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_renumber(dir_fd) }
|
||||
}
|
||||
10
wasi-common/wasi-misc-tests/src/bin/sched_yield.rs
Normal file
10
wasi-common/wasi-misc-tests/src/bin/sched_yield.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
use wasi::wasi_unstable;
|
||||
|
||||
fn test_sched_yield() {
|
||||
assert!(wasi_unstable::sched_yield().is_ok(), "sched_yield");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Run tests
|
||||
test_sched_yield()
|
||||
}
|
||||
47
wasi-common/wasi-misc-tests/src/bin/symlink_loop.rs
Normal file
47
wasi-common/wasi-misc-tests/src/bin/symlink_loop.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::cleanup_file;
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_path_open, wasi_path_symlink};
|
||||
|
||||
unsafe fn test_symlink_loop(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a self-referencing symlink.
|
||||
assert!(
|
||||
wasi_path_symlink("symlink", dir_fd, "symlink").is_ok(),
|
||||
"creating a symlink"
|
||||
);
|
||||
|
||||
// Try to open it.
|
||||
let mut file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
assert_eq!(
|
||||
wasi_path_open(dir_fd, 0, "symlink", 0, 0, 0, 0, &mut file_fd),
|
||||
wasi_unstable::raw::__WASI_ELOOP,
|
||||
"opening a self-referencing symlink",
|
||||
);
|
||||
|
||||
// Clean up.
|
||||
cleanup_file(dir_fd, "symlink");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_symlink_loop(dir_fd) }
|
||||
}
|
||||
157
wasi-common/wasi-misc-tests/src/bin/truncation_rights.rs
Normal file
157
wasi-common/wasi-misc-tests/src/bin/truncation_rights.rs
Normal file
@@ -0,0 +1,157 @@
|
||||
use std::{env, mem, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_file, close_fd, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::{wasi_fd_fdstat_get, wasi_path_open};
|
||||
|
||||
unsafe fn test_truncation_rights(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a file in the scratch directory.
|
||||
create_file(dir_fd, "file");
|
||||
|
||||
// Get the rights for the scratch directory.
|
||||
let mut dir_fdstat: wasi_unstable::FdStat = mem::zeroed();
|
||||
let mut status = wasi_fd_fdstat_get(dir_fd, &mut dir_fdstat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"calling fd_fdstat on the scratch directory"
|
||||
);
|
||||
assert_eq!(
|
||||
dir_fdstat.fs_filetype,
|
||||
wasi_unstable::FILETYPE_DIRECTORY,
|
||||
"expected the scratch directory to be a directory",
|
||||
);
|
||||
assert_eq!(
|
||||
dir_fdstat.fs_flags, 0,
|
||||
"expected the scratch directory to have no special flags",
|
||||
);
|
||||
assert_eq!(
|
||||
dir_fdstat.fs_rights_base & wasi_unstable::RIGHT_FD_FILESTAT_SET_SIZE,
|
||||
0,
|
||||
"directories shouldn't have the fd_filestat_set_size right",
|
||||
);
|
||||
|
||||
// If we have the right to set sizes from paths, test that it works.
|
||||
if (dir_fdstat.fs_rights_base & wasi_unstable::RIGHT_PATH_FILESTAT_SET_SIZE) == 0 {
|
||||
eprintln!("implementation doesn't support setting file sizes, skipping");
|
||||
} else {
|
||||
// Test that we can truncate the file.
|
||||
let mut file_fd: wasi_unstable::Fd = wasi_unstable::Fd::max_value() - 1;
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_TRUNC,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"truncating a file"
|
||||
);
|
||||
close_fd(file_fd);
|
||||
|
||||
let mut rights_base: wasi_unstable::Rights = dir_fdstat.fs_rights_base;
|
||||
let mut rights_inheriting: wasi_unstable::Rights = dir_fdstat.fs_rights_inheriting;
|
||||
|
||||
if (rights_inheriting & wasi_unstable::RIGHT_FD_FILESTAT_SET_SIZE) == 0 {
|
||||
eprintln!("implementation doesn't support setting file sizes through file descriptors, skipping");
|
||||
} else {
|
||||
rights_inheriting &= !wasi_unstable::RIGHT_FD_FILESTAT_SET_SIZE;
|
||||
assert!(
|
||||
wasi_unstable::fd_fdstat_set_rights(dir_fd, rights_base, rights_inheriting).is_ok(),
|
||||
"droping fd_filestat_set_size inheriting right on a directory",
|
||||
);
|
||||
}
|
||||
|
||||
// Test that we can truncate the file without the
|
||||
// wasi_unstable::RIGHT_FD_FILESTAT_SET_SIZE right.
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_TRUNC,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"truncating a file without fd_filestat_set_size right",
|
||||
);
|
||||
close_fd(file_fd);
|
||||
|
||||
rights_base &= !wasi_unstable::RIGHT_PATH_FILESTAT_SET_SIZE;
|
||||
assert!(
|
||||
wasi_unstable::fd_fdstat_set_rights(dir_fd, rights_base, rights_inheriting).is_ok(),
|
||||
"droping path_filestat_set_size base right on a directory",
|
||||
);
|
||||
|
||||
// Test that clearing wasi_unstable::RIGHT_PATH_FILESTAT_SET_SIZE actually
|
||||
// took effect.
|
||||
status = wasi_fd_fdstat_get(dir_fd, &mut dir_fdstat);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"reading the fdstat from a directory",
|
||||
);
|
||||
assert_eq!(
|
||||
(dir_fdstat.fs_rights_base & wasi_unstable::RIGHT_PATH_FILESTAT_SET_SIZE),
|
||||
0,
|
||||
"reading the fdstat from a directory",
|
||||
);
|
||||
|
||||
// Test that we can't truncate the file without the
|
||||
// wasi_unstable::RIGHT_PATH_FILESTAT_SET_SIZE right.
|
||||
status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
"file",
|
||||
wasi_unstable::O_TRUNC,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ENOTCAPABLE,
|
||||
"truncating a file without path_filestat_set_size right",
|
||||
);
|
||||
assert_eq!(
|
||||
file_fd,
|
||||
wasi_unstable::Fd::max_value(),
|
||||
"failed open should set the file descriptor to -1",
|
||||
);
|
||||
}
|
||||
|
||||
cleanup_file(dir_fd, "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: {} <scratch directory>", 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_truncation_rights(dir_fd) }
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
use std::{env, process};
|
||||
use wasi::wasi_unstable;
|
||||
use wasi_misc_tests::open_scratch_directory;
|
||||
use wasi_misc_tests::utils::{cleanup_dir, create_dir, create_file};
|
||||
use wasi_misc_tests::wasi_wrappers::wasi_path_unlink_file;
|
||||
|
||||
unsafe fn test_unlink_file_trailing_slashes(dir_fd: wasi_unstable::Fd) {
|
||||
// Create a directory in the scratch directory.
|
||||
create_dir(dir_fd, "dir");
|
||||
|
||||
// Test that unlinking it fails.
|
||||
assert_eq!(
|
||||
wasi_path_unlink_file(dir_fd, "dir"),
|
||||
Err(wasi_unstable::EISDIR),
|
||||
"unlink_file on a directory should fail"
|
||||
);
|
||||
|
||||
// Test that unlinking it with a trailing flash fails.
|
||||
assert_eq!(
|
||||
wasi_path_unlink_file(dir_fd, "dir/"),
|
||||
Err(wasi_unstable::EISDIR),
|
||||
"unlink_file on a directory should fail"
|
||||
);
|
||||
|
||||
// Clean up.
|
||||
cleanup_dir(dir_fd, "dir");
|
||||
|
||||
// Create a temporary file.
|
||||
create_file(dir_fd, "file");
|
||||
|
||||
// Test that unlinking it with a trailing flash fails.
|
||||
assert_eq!(
|
||||
wasi_path_unlink_file(dir_fd, "file/"),
|
||||
Err(wasi_unstable::ENOTDIR),
|
||||
"unlink_file with a trailing slash should fail"
|
||||
);
|
||||
|
||||
// Test that unlinking it with no trailing flash succeeds.
|
||||
assert_eq!(
|
||||
wasi_path_unlink_file(dir_fd, "file"),
|
||||
Ok(()),
|
||||
"unlink_file with no trailing slash should succeed"
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let prog = args.next().unwrap();
|
||||
let arg = if let Some(arg) = args.next() {
|
||||
arg
|
||||
} else {
|
||||
eprintln!("usage: {} <scratch directory>", 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_unlink_file_trailing_slashes(dir_fd) }
|
||||
}
|
||||
25
wasi-common/wasi-misc-tests/src/lib.rs
Normal file
25
wasi-common/wasi-misc-tests/src/lib.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
pub mod utils;
|
||||
pub mod wasi_wrappers;
|
||||
|
||||
use libc;
|
||||
use std::ffi::CString;
|
||||
use std::io;
|
||||
use wasi::wasi_unstable;
|
||||
|
||||
pub fn open_scratch_directory(path: &str) -> Result<wasi_unstable::Fd, String> {
|
||||
// Open the scratch directory.
|
||||
let dir_fd: wasi_unstable::Fd = unsafe {
|
||||
let cstr = CString::new(path.as_bytes()).unwrap();
|
||||
libc::open(cstr.as_ptr(), libc::O_RDONLY | libc::O_DIRECTORY)
|
||||
} as wasi_unstable::Fd;
|
||||
|
||||
if (dir_fd as std::os::raw::c_int) < 0 {
|
||||
Err(format!(
|
||||
"error opening scratch directory '{}': {}",
|
||||
path,
|
||||
io::Error::last_os_error()
|
||||
))
|
||||
} else {
|
||||
Ok(dir_fd)
|
||||
}
|
||||
}
|
||||
54
wasi-common/wasi-misc-tests/src/utils.rs
Normal file
54
wasi-common/wasi-misc-tests/src/utils.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use crate::wasi_wrappers::*;
|
||||
use more_asserts::assert_gt;
|
||||
use wasi::wasi_unstable;
|
||||
|
||||
pub unsafe fn create_dir(dir_fd: wasi_unstable::Fd, dir_name: &str) {
|
||||
assert!(
|
||||
wasi_path_create_directory(dir_fd, dir_name).is_ok(),
|
||||
"creating a directory"
|
||||
);
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup_dir(dir_fd: wasi_unstable::Fd, dir_name: &str) {
|
||||
assert!(
|
||||
wasi_path_remove_directory(dir_fd, dir_name).is_ok(),
|
||||
"remove_directory on an empty directory should succeed"
|
||||
);
|
||||
}
|
||||
|
||||
/// Create an empty file with the given name.
|
||||
pub unsafe fn create_file(dir_fd: wasi_unstable::Fd, file_name: &str) {
|
||||
let mut file_fd = wasi_unstable::Fd::max_value() - 1;
|
||||
let status = wasi_path_open(
|
||||
dir_fd,
|
||||
0,
|
||||
file_name,
|
||||
wasi_unstable::O_CREAT,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut file_fd,
|
||||
);
|
||||
assert_eq!(
|
||||
status,
|
||||
wasi_unstable::raw::__WASI_ESUCCESS,
|
||||
"creating a file"
|
||||
);
|
||||
assert_gt!(
|
||||
file_fd,
|
||||
libc::STDERR_FILENO as wasi_unstable::Fd,
|
||||
"file descriptor range check",
|
||||
);
|
||||
close_fd(file_fd);
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup_file(dir_fd: wasi_unstable::Fd, file_name: &str) {
|
||||
assert!(
|
||||
wasi_path_unlink_file(dir_fd, file_name).is_ok(),
|
||||
"unlink_file on a symlink should succeed"
|
||||
);
|
||||
}
|
||||
|
||||
pub unsafe fn close_fd(fd: wasi_unstable::Fd) {
|
||||
assert!(wasi_unstable::fd_close(fd).is_ok(), "closing a file");
|
||||
}
|
||||
217
wasi-common/wasi-misc-tests/src/wasi_wrappers.rs
Normal file
217
wasi-common/wasi-misc-tests/src/wasi_wrappers.rs
Normal file
@@ -0,0 +1,217 @@
|
||||
//! Minimal wrappers around WASI functions to allow use of `&str` rather than
|
||||
//! pointer-length pairs.
|
||||
//!
|
||||
//! Where possible, we use the idiomatic wasi_unstable wrappers rather than the
|
||||
//! raw interfaces, however for functions with out parameters, we use the raw
|
||||
//! interfaces so that we can test whether they are stored to. In the future,
|
||||
//! WASI should switch to multi-value and eliminate out parameters altogether.
|
||||
|
||||
use wasi::wasi_unstable;
|
||||
|
||||
pub unsafe fn wasi_path_create_directory(
|
||||
dir_fd: wasi_unstable::Fd,
|
||||
dir_name: &str,
|
||||
) -> Result<(), wasi_unstable::Error> {
|
||||
wasi_unstable::path_create_directory(dir_fd, dir_name.as_bytes())
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_path_remove_directory(
|
||||
dir_fd: wasi_unstable::Fd,
|
||||
dir_name: &str,
|
||||
) -> Result<(), wasi_unstable::Error> {
|
||||
wasi_unstable::path_remove_directory(dir_fd, dir_name.as_bytes())
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_path_unlink_file(
|
||||
dir_fd: wasi_unstable::Fd,
|
||||
file_name: &str,
|
||||
) -> Result<(), wasi_unstable::Error> {
|
||||
wasi_unstable::path_unlink_file(dir_fd, file_name.as_bytes())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub unsafe fn wasi_path_open(
|
||||
dirfd: wasi_unstable::Fd,
|
||||
dirflags: wasi_unstable::LookupFlags,
|
||||
path: &str,
|
||||
oflags: wasi_unstable::OFlags,
|
||||
fs_rights_base: wasi_unstable::Rights,
|
||||
fs_rights_inheriting: wasi_unstable::Rights,
|
||||
fs_flags: wasi_unstable::FdFlags,
|
||||
fd: &mut wasi_unstable::Fd,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_path_open(
|
||||
dirfd,
|
||||
dirflags,
|
||||
path.as_ptr(),
|
||||
path.len(),
|
||||
oflags,
|
||||
fs_rights_base,
|
||||
fs_rights_inheriting,
|
||||
fs_flags,
|
||||
fd,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_path_symlink(
|
||||
old_path: &str,
|
||||
dirfd: wasi_unstable::Fd,
|
||||
new_path: &str,
|
||||
) -> Result<(), wasi_unstable::Error> {
|
||||
wasi_unstable::path_symlink(old_path.as_bytes(), dirfd, new_path.as_bytes())
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_path_readlink(
|
||||
dirfd: wasi_unstable::Fd,
|
||||
path: &str,
|
||||
buf: &mut [u8],
|
||||
bufused: &mut usize,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_path_readlink(
|
||||
dirfd,
|
||||
path.as_ptr(),
|
||||
path.len(),
|
||||
buf.as_mut_ptr(),
|
||||
buf.len(),
|
||||
bufused,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_path_rename(
|
||||
old_dirfd: wasi_unstable::Fd,
|
||||
old_path: &str,
|
||||
new_dirfd: wasi_unstable::Fd,
|
||||
new_path: &str,
|
||||
) -> Result<(), wasi_unstable::Error> {
|
||||
wasi_unstable::path_rename(
|
||||
old_dirfd,
|
||||
old_path.as_bytes(),
|
||||
new_dirfd,
|
||||
new_path.as_bytes(),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_fdstat_get(
|
||||
fd: wasi_unstable::Fd,
|
||||
fdstat: &mut wasi_unstable::FdStat,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_fdstat_get(fd, fdstat)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_seek(
|
||||
fd: wasi_unstable::Fd,
|
||||
offset: wasi_unstable::FileDelta,
|
||||
whence: wasi_unstable::Whence,
|
||||
newoffset: &mut wasi_unstable::FileSize,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_seek(fd, offset, whence, newoffset)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_tell(
|
||||
fd: wasi_unstable::Fd,
|
||||
offset: &mut wasi_unstable::FileSize,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_tell(fd, offset)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_clock_time_get(
|
||||
clock_id: wasi_unstable::ClockId,
|
||||
precision: wasi_unstable::Timestamp,
|
||||
time: &mut wasi_unstable::Timestamp,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_clock_time_get(clock_id, precision, time)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_filestat_get(
|
||||
fd: wasi_unstable::Fd,
|
||||
filestat: &mut wasi_unstable::FileStat,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_filestat_get(fd, filestat)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_write(
|
||||
fd: wasi_unstable::Fd,
|
||||
iovs: &[wasi_unstable::CIoVec],
|
||||
nwritten: &mut libc::size_t,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_write(fd, iovs.as_ptr(), iovs.len(), nwritten)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_read(
|
||||
fd: wasi_unstable::Fd,
|
||||
iovs: &[wasi_unstable::IoVec],
|
||||
nread: &mut libc::size_t,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_read(fd, iovs.as_ptr(), iovs.len(), nread)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_pread(
|
||||
fd: wasi_unstable::Fd,
|
||||
iovs: &[wasi_unstable::IoVec],
|
||||
offset: wasi_unstable::FileSize,
|
||||
nread: &mut usize,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_pread(fd, iovs.as_ptr(), iovs.len(), offset, nread)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_pwrite(
|
||||
fd: wasi_unstable::Fd,
|
||||
iovs: &mut [wasi_unstable::CIoVec],
|
||||
offset: wasi_unstable::FileSize,
|
||||
nwritten: &mut usize,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_pwrite(fd, iovs.as_ptr(), iovs.len(), offset, nwritten)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_path_filestat_get(
|
||||
fd: wasi_unstable::Fd,
|
||||
dirflags: wasi_unstable::LookupFlags,
|
||||
path: &str,
|
||||
path_len: usize,
|
||||
filestat: &mut wasi_unstable::FileStat,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_path_filestat_get(fd, dirflags, path.as_ptr(), path_len, filestat)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_path_filestat_set_times(
|
||||
fd: wasi_unstable::Fd,
|
||||
dirflags: wasi_unstable::LookupFlags,
|
||||
path: &str,
|
||||
st_atim: wasi_unstable::Timestamp,
|
||||
st_mtim: wasi_unstable::Timestamp,
|
||||
fst_flags: wasi_unstable::FstFlags,
|
||||
) -> Result<(), wasi_unstable::Error> {
|
||||
wasi_unstable::path_filestat_set_times(
|
||||
fd,
|
||||
dirflags,
|
||||
path.as_bytes(),
|
||||
st_atim,
|
||||
st_mtim,
|
||||
fst_flags,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_readdir(
|
||||
fd: wasi_unstable::Fd,
|
||||
buf: &mut [u8],
|
||||
buf_len: usize,
|
||||
cookie: wasi_unstable::DirCookie,
|
||||
buf_used: &mut usize,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_readdir(
|
||||
fd,
|
||||
buf.as_mut_ptr() as *mut libc::c_void,
|
||||
buf_len,
|
||||
cookie,
|
||||
buf_used,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn wasi_fd_advise(
|
||||
fd: wasi_unstable::Fd,
|
||||
offset: wasi_unstable::FileSize,
|
||||
len: wasi_unstable::FileSize,
|
||||
advice: wasi_unstable::Advice,
|
||||
) -> wasi_unstable::Errno {
|
||||
wasi_unstable::raw::__wasi_fd_advise(fd, offset, len, advice)
|
||||
}
|
||||
Reference in New Issue
Block a user