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