-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a wasi-test to show a dir_fd always gets ERRNO_BADF on appropriat…
…e fd_ operations (#6197) * add a wasi-test to show a dir_fd always gets ERRNO_BADF on appropriate fd_ operations. This is a conformance test for the current behavior of preview 1 in wasi-common. It is debatable whether this is the right errno, I think for most of these ERRNO_ISDIR would be more descriptive, but this is the behavior we have. * Add comments to all the fd op failures explaining closest linux/posix behavior
- Loading branch information
Pat Hickey
committed
Apr 12, 2023
1 parent
f684a5f
commit d1d381e
Showing
1 changed file
with
99 additions
and
0 deletions.
There are no files selected for viewing
99 changes: 99 additions & 0 deletions
99
crates/test-programs/wasi-tests/src/bin/dir_fd_op_failures.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use std::{env, process}; | ||
use wasi_tests::open_scratch_directory; | ||
|
||
unsafe fn test_fd_dir_ops(dir_fd: wasi::Fd) { | ||
let stat = wasi::fd_filestat_get(dir_fd).expect("failed to fdstat"); | ||
assert_eq!(stat.filetype, wasi::FILETYPE_DIRECTORY); | ||
|
||
let mut read_buf = vec![0; 128].into_boxed_slice(); | ||
let iovec = wasi::Iovec { | ||
buf: read_buf.as_mut_ptr(), | ||
buf_len: read_buf.len(), | ||
}; | ||
let r = wasi::fd_read(dir_fd, &[iovec]); | ||
// On posix, this fails with ERRNO_ISDIR: | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_read error"); | ||
|
||
let r = wasi::fd_pread(dir_fd, &[iovec], 0); | ||
// On posix, this fails with ERRNO_ISDIR | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_pread error"); | ||
|
||
let write_buf = vec![0; 128].into_boxed_slice(); | ||
let ciovec = wasi::Ciovec { | ||
buf: write_buf.as_ptr(), | ||
buf_len: write_buf.len(), | ||
}; | ||
let r = wasi::fd_write(dir_fd, &[ciovec]); | ||
// Same behavior as specified by POSIX: | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_write error"); | ||
|
||
let r = wasi::fd_pwrite(dir_fd, &[ciovec], 0); | ||
// Same behavior as specified by POSIX: | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_pwrite error"); | ||
|
||
// Divergence from posix: lseek(dirfd) will return 0 | ||
let r = wasi::fd_seek(dir_fd, 0, wasi::WHENCE_CUR); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_seek WHENCE_CUR error"); | ||
let r = wasi::fd_seek(dir_fd, 0, wasi::WHENCE_SET); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_seek WHENCE_SET error"); | ||
let r = wasi::fd_seek(dir_fd, 0, wasi::WHENCE_END); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_seek WHENCE_END error"); | ||
|
||
// Tell isnt in posix, its basically lseek with WHENCE_CUR above | ||
let r = wasi::fd_tell(dir_fd); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_tell error"); | ||
|
||
// posix_fadvise(dirfd, 0, 0, POSIX_FADV_DONTNEED) will return 0 on linux. | ||
// not available on mac os. | ||
let r = wasi::fd_advise(dir_fd, 0, 0, wasi::ADVICE_DONTNEED); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_advise error"); | ||
|
||
// fallocate(dirfd, FALLOC_FL_ZERO_RANGE, 0, 1) will fail with errno EBADF on linux. | ||
// not available on mac os. | ||
let r = wasi::fd_allocate(dir_fd, 0, 0); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_allocate error"); | ||
|
||
// fdatasync(dirfd) will return 0 on linux. | ||
// not available on mac os. | ||
let r = wasi::fd_datasync(dir_fd); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_datasync error"); | ||
|
||
// fsync(dirfd) will return 0 on linux. | ||
// not available on mac os. | ||
let r = wasi::fd_sync(dir_fd); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_sync error"); | ||
|
||
// fcntl(dirfd, F_SETFL, O_NONBLOCK) will return 0 on linux. | ||
// not available on mac os. | ||
let r = wasi::fd_fdstat_set_flags(dir_fd, wasi::FDFLAGS_NONBLOCK); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_fdstat_set_flags error"); | ||
|
||
// ftruncate(dirfd, 1) will fail with errno EINVAL on posix. | ||
// here, we fail with EBADF instead: | ||
let r = wasi::fd_filestat_set_size(dir_fd, 0); | ||
assert_eq!(r, Err(wasi::ERRNO_BADF), "fd_filestat_set_size error"); | ||
} | ||
|
||
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) | ||
} | ||
}; | ||
|
||
unsafe { | ||
test_fd_dir_ops(dir_fd); | ||
} | ||
} |