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