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