Repository: tokio-rs/tokio
File: tokio/src/process/mod.rs (Rust)

Code before:
    /// # use tokio::process::Command;
    /// # use tokio::sync::oneshot::channel;
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     let (_tx, rx) = channel::<()>();
    ///
    ///     let mut child = Command::new("echo")
    ///         .arg("Hello World!")
    ///         .stdout(Stdio::piped())
    ///         .spawn()
    ///         .unwrap();
    ///
    ///     let mut stdout = child.stdout.take().expect("stdout is not captured");
    ///
    ///     let read_stdout = tokio::spawn(async move {
    ///         let mut buff = Vec::new();
    ///         let _ = stdout.read_to_end(&mut buff).await;
    ///
    ///         buff
    ///     });
    ///
    ///     tokio::select! {
    ///             _ = child.wait() => {}
    ///             _ = rx => { child.kill().await.expect("kill failed") },
    ///     }
    ///
    ///     let buff = read_stdout.await.unwrap();
    ///
    ///     assert_eq!(buff, b"Hello World!\n");
    /// }
    /// ```
    pub async fn kill(&mut self) -> io::Result<()> {
        self.start_kill()?;
        self.wait().await?;
        Ok(())
    }

    /// Waits for the child to exit completely, returning the status that it
    /// exited with. This function will continue to have the same return value
    /// after it has been called at least once.
    ///
    /// 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.
    ///
    /// If the caller wishes to explicitly control when the child's stdin
    /// handle is closed, they may `.take()` it before calling `.wait()`:
    ///
    /// # Cancel safety

Review comment (bug):
Style nit:

```suggestion
    ///     tokio::select! {
    ///         _ = child.wait() => {}
    ///         _ = rx => { child.kill().await.expect("kill failed") },
    ///     }
```

Code after:
    /// # use tokio::process::Command;
    /// # use tokio::sync::oneshot::channel;
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     let (_tx, rx) = channel::<()>();
    ///
    ///     let mut child = Command::new("echo")
    ///         .arg("Hello World!")
    ///         .stdout(Stdio::piped())
    ///         .spawn()
    ///         .unwrap();
    ///
    ///     let mut stdout = child.stdout.take().expect("stdout is not captured");
    ///
    ///     let read_stdout = tokio::spawn(async move {
    ///         let mut buff = Vec::new();
    ///         let _ = stdout.read_to_end(&mut buff).await;
    ///
    ///         buff
    ///     });
    ///
    ///     tokio::select! {
    ///         _ = child.wait() => {}
    ///         _ = rx => { child.kill().await.expect("kill failed") },
    ///     }
    ///
    ///     let buff = read_stdout.await.unwrap();
    ///
    ///     assert_eq!(buff, b"Hello World!\n");
    /// }
    /// ```
    pub async fn kill(&mut self) -> io::Result<()> {
        self.start_kill()?;
        self.wait().await?;
        Ok(())
    }

    /// Waits for the child to exit completely, returning the status that it
    /// exited with. This function will continue to have the same return value
    /// after it has been called at least once.
    ///
    /// 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.
    ///
    /// If the caller wishes to explicitly control when the child's stdin
    /// handle is closed, they may `.take()` it before calling `.wait()`:
    ///
    /// # Cancel safety