diff --git a/library/std/src/os/wasi/process.rs b/library/std/src/os/wasi/process.rs index 4b8716a4626bf..199ba376f99c3 100644 --- a/library/std/src/os/wasi/process.rs +++ b/library/std/src/os/wasi/process.rs @@ -6,13 +6,16 @@ #![allow(dead_code, unused)] use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::process; +use crate::sys::{AsInner, FromInner, IntoInner}; +use crate::{process, sys}; #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawFd for process::Stdio { #[inline] unsafe fn from_raw_fd(fd: RawFd) -> process::Stdio { - unimplemented!() + let fd = unsafe { sys::fd::FileDesc::from_raw_fd(fd) }; + let io = sys::process::Stdio::Fd(fd); + process::Stdio::from_inner(io) } } @@ -20,7 +23,9 @@ impl FromRawFd for process::Stdio { impl From for process::Stdio { #[inline] fn from(fd: OwnedFd) -> process::Stdio { - unimplemented!() + let fd = sys::fd::FileDesc::from_inner(fd); + let io = sys::process::Stdio::Fd(fd); + process::Stdio::from_inner(io) } } @@ -28,7 +33,7 @@ impl From for process::Stdio { impl AsRawFd for process::ChildStdin { #[inline] fn as_raw_fd(&self) -> RawFd { - unimplemented!() + self.as_inner().as_raw_fd() } } @@ -36,7 +41,7 @@ impl AsRawFd for process::ChildStdin { impl AsRawFd for process::ChildStdout { #[inline] fn as_raw_fd(&self) -> RawFd { - unimplemented!() + self.as_inner().as_raw_fd() } } @@ -44,7 +49,7 @@ impl AsRawFd for process::ChildStdout { impl AsRawFd for process::ChildStderr { #[inline] fn as_raw_fd(&self) -> RawFd { - unimplemented!() + self.as_inner().as_raw_fd() } } @@ -52,7 +57,7 @@ impl AsRawFd for process::ChildStderr { impl IntoRawFd for process::ChildStdin { #[inline] fn into_raw_fd(self) -> RawFd { - unimplemented!() + self.into_inner().into_raw_fd() } } @@ -60,7 +65,7 @@ impl IntoRawFd for process::ChildStdin { impl IntoRawFd for process::ChildStdout { #[inline] fn into_raw_fd(self) -> RawFd { - unimplemented!() + self.into_inner().into_raw_fd() } } @@ -68,7 +73,7 @@ impl IntoRawFd for process::ChildStdout { impl IntoRawFd for process::ChildStderr { #[inline] fn into_raw_fd(self) -> RawFd { - unimplemented!() + self.into_inner().into_raw_fd() } } @@ -76,7 +81,7 @@ impl IntoRawFd for process::ChildStderr { impl AsFd for crate::process::ChildStdin { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { - unimplemented!() + self.as_inner().as_fd() } } @@ -84,7 +89,7 @@ impl AsFd for crate::process::ChildStdin { impl From for OwnedFd { #[inline] fn from(child_stdin: crate::process::ChildStdin) -> OwnedFd { - unimplemented!() + child_stdin.into_inner().into_inner() } } @@ -92,7 +97,7 @@ impl From for OwnedFd { impl AsFd for crate::process::ChildStdout { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { - unimplemented!() + self.as_inner().as_fd() } } @@ -100,7 +105,7 @@ impl AsFd for crate::process::ChildStdout { impl From for OwnedFd { #[inline] fn from(child_stdout: crate::process::ChildStdout) -> OwnedFd { - unimplemented!() + child_stdout.into_inner().into_inner() } } @@ -108,7 +113,7 @@ impl From for OwnedFd { impl AsFd for crate::process::ChildStderr { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { - unimplemented!() + self.as_inner().as_fd() } } @@ -116,6 +121,6 @@ impl AsFd for crate::process::ChildStderr { impl From for OwnedFd { #[inline] fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd { - unimplemented!() + child_stderr.into_inner().into_inner() } } diff --git a/library/std/tests/wasix_process_fds.rs b/library/std/tests/wasix_process_fds.rs new file mode 100644 index 0000000000000..f3928e3228555 --- /dev/null +++ b/library/std/tests/wasix_process_fds.rs @@ -0,0 +1,50 @@ +#![cfg(all(target_os = "wasi", target_vendor = "wasmer"))] + +use std::env; +use std::os::wasi::io::{AsFd, AsRawFd, FromRawFd, IntoRawFd, OwnedFd}; +use std::process::{Command, Stdio}; + +fn assert_borrowed_fd(stream: &T) { + assert_eq!(stream.as_raw_fd(), stream.as_fd().as_raw_fd()); +} + +fn stdio_through_raw_fd(stream: T) -> Stdio { + let fd = stream.into_raw_fd(); + unsafe { Stdio::from_raw_fd(fd) } +} + +fn stdio_through_owned_fd>(stream: T) -> Stdio { + Stdio::from(stream.into()) +} + +#[test] +fn child_stream_fd_conversions_transfer_ownership() { + const CHILD: &str = "RUST_STD_WASIX_PROCESS_FD_CHILD"; + if env::var_os(CHILD).is_some() { + return; + } + + let mut child = Command::new(env::current_exe().unwrap()) + .arg("--exact") + .arg("child_stream_fd_conversions_transfer_ownership") + .env(CHILD, "1") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + let stdin = child.stdin.take().unwrap(); + assert_borrowed_fd(&stdin); + drop(stdio_through_raw_fd(stdin)); + + let stdout = child.stdout.take().unwrap(); + assert_borrowed_fd(&stdout); + drop(stdio_through_owned_fd(stdout)); + + let stderr = child.stderr.take().unwrap(); + assert_borrowed_fd(&stderr); + drop(stdio_through_owned_fd(stderr)); + + assert!(child.wait().unwrap().success()); +}