diff options
Diffstat (limited to 'tokio/src/process')
-rw-r--r-- | tokio/src/process/mod.rs | 34 | ||||
-rw-r--r-- | tokio/src/process/unix/mod.rs | 58 |
2 files changed, 44 insertions, 48 deletions
diff --git a/tokio/src/process/mod.rs b/tokio/src/process/mod.rs index ad64371a..bd23e1f7 100644 --- a/tokio/src/process/mod.rs +++ b/tokio/src/process/mod.rs @@ -1038,39 +1038,41 @@ pub struct ChildStderr { impl AsyncWrite for ChildStdin { fn poll_write( - mut self: Pin<&mut Self>, + self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>> { - Pin::new(&mut self.inner).poll_write(cx, buf) + self.inner.poll_write(cx, buf) } - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> { - Pin::new(&mut self.inner).poll_flush(cx) + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { + Poll::Ready(Ok(())) } - fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> { - Pin::new(&mut self.inner).poll_shutdown(cx) + fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { + Poll::Ready(Ok(())) } } impl AsyncRead for ChildStdout { fn poll_read( - mut self: Pin<&mut Self>, + self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>> { - Pin::new(&mut self.inner).poll_read(cx, buf) + // Safety: pipes support reading into uninitialized memory + unsafe { self.inner.poll_read(cx, buf) } } } impl AsyncRead for ChildStderr { fn poll_read( - mut self: Pin<&mut Self>, + self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>> { - Pin::new(&mut self.inner).poll_read(cx, buf) + // Safety: pipes support reading into uninitialized memory + unsafe { self.inner.poll_read(cx, buf) } } } @@ -1082,19 +1084,19 @@ mod sys { impl AsRawFd for ChildStdin { fn as_raw_fd(&self) -> RawFd { - self.inner.get_ref().as_raw_fd() + self.inner.as_raw_fd() } } impl AsRawFd for ChildStdout { fn as_raw_fd(&self) -> RawFd { - self.inner.get_ref().as_raw_fd() + self.inner.as_raw_fd() } } impl AsRawFd for ChildStderr { fn as_raw_fd(&self) -> RawFd { - self.inner.get_ref().as_raw_fd() + self.inner.as_raw_fd() } } } @@ -1107,19 +1109,19 @@ mod sys { impl AsRawHandle for ChildStdin { fn as_raw_handle(&self) -> RawHandle { - self.inner.get_ref().as_raw_handle() + self.inner.as_raw_handle() } } impl AsRawHandle for ChildStdout { fn as_raw_handle(&self) -> RawHandle { - self.inner.get_ref().as_raw_handle() + self.inner.as_raw_handle() } } impl AsRawHandle for ChildStderr { fn as_raw_handle(&self) -> RawHandle { - self.inner.get_ref().as_raw_handle() + self.inner.as_raw_handle() } } } diff --git a/tokio/src/process/unix/mod.rs b/tokio/src/process/unix/mod.rs index db9d592c..6e970ee8 100644 --- a/tokio/src/process/unix/mod.rs +++ b/tokio/src/process/unix/mod.rs @@ -37,9 +37,10 @@ use crate::signal::unix::{signal, Signal, SignalKind}; use mio::event::Source; use mio::unix::SourceFd; use std::fmt; +use std::fs::File; use std::future::Future; use std::io; -use std::os::unix::io::{AsRawFd, RawFd}; +use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; use std::pin::Pin; use std::process::{Child as StdChild, ExitStatus}; use std::task::Context; @@ -141,45 +142,35 @@ impl Future for Child { } #[derive(Debug)] -pub(crate) struct Fd<T> { - inner: T, +pub(crate) struct Pipe { + // Actually a pipe and not a File. However, we are reusing `File` to get + // close on drop. This is a similar trick as `mio`. + fd: File, } -impl<T> io::Read for Fd<T> -where - T: io::Read, -{ +impl<'a> io::Read for &'a Pipe { fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> { - self.inner.read(bytes) + (&self.fd).read(bytes) } } -impl<T> io::Write for Fd<T> -where - T: io::Write, -{ +impl<'a> io::Write for &'a Pipe { fn write(&mut self, bytes: &[u8]) -> io::Result<usize> { - self.inner.write(bytes) + (&self.fd).write(bytes) } fn flush(&mut self) -> io::Result<()> { - self.inner.flush() + (&self.fd).flush() } } -impl<T> AsRawFd for Fd<T> -where - T: AsRawFd, -{ +impl AsRawFd for Pipe { fn as_raw_fd(&self) -> RawFd { - self.inner.as_raw_fd() + self.fd.as_raw_fd() } } -impl<T> Source for Fd<T> -where - T: AsRawFd, -{ +impl Source for Pipe { fn register( &mut self, registry: &mio::Registry, @@ -203,13 +194,13 @@ where } } -pub(crate) type ChildStdin = PollEvented<Fd<std::process::ChildStdin>>; -pub(crate) type ChildStdout = PollEvented<Fd<std::process::ChildStdout>>; -pub(crate) type ChildStderr = PollEvented<Fd<std::process::ChildStderr>>; +pub(crate) type ChildStdin = PollEvented<Pipe>; +pub(crate) type ChildStdout = PollEvented<Pipe>; +pub(crate) type ChildStderr = PollEvented<Pipe>; -fn stdio<T>(option: Option<T>) -> io::Result<Option<PollEvented<Fd<T>>>> +fn stdio<T>(option: Option<T>) -> io::Result<Option<PollEvented<Pipe>>> where - T: AsRawFd, + T: IntoRawFd, { let io = match option { Some(io) => io, @@ -217,8 +208,8 @@ where }; // Set the fd to nonblocking before we pass it to the event loop - unsafe { - let fd = io.as_raw_fd(); + let fd = unsafe { + let fd = io.into_raw_fd(); let r = libc::fcntl(fd, libc::F_GETFL); if r == -1 { return Err(io::Error::last_os_error()); @@ -227,6 +218,9 @@ where if r == -1 { return Err(io::Error::last_os_error()); } - } - Ok(Some(PollEvented::new(Fd { inner: io })?)) + + File::from_raw_fd(fd) + }; + + Ok(Some(PollEvented::new(Pipe { fd })?)) } |