Open tiran opened 2 years ago
I think you have to use read
and write
to read from and write to sockets.
@bjorn3 sock_recv
and sock_send
correspond to POSIX recv
and send
, and are expected to work with sockets. It seems likely something else is going on here.
My example works when I replace recv()
with read()
. But it's kinda the wrong API call. Portable applications like Python interpreter use recv()
because read()
does not work with sockets on Windows. Windows treats file handles and socket handles differently.
@bjorn3 sock_recv and sock_send correspond to POSIX recv and send, and are expected to work with sockets. It seems likely something else is going on here.
Rust's libstd uses fd_read and fd_write for WASI, not sock_recv and sock_send. Wasmtime also doesn't seem to implement sock_recv and sock_send at all.
I'm using WASI-SDK 16 to compile a portable C application to wasm32-wasi. To be more precise I want to get CPython's socket module working under WASI. It uses recv
and send
to read to and write from a socket.
Ah, I was mistaken. Wasmtime has some code for sock_send
and sock_recv
, but they're not fully implemented.
I've now submitted https://github.com/bytecodealliance/wasmtime/pull/4776 to implement them. With that patch, the reproducer reported above compiles and produces the expected output.
$ target/debug/wasmtime run --tcplisten 127.0.0.1:8080 recv.wasm
accept() on fd 3
.....
accept returned fd 4
recv 78
buf GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.81.0
Accept: */*
(78)
Test Case
recv.zip
Steps to Reproduce
wasmtime run --tcplisten 127.0.0.1:8080 recv.wasm
curl http://localhost:8080
Expected Results
I expect that
recv()
can read from the fd that has been returned fromaccept
.Actual Results
recv()
calls always fail withBad file descriptor
. Output from my reproducer:Versions and Environment
Wasmtime version or commit: 0.39.1 and 418dbc15bd2a5269b338587661387e05fc77b983
Operating system: Linux
Architecture: x86_64
Extra Info
I did a bit of debugging with
rust-gdb
. It looks likewasi_common::snapshots::preview_1::sock_recv
callswasi_common::file::WasiFile::sock_recv
which always fails withbadf
.sock_accept
on the other hand is provided bywasi_cap_std_sync::net
(crates/wasi-common/cap-std-sync/src/net.rs
).reproducer