1 use crate::io::blocking::Blocking; 2 use crate::io::AsyncWrite; 3 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 error stream of a process. 11 /// 12 /// Concurrent writes to stderr 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 [`stderr`] function. 19 /// 20 /// [`stderr`]: stderr() 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 stderr = io::stdout(); 32 /// stderr.write_all(b"Print some error here.").await?; 33 /// Ok(()) 34 /// } 35 /// ``` 36 #[derive(Debug)] 37 pub struct Stderr { 38 std: Blocking<std::io::Stderr>, 39 } 40 41 /// Constructs a new handle to the standard error of the current process. 42 /// 43 /// The returned handle allows writing to standard error from the within the 44 /// Tokio runtime. 45 /// 46 /// Concurrent writes to stderr 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 stderr = io::stdout(); 63 /// stderr.write_all(b"Print some error here.").await?; 64 /// Ok(()) 65 /// } 66 /// ``` 67 pub fn stderr() -> Stderr { 68 let std = io::stderr(); 69 Stderr { 70 std: Blocking::new(std), 71 } 72 } 73 } 74 75 #[cfg(unix)] 76 impl std::os::unix::io::AsRawFd for Stderr { as_raw_fd(&self) -> std::os::unix::io::RawFd77 fn as_raw_fd(&self) -> std::os::unix::io::RawFd { 78 std::io::stderr().as_raw_fd() 79 } 80 } 81 82 #[cfg(windows)] 83 impl std::os::windows::io::AsRawHandle for Stderr { as_raw_handle(&self) -> std::os::windows::io::RawHandle84 fn as_raw_handle(&self) -> std::os::windows::io::RawHandle { 85 std::io::stderr().as_raw_handle() 86 } 87 } 88 89 impl AsyncWrite for Stderr { 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