• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 mod sys {
77     use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
78 
79     use super::Stdout;
80 
81     impl AsRawFd for Stdout {
as_raw_fd(&self) -> RawFd82         fn as_raw_fd(&self) -> RawFd {
83             std::io::stdout().as_raw_fd()
84         }
85     }
86 
87     impl AsFd for Stdout {
as_fd(&self) -> BorrowedFd<'_>88         fn as_fd(&self) -> BorrowedFd<'_> {
89             unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
90         }
91     }
92 }
93 
94 cfg_windows! {
95     use crate::os::windows::io::{AsHandle, BorrowedHandle, AsRawHandle, RawHandle};
96 
97     impl AsRawHandle for Stdout {
98         fn as_raw_handle(&self) -> RawHandle {
99             std::io::stdout().as_raw_handle()
100         }
101     }
102 
103     impl AsHandle for Stdout {
104         fn as_handle(&self) -> BorrowedHandle<'_> {
105             unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
106         }
107     }
108 }
109 
110 impl AsyncWrite for Stdout {
poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>>111     fn poll_write(
112         mut self: Pin<&mut Self>,
113         cx: &mut Context<'_>,
114         buf: &[u8],
115     ) -> Poll<io::Result<usize>> {
116         Pin::new(&mut self.std).poll_write(cx, buf)
117     }
118 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>>119     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
120         Pin::new(&mut self.std).poll_flush(cx)
121     }
122 
poll_shutdown( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), io::Error>>123     fn poll_shutdown(
124         mut self: Pin<&mut Self>,
125         cx: &mut Context<'_>,
126     ) -> Poll<Result<(), io::Error>> {
127         Pin::new(&mut self.std).poll_shutdown(cx)
128     }
129 }
130