diff --git a/lib/wasix/src/lib.rs b/lib/wasix/src/lib.rs index 47d01cf9706..9185d7ef873 100644 --- a/lib/wasix/src/lib.rs +++ b/lib/wasix/src/lib.rs @@ -392,6 +392,7 @@ fn wasi_snapshot_preview1_exports( "proc_raise" => Function::new_typed_with_env(&mut store, env, proc_raise), "random_get" => Function::new_typed_with_env(&mut store, env, random_get::), "sched_yield" => Function::new_typed_with_env(&mut store, env, sched_yield::), + "sock_accept" => Function::new_typed_with_env(&mut store, env, sock_accept::), "sock_recv" => Function::new_typed_with_env(&mut store, env, sock_recv::), "sock_send" => Function::new_typed_with_env(&mut store, env, sock_send::), "sock_shutdown" => Function::new_typed_with_env(&mut store, env, sock_shutdown), @@ -504,8 +505,8 @@ fn wasix_exports_32(mut store: &mut impl AsStoreMut, env: &FunctionEnv) "sock_leave_multicast_v6" => Function::new_typed_with_env(&mut store, env, sock_leave_multicast_v6::), "sock_bind" => Function::new_typed_with_env(&mut store, env, sock_bind::), "sock_listen" => Function::new_typed_with_env(&mut store, env, sock_listen::), - "sock_accept" => Function::new_typed_with_env(&mut store, env, sock_accept::), - "sock_accept_v2" => Function::new_typed_with_env(&mut store, env, sock_accept::), + "sock_accept" => Function::new_typed_with_env(&mut store, env, sock_accept_v2::), + "sock_accept_v2" => Function::new_typed_with_env(&mut store, env, sock_accept_v2::), "sock_connect" => Function::new_typed_with_env(&mut store, env, sock_connect::), "sock_recv" => Function::new_typed_with_env(&mut store, env, sock_recv::), "sock_recv_from" => Function::new_typed_with_env(&mut store, env, sock_recv_from::), @@ -622,8 +623,8 @@ fn wasix_exports_64(mut store: &mut impl AsStoreMut, env: &FunctionEnv) "sock_leave_multicast_v6" => Function::new_typed_with_env(&mut store, env, sock_leave_multicast_v6::), "sock_bind" => Function::new_typed_with_env(&mut store, env, sock_bind::), "sock_listen" => Function::new_typed_with_env(&mut store, env, sock_listen::), - "sock_accept" => Function::new_typed_with_env(&mut store, env, sock_accept::), - "sock_accept_v2" => Function::new_typed_with_env(&mut store, env, sock_accept::), + "sock_accept" => Function::new_typed_with_env(&mut store, env, sock_accept_v2::), + "sock_accept_v2" => Function::new_typed_with_env(&mut store, env, sock_accept_v2::), "sock_connect" => Function::new_typed_with_env(&mut store, env, sock_connect::), "sock_recv" => Function::new_typed_with_env(&mut store, env, sock_recv::), "sock_recv_from" => Function::new_typed_with_env(&mut store, env, sock_recv_from::), diff --git a/lib/wasix/src/syscalls/wasix/sock_accept.rs b/lib/wasix/src/syscalls/wasix/sock_accept.rs index 7d76306643e..9b54e829a96 100644 --- a/lib/wasix/src/syscalls/wasix/sock_accept.rs +++ b/lib/wasix/src/syscalls/wasix/sock_accept.rs @@ -19,13 +19,69 @@ pub fn sock_accept( sock: WasiFd, mut fd_flags: Fdflags, ro_fd: WasmPtr, +) -> Result { + wasi_try_ok!(WasiEnv::process_signals_and_exit(&mut ctx)?); + + let env = ctx.data(); + let (memory, state, _) = unsafe { env.get_memory_and_wasi_state_and_inodes(&ctx, 0) }; + + let (fd, addr) = wasi_try_ok!(sock_accept_internal::(env, sock, fd_flags)); + + wasi_try_mem_ok!(ro_fd.write(&memory, fd)); + + Ok(Errno::Success) +} + +/// ### `sock_accept_v2()` +/// Accept a new incoming connection. +/// Note: This is similar to `accept` in POSIX. +/// +/// ## Parameters +/// +/// * `fd` - The listening socket. +/// * `flags` - The desired values of the file descriptor flags. +/// * `ro_addr` - Returns the address and port of the client +/// +/// ## Return +/// +/// New socket connection +#[instrument(level = "debug", skip_all, fields(%sock, fd = field::Empty), ret, err)] +pub fn sock_accept_v2( + mut ctx: FunctionEnvMut<'_, WasiEnv>, + sock: WasiFd, + mut fd_flags: Fdflags, + ro_fd: WasmPtr, ro_addr: WasmPtr<__wasi_addr_port_t, M>, ) -> Result { wasi_try_ok!(WasiEnv::process_signals_and_exit(&mut ctx)?); - let tasks = ctx.data().tasks().clone(); - let (child, addr, fd_flags) = wasi_try_ok!(__sock_asyncify( - ctx.data(), + let env = ctx.data(); + let (memory, state, _) = unsafe { env.get_memory_and_wasi_state_and_inodes(&ctx, 0) }; + + let (fd, addr) = wasi_try_ok!(sock_accept_internal::(env, sock, fd_flags)); + + wasi_try_mem_ok!(ro_fd.write(&memory, fd)); + wasi_try_ok!(crate::net::write_ip_port( + &memory, + ro_addr, + addr.ip(), + addr.port() + )); + + Ok(Errno::Success) +} + +pub fn sock_accept_internal( + env: &WasiEnv, + sock: WasiFd, + mut fd_flags: Fdflags, +) -> Result<(WasiFd, SocketAddr), Errno> { + let state = env.state(); + let inodes = &state.inodes; + + let tasks = env.tasks().clone(); + let (child, addr, fd_flags) = __sock_asyncify( + env, sock, Rights::SOCK_ACCEPT, move |socket, fd| async move { @@ -36,11 +92,8 @@ pub fn sock_accept( .accept(tasks.deref(), fd_flags) .await .map(|a| (a.0, a.1, fd_flags)) - } - )); - - let env = ctx.data(); - let (memory, state, inodes) = unsafe { env.get_memory_and_wasi_state_and_inodes(&ctx, 0) }; + }, + )?; let kind = Kind::Socket { socket: InodeSocket::new(InodeSocketKind::TcpStream { @@ -64,16 +117,8 @@ pub fn sock_accept( } let rights = Rights::all_socket(); - let fd = wasi_try_ok!(state.fs.create_fd(rights, rights, new_flags, 0, inode)); + let fd = state.fs.create_fd(rights, rights, new_flags, 0, inode)?; Span::current().record("fd", fd); - wasi_try_mem_ok!(ro_fd.write(&memory, fd)); - wasi_try_ok!(crate::net::write_ip_port( - &memory, - ro_addr, - addr.ip(), - addr.port() - )); - - Ok(Errno::Success) + Ok((fd, addr)) } diff --git a/tests/integration/cli/tests/snapshot.rs b/tests/integration/cli/tests/snapshot.rs index 063bbe2c7a4..de6a84b0f2e 100644 --- a/tests/integration/cli/tests/snapshot.rs +++ b/tests/integration/cli/tests/snapshot.rs @@ -1082,6 +1082,17 @@ fn test_snapshot_dash_python() { assert_json_snapshot!(snapshot); } +#[cfg_attr(any(target_env = "musl", target_os = "windows"), ignore)] +#[test] +fn test_snapshot_python_3_11_3() { + let snapshot = TestBuilder::new() + .with_name(function!()) + .arg("-c") + .arg("print(10)") + .run_wasm(include_bytes!("./wasm/python-3.11.3.wasm")); + assert_json_snapshot!(snapshot); +} + #[cfg_attr(any(target_env = "musl", target_os = "windows"), ignore)] #[test] fn test_snapshot_dash_dev_zero() { diff --git a/tests/integration/cli/tests/snapshots/snapshot__snapshot_python_3_11_3.snap b/tests/integration/cli/tests/snapshots/snapshot__snapshot_python_3_11_3.snap new file mode 100644 index 00000000000..0761c7c4c13 --- /dev/null +++ b/tests/integration/cli/tests/snapshots/snapshot__snapshot_python_3_11_3.snap @@ -0,0 +1,25 @@ +--- +source: tests/integration/cli/tests/snapshot.rs +assertion_line: 1093 +expression: snapshot +--- +{ + "spec": { + "name": "snapshot::test_snapshot_python_3_11_3", + "use_packages": [], + "include_webcs": [], + "cli_args": [ + "-c", + "print(10)" + ], + "enable_threads": true, + "enable_network": false + }, + "result": { + "Success": { + "stdout": "10\n", + "stderr": "", + "exit_code": 0 + } + } +} diff --git a/tests/integration/cli/tests/wasm/python-3.11.3.wasm b/tests/integration/cli/tests/wasm/python-3.11.3.wasm new file mode 100644 index 00000000000..afc10f79c36 Binary files /dev/null and b/tests/integration/cli/tests/wasm/python-3.11.3.wasm differ