Compile the following program with cargo b --target=wasm32-wasip1
use std::{
env,
io::stdin,
mem,
os::fd::AsRawFd,
process::exit,
};
fn main() {
let stdin = stdin();
let stat = unsafe {
let mut stat = mem::zeroed();
libc::fstat(stdin.as_raw_fd(), &mut stat);
stat
};
dbg!(&stat);
if (stat.st_mode & libc::S_IFMT) != libc::S_IFIFO {
let name = env::args().next().unwrap();
eprintln!(r#"Usage: echo -e "a\nb" | {name}"#);
exit(1);
}
let strings: Vec<String> = stdin.lines().filter_map(Result::ok).collect();
dbg!(&strings);
}
Run it with piped input, e.g. echo -e "a\nb" | wasmer run ./target/wasm32-wasip1/debug/example.wasm
Expected behavior
I expect st_mode will have the type set as named pipe ((stat.st_mode & libc::S_IFMT) != libc::S_IFIFO will evaluate to false), and the program will print the lines from the input and exit with status code 0.
Can confirm this is an issue with wasmer (and wasmtime), as it works as expected with iwasm and wasm3 (I'm starting to have a concerning amount of wasm runtimes installed on my system :p)
Describe the bug
The resulting stat struct after fstat never have the mode set to named pipe (
(stat.st_mode & libc::S_IFMT) == libc::S_IFIFO
) when it should.Steps to reproduce
Compile the following program with
cargo b --target=wasm32-wasip1
Run it with piped input, e.g.
echo -e "a\nb" | wasmer run ./target/wasm32-wasip1/debug/example.wasm
Expected behavior
I expect
st_mode
will have the type set as named pipe ((stat.st_mode & libc::S_IFMT) != libc::S_IFIFO
will evaluate tofalse
), and the program will print the lines from the input and exit with status code 0.This is what happens when compiling it to linux:
Actual behavior
The file type isn't set as named pipe like it should (
(stat.st_mode & libc::S_IFMT) != libc::S_IFIFO
is alwaystrue
):Additional context
This also happens on
wasmtime
. Maybe this is a limitation with the wasi interface?