1 use crate::io::blocking::Blocking;
2 use crate::io::stdio_common::SplitByUtf8BoundaryIfWindows;
3 use crate::io::AsyncWrite;
4 use std::io;
5 use std::pin::Pin;
6 use std::task::Context;
7 use std::task::Poll;
8 
9 cfg_io_std! {
10     /// A handle to the standard output stream of a process.
11     ///
12     /// Concurrent writes to stdout must be executed with care: Only individual
13     /// writes to this [`AsyncWrite`] are guaranteed to be intact. In particular
14     /// you should be aware that writes using [`write_all`] are not guaranteed
15     /// to occur as a single write, so multiple threads writing data with
16     /// [`write_all`] may result in interleaved output.
17     ///
18     /// Created by the [`stdout`] function.
19     ///
20     /// [`stdout`]: stdout()
21     /// [`AsyncWrite`]: AsyncWrite
22     /// [`write_all`]: crate::io::AsyncWriteExt::write_all()
23     ///
24     /// # Examples
25     ///
26     /// ```
27     /// use tokio::io::{self, AsyncWriteExt};
28     ///
29     /// #[tokio::main]
30     /// async fn main() -> io::Result<()> {
31     ///     let mut stdout = io::stdout();
32     ///     stdout.write_all(b"Hello world!").await?;
33     ///     Ok(())
34     /// }
35     /// ```
36     #[derive(Debug)]
37     pub struct Stdout {
38         std: SplitByUtf8BoundaryIfWindows<Blocking<std::io::Stdout>>,
39     }
40 
41     /// Constructs a new handle to the standard output of the current process.
42     ///
43     /// The returned handle allows writing to standard out from the within the
44     /// Tokio runtime.
45     ///
46     /// Concurrent writes to stdout must be executed with care: Only individual
47     /// writes to this [`AsyncWrite`] are guaranteed to be intact. In particular
48     /// you should be aware that writes using [`write_all`] are not guaranteed
49     /// to occur as a single write, so multiple threads writing data with
50     /// [`write_all`] may result in interleaved output.
51     ///
52     /// [`AsyncWrite`]: AsyncWrite
53     /// [`write_all`]: crate::io::AsyncWriteExt::write_all()
54     ///
55     /// # Examples
56     ///
57     /// ```
58     /// use tokio::io::{self, AsyncWriteExt};
59     ///
60     /// #[tokio::main]
61     /// async fn main() -> io::Result<()> {
62     ///     let mut stdout = io::stdout();
63     ///     stdout.write_all(b"Hello world!").await?;
64     ///     Ok(())
65     /// }
66     /// ```
67     pub fn stdout() -> Stdout {
68         let std = io::stdout();
69         Stdout {
70             std: SplitByUtf8BoundaryIfWindows::new(Blocking::new(std)),
71         }
72     }
73 }
74 
75 #[cfg(unix)]
76 impl std::os::unix::io::AsRawFd for Stdout {
as_raw_fd(&self) -> std::os::unix::io::RawFd77     fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
78         std::io::stdout().as_raw_fd()
79     }
80 }
81 
82 #[cfg(windows)]
83 impl std::os::windows::io::AsRawHandle for Stdout {
as_raw_handle(&self) -> std::os::windows::io::RawHandle84     fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
85         std::io::stdout().as_raw_handle()
86     }
87 }
88 
89 impl AsyncWrite for Stdout {
poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>>90     fn poll_write(
91         mut self: Pin<&mut Self>,
92         cx: &mut Context<'_>,
93         buf: &[u8],
94     ) -> Poll<io::Result<usize>> {
95         Pin::new(&mut self.std).poll_write(cx, buf)
96     }
97 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>>98     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
99         Pin::new(&mut self.std).poll_flush(cx)
100     }
101 
poll_shutdown( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), io::Error>>102     fn poll_shutdown(
103         mut self: Pin<&mut Self>,
104         cx: &mut Context<'_>,
105     ) -> Poll<Result<(), io::Error>> {
106         Pin::new(&mut self.std).poll_shutdown(cx)
107     }
108 }
109