Skip to content

Commit

Permalink
process: add from_std to ChildStd* (#4045)
Browse files Browse the repository at this point in the history
  • Loading branch information
Darksonn authored Aug 19, 2021
1 parent 8aa2bfe commit 2bc9a42
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 31 deletions.
57 changes: 51 additions & 6 deletions tokio/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,9 @@ pub struct Command {

pub(crate) struct SpawnedChild {
child: imp::Child,
stdin: Option<imp::ChildStdin>,
stdout: Option<imp::ChildStdout>,
stderr: Option<imp::ChildStderr>,
stdin: Option<imp::ChildStdio>,
stdout: Option<imp::ChildStdio>,
stderr: Option<imp::ChildStdio>,
}

impl Command {
Expand Down Expand Up @@ -1151,7 +1151,7 @@ impl Child {
/// handle of a child process asynchronously.
#[derive(Debug)]
pub struct ChildStdin {
inner: imp::ChildStdin,
inner: imp::ChildStdio,
}

/// The standard output stream for spawned children.
Expand All @@ -1160,7 +1160,7 @@ pub struct ChildStdin {
/// handle of a child process asynchronously.
#[derive(Debug)]
pub struct ChildStdout {
inner: imp::ChildStdout,
inner: imp::ChildStdio,
}

/// The standard error stream for spawned children.
Expand All @@ -1169,7 +1169,52 @@ pub struct ChildStdout {
/// handle of a child process asynchronously.
#[derive(Debug)]
pub struct ChildStderr {
inner: imp::ChildStderr,
inner: imp::ChildStdio,
}

impl ChildStdin {
/// Create an asynchronous `ChildStdin` from a synchronous one.
///
/// # Errors
///
/// This method may fail if an error is encountered when setting the pipe to
/// non-blocking mode, or when registering the pipe with the runtime's IO
/// driver.
pub fn from_std(inner: std::process::ChildStdin) -> io::Result<Self> {
Ok(Self {
inner: imp::stdio(inner)?,
})
}
}

impl ChildStdout {
/// Create an asynchronous `ChildStderr` from a synchronous one.
///
/// # Errors
///
/// This method may fail if an error is encountered when setting the pipe to
/// non-blocking mode, or when registering the pipe with the runtime's IO
/// driver.
pub fn from_std(inner: std::process::ChildStdout) -> io::Result<Self> {
Ok(Self {
inner: imp::stdio(inner)?,
})
}
}

impl ChildStderr {
/// Create an asynchronous `ChildStderr` from a synchronous one.
///
/// # Errors
///
/// This method may fail if an error is encountered when setting the pipe to
/// non-blocking mode, or when registering the pipe with the runtime's IO
/// driver.
pub fn from_std(inner: std::process::ChildStderr) -> io::Result<Self> {
Ok(Self {
inner: imp::stdio(inner)?,
})
}
}

impl AsyncWrite for ChildStdin {
Expand Down
19 changes: 6 additions & 13 deletions tokio/src/process/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ impl fmt::Debug for Child {

pub(crate) fn spawn_child(cmd: &mut std::process::Command) -> io::Result<SpawnedChild> {
let mut child = cmd.spawn()?;
let stdin = stdio(child.stdin.take())?;
let stdout = stdio(child.stdout.take())?;
let stderr = stdio(child.stderr.take())?;
let stdin = child.stdin.take().map(stdio).transpose()?;
let stdout = child.stdout.take().map(stdio).transpose()?;
let stderr = child.stderr.take().map(stdio).transpose()?;

let signal = signal(SignalKind::child())?;

Expand Down Expand Up @@ -213,9 +213,7 @@ impl Source for Pipe {
}
}

pub(crate) type ChildStdin = PollEvented<Pipe>;
pub(crate) type ChildStdout = PollEvented<Pipe>;
pub(crate) type ChildStderr = PollEvented<Pipe>;
pub(crate) type ChildStdio = PollEvented<Pipe>;

fn set_nonblocking<T: AsRawFd>(fd: &mut T, nonblocking: bool) -> io::Result<()> {
unsafe {
Expand All @@ -240,18 +238,13 @@ fn set_nonblocking<T: AsRawFd>(fd: &mut T, nonblocking: bool) -> io::Result<()>
Ok(())
}

fn stdio<T>(option: Option<T>) -> io::Result<Option<PollEvented<Pipe>>>
pub(super) fn stdio<T>(io: T) -> io::Result<PollEvented<Pipe>>
where
T: IntoRawFd,
{
let io = match option {
Some(io) => io,
None => return Ok(None),
};

// Set the fd to nonblocking before we pass it to the event loop
let mut pipe = Pipe::from(io);
set_nonblocking(&mut pipe, true)?;

Ok(Some(PollEvented::new(pipe)?))
PollEvented::new(pipe)
}
18 changes: 6 additions & 12 deletions tokio/src/process/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ unsafe impl Send for Waiting {}

pub(crate) fn spawn_child(cmd: &mut StdCommand) -> io::Result<SpawnedChild> {
let mut child = cmd.spawn()?;
let stdin = stdio(child.stdin.take());
let stdout = stdio(child.stdout.take());
let stderr = stdio(child.stderr.take());
let stdin = child.stdin.take().map(stdio).transpose()?;
let stdout = child.stdout.take().map(stdio).transpose()?;
let stderr = child.stderr.take().map(stdio).transpose()?;

Ok(SpawnedChild {
child: Child {
Expand Down Expand Up @@ -167,20 +167,14 @@ unsafe extern "system" fn callback(ptr: PVOID, _timer_fired: BOOLEAN) {
let _ = complete.take().unwrap().send(());
}

pub(crate) type ChildStdin = PollEvented<NamedPipe>;
pub(crate) type ChildStdout = PollEvented<NamedPipe>;
pub(crate) type ChildStderr = PollEvented<NamedPipe>;
pub(crate) type ChildStdio = PollEvented<NamedPipe>;

fn stdio<T>(option: Option<T>) -> Option<PollEvented<NamedPipe>>
pub(super) fn stdio<T>(io: T) -> io::Result<PollEvented<NamedPipe>>
where
T: IntoRawHandle,
{
let io = match option {
Some(io) => io,
None => return None,
};
let pipe = unsafe { NamedPipe::from_raw_handle(io.into_raw_handle()) };
PollEvented::new(pipe).ok()
PollEvented::new(pipe)
}

pub(crate) fn convert_to_stdio(io: PollEvented<NamedPipe>) -> io::Result<Stdio> {
Expand Down

0 comments on commit 2bc9a42

Please sign in to comment.