pub struct Duplex(_, _);
Expand description
An implementation of Process
that uses tokio::process
as the launcher.
All read and write operations are async.
Note: On *nix platforms, the owned process will have 2 seconds between signals, which is run in a spawned task.
Panics
When, on *nix platforms, a process gets dropped without a runtime.
Implementations
sourceimpl Duplex
impl Duplex
sourcepub fn id(&self) -> Option<u32>
pub fn id(&self) -> Option<u32>
Returns the OS-assigned process identifier associated with this child.
Examples
Basic usage:
use tokio::process::Command;
use pwner::Spawner;
let mut command = Command::new("ls");
if let Ok(child) = command.spawn_owned() {
match child.id() {
Some(pid) => println!("Child's ID is {}", pid),
None => println!("Child has already exited"),
}
} else {
println!("ls command didn't start");
}
sourcepub fn read_from(&mut self, read_source: ReadSource) -> &mut Self
pub fn read_from(&mut self, read_source: ReadSource) -> &mut Self
Choose which pipe to read form next.
Examples
Basic usage:
use tokio::io::AsyncReadExt;
use tokio::process::Command;
use pwner::Spawner;
use pwner::tokio::ReadSource;
let mut child = Command::new("ls").spawn_owned().unwrap();
let mut buffer = [0_u8; 1024];
child.read_from(ReadSource::Both).read(&mut buffer).await.unwrap();
sourcepub async fn wait(self) -> Result<(ExitStatus, ChildStdout, ChildStderr), Error>
pub async fn wait(self) -> Result<(ExitStatus, ChildStdout, ChildStderr), Error>
Waits for the child to exit completely, returning the status with which it exited, stdout, and stderr.
The stdin handle to the child process, if any, will be closed before waiting. This helps avoid deadlock: it ensures that the child does not block waiting for input from the parent, while the parent waits for the child to exit.
Examples
Basic usage:
use pwner::Spawner;
use tokio::io::{AsyncReadExt, BufReader};
use tokio::process::Command;
let child = Command::new("ls").spawn_owned().unwrap();
let (status, stdout, stderr) = child.wait().await.unwrap();
let mut buffer = String::new();
if status.success() {
let mut reader = BufReader::new(stdout);
reader.read_to_string(&mut buffer).await.unwrap();
} else {
let mut reader = BufReader::new(stderr);
reader.read_to_string(&mut buffer).await.unwrap();
}
Errors
Relays the error from tokio::process::Child::wait()
sourcepub fn pipes(&mut self) -> (&mut ChildStdin, &mut ChildStdout, &mut ChildStderr)
pub fn pipes(&mut self) -> (&mut ChildStdin, &mut ChildStdout, &mut ChildStderr)
Decomposes the handle into mutable references to the pipes.
Examples
Basic usage:
use tokio::io::{ AsyncReadExt, AsyncWriteExt };
use tokio::process::Command;
use pwner::Spawner;
let mut child = Command::new("cat").spawn_owned().unwrap();
let mut buffer = [0_u8; 1024];
let (stdin, stdout, _) = child.pipes();
stdin.write_all(b"hello\n").await.unwrap();
stdout.read(&mut buffer).await.unwrap();
sourcepub fn decompose(self) -> (Simplex, Output)
pub fn decompose(self) -> (Simplex, Output)
Separates the process and its input from the output pipes. Ownership is retained by a
Simplex
which still implements a graceful drop of the child process.
Examples
Basic usage:
use tokio::io::{ AsyncReadExt, AsyncWriteExt };
use tokio::process::Command;
use pwner::Spawner;
let child = Command::new("cat").spawn_owned().unwrap();
let (mut input_only_process, mut output) = child.decompose();
// Spawn printing task
tokio::spawn(async move {
let mut buffer = [0; 1024];
while let Ok(bytes) = output.read(&mut buffer).await {
if let Ok(string) = std::str::from_utf8(&buffer[..bytes]) {
print!("{}", string);
}
}
});
// Interact normally with the child process
input_only_process.write_all(b"hello\n").await.unwrap();
sourcepub fn eject(self) -> (Child, ChildStdin, ChildStdout, ChildStderr)
pub fn eject(self) -> (Child, ChildStdin, ChildStdout, ChildStderr)
Completely releases the ownership of the child process. The raw underlying process and pipes are returned and no wrapping function is applicable any longer.
Note: By ejecting the process, graceful drop will no longer be available.
Examples
Basic usage:
use tokio::io::{ AsyncReadExt, AsyncWriteExt };
use tokio::process::Command;
use pwner::Spawner;
let mut child = Command::new("cat").spawn_owned().unwrap();
let mut buffer = [0_u8; 1024];
let (process, mut stdin, mut stdout, _) = child.eject();
stdin.write_all(b"hello\n").await.unwrap();
stdout.read(&mut buffer).await.unwrap();
// Graceful drop will not be executed for `child` as the ejected variable leaves scope here
sourcepub async fn shutdown(self) -> Result<ExitStatus>
pub async fn shutdown(self) -> Result<ExitStatus>
Consumes the process to allow awaiting for shutdown.
This method is essentially the same as a drop
, however it return a Future
which allows
the parent to await the shutdown.
Examples
Basic usage:
use tokio::process::Command;
use pwner::Spawner;
let child = Command::new("top").spawn_owned().unwrap();
child.shutdown().await.unwrap();
Errors
std::io::Error
if failure when killing the process.
Trait Implementations
sourceimpl AsyncWrite for Duplex
impl AsyncWrite for Duplex
sourcefn poll_write(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize>>
fn poll_write(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize>>
buf
into the object. Read moresourcefn poll_flush(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
fn poll_flush(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
sourcefn poll_shutdown(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
fn poll_shutdown(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
sourcefn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>]
) -> Poll<Result<usize, Error>>
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>]
) -> Poll<Result<usize, Error>>
poll_write
, except that it writes from a slice of buffers. Read moresourcefn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
poll_write_vectored
implementation. Read moreimpl Process for Duplex
Auto Trait Implementations
impl !RefUnwindSafe for Duplex
impl Send for Duplex
impl Sync for Duplex
impl Unpin for Duplex
impl !UnwindSafe for Duplex
Blanket Implementations
sourceimpl<R> AsyncReadExt for Rwhere
R: AsyncRead + ?Sized,
impl<R> AsyncReadExt for Rwhere
R: AsyncRead + ?Sized,
sourcefn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>where
Self: Unpin,
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>where
Self: Unpin,
sourcefn read_buf<B, 'a>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>where
Self: Sized + Unpin,
B: BufMut,
fn read_buf<B, 'a>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>where
Self: Sized + Unpin,
B: BufMut,
sourcefn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>where
Self: Unpin,
fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>where
Self: Unpin,
buf
. Read moresourcefn read_u8<'a>(&'a mut self) -> ReadU8<&'a mut Self>where
Self: Unpin,
fn read_u8<'a>(&'a mut self) -> ReadU8<&'a mut Self>where
Self: Unpin,
sourcefn read_i8<'a>(&'a mut self) -> ReadI8<&'a mut Self>where
Self: Unpin,
fn read_i8<'a>(&'a mut self) -> ReadI8<&'a mut Self>where
Self: Unpin,
sourcefn read_u16<'a>(&'a mut self) -> ReadU16<&'a mut Self>where
Self: Unpin,
fn read_u16<'a>(&'a mut self) -> ReadU16<&'a mut Self>where
Self: Unpin,
sourcefn read_i16<'a>(&'a mut self) -> ReadI16<&'a mut Self>where
Self: Unpin,
fn read_i16<'a>(&'a mut self) -> ReadI16<&'a mut Self>where
Self: Unpin,
sourcefn read_u32<'a>(&'a mut self) -> ReadU32<&'a mut Self>where
Self: Unpin,
fn read_u32<'a>(&'a mut self) -> ReadU32<&'a mut Self>where
Self: Unpin,
sourcefn read_i32<'a>(&'a mut self) -> ReadI32<&'a mut Self>where
Self: Unpin,
fn read_i32<'a>(&'a mut self) -> ReadI32<&'a mut Self>where
Self: Unpin,
sourcefn read_u64<'a>(&'a mut self) -> ReadU64<&'a mut Self>where
Self: Unpin,
fn read_u64<'a>(&'a mut self) -> ReadU64<&'a mut Self>where
Self: Unpin,
sourcefn read_i64<'a>(&'a mut self) -> ReadI64<&'a mut Self>where
Self: Unpin,
fn read_i64<'a>(&'a mut self) -> ReadI64<&'a mut Self>where
Self: Unpin,
sourcefn read_u128<'a>(&'a mut self) -> ReadU128<&'a mut Self>where
Self: Unpin,
fn read_u128<'a>(&'a mut self) -> ReadU128<&'a mut Self>where
Self: Unpin,
sourcefn read_i128<'a>(&'a mut self) -> ReadI128<&'a mut Self>where
Self: Unpin,
fn read_i128<'a>(&'a mut self) -> ReadI128<&'a mut Self>where
Self: Unpin,
sourcefn read_f32<'a>(&'a mut self) -> ReadF32<&'a mut Self>where
Self: Unpin,
fn read_f32<'a>(&'a mut self) -> ReadF32<&'a mut Self>where
Self: Unpin,
sourcefn read_f64<'a>(&'a mut self) -> ReadF64<&'a mut Self>where
Self: Unpin,
fn read_f64<'a>(&'a mut self) -> ReadF64<&'a mut Self>where
Self: Unpin,
sourcefn read_u16_le<'a>(&'a mut self) -> ReadU16Le<&'a mut Self>where
Self: Unpin,
fn read_u16_le<'a>(&'a mut self) -> ReadU16Le<&'a mut Self>where
Self: Unpin,
sourcefn read_i16_le<'a>(&'a mut self) -> ReadI16Le<&'a mut Self>where
Self: Unpin,
fn read_i16_le<'a>(&'a mut self) -> ReadI16Le<&'a mut Self>where
Self: Unpin,
sourcefn read_u32_le<'a>(&'a mut self) -> ReadU32Le<&'a mut Self>where
Self: Unpin,
fn read_u32_le<'a>(&'a mut self) -> ReadU32Le<&'a mut Self>where
Self: Unpin,
sourcefn read_i32_le<'a>(&'a mut self) -> ReadI32Le<&'a mut Self>where
Self: Unpin,
fn read_i32_le<'a>(&'a mut self) -> ReadI32Le<&'a mut Self>where
Self: Unpin,
sourcefn read_u64_le<'a>(&'a mut self) -> ReadU64Le<&'a mut Self>where
Self: Unpin,
fn read_u64_le<'a>(&'a mut self) -> ReadU64Le<&'a mut Self>where
Self: Unpin,
sourcefn read_i64_le<'a>(&'a mut self) -> ReadI64Le<&'a mut Self>where
Self: Unpin,
fn read_i64_le<'a>(&'a mut self) -> ReadI64Le<&'a mut Self>where
Self: Unpin,
sourcefn read_u128_le<'a>(&'a mut self) -> ReadU128Le<&'a mut Self>where
Self: Unpin,
fn read_u128_le<'a>(&'a mut self) -> ReadU128Le<&'a mut Self>where
Self: Unpin,
sourcefn read_i128_le<'a>(&'a mut self) -> ReadI128Le<&'a mut Self>where
Self: Unpin,
fn read_i128_le<'a>(&'a mut self) -> ReadI128Le<&'a mut Self>where
Self: Unpin,
sourcefn read_f32_le<'a>(&'a mut self) -> ReadF32Le<&'a mut Self>where
Self: Unpin,
fn read_f32_le<'a>(&'a mut self) -> ReadF32Le<&'a mut Self>where
Self: Unpin,
sourcefn read_f64_le<'a>(&'a mut self) -> ReadF64Le<&'a mut Self>where
Self: Unpin,
fn read_f64_le<'a>(&'a mut self) -> ReadF64Le<&'a mut Self>where
Self: Unpin,
sourcefn read_to_end<'a>(
&'a mut self,
buf: &'a mut Vec<u8, Global>
) -> ReadToEnd<'a, Self>where
Self: Unpin,
fn read_to_end<'a>(
&'a mut self,
buf: &'a mut Vec<u8, Global>
) -> ReadToEnd<'a, Self>where
Self: Unpin,
buf
. Read moresourcefn read_to_string<'a>(
&'a mut self,
dst: &'a mut String
) -> ReadToString<'a, Self>where
Self: Unpin,
fn read_to_string<'a>(
&'a mut self,
dst: &'a mut String
) -> ReadToString<'a, Self>where
Self: Unpin,
buf
. Read more