summaryrefslogtreecommitdiffstats
path: root/tokio/src/process
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/process')
-rw-r--r--tokio/src/process/mod.rs34
-rw-r--r--tokio/src/process/unix/mod.rs58
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 })?))
}