]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/stdio.rs
Rollup merge of #99415 - ferrocene:pa-reuse-initial, r=Mark-Simulacrum
[rust.git] / library / std / src / io / stdio.rs
1 #![cfg_attr(test, allow(unused))]
2
3 #[cfg(test)]
4 mod tests;
5
6 use crate::io::prelude::*;
7
8 use crate::cell::{Cell, RefCell};
9 use crate::fmt;
10 use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
11 use crate::pin::Pin;
12 use crate::sync::atomic::{AtomicBool, Ordering};
13 use crate::sync::{Arc, Mutex, MutexGuard, OnceLock};
14 use crate::sys::stdio;
15 use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
16
17 type LocalStream = Arc<Mutex<Vec<u8>>>;
18
19 thread_local! {
20     /// Used by the test crate to capture the output of the print macros and panics.
21     static OUTPUT_CAPTURE: Cell<Option<LocalStream>> = {
22         Cell::new(None)
23     }
24 }
25
26 /// Flag to indicate OUTPUT_CAPTURE is used.
27 ///
28 /// If it is None and was never set on any thread, this flag is set to false,
29 /// and OUTPUT_CAPTURE can be safely ignored on all threads, saving some time
30 /// and memory registering an unused thread local.
31 ///
32 /// Note about memory ordering: This contains information about whether a
33 /// thread local variable might be in use. Although this is a global flag, the
34 /// memory ordering between threads does not matter: we only want this flag to
35 /// have a consistent order between set_output_capture and print_to *within
36 /// the same thread*. Within the same thread, things always have a perfectly
37 /// consistent order. So Ordering::Relaxed is fine.
38 static OUTPUT_CAPTURE_USED: AtomicBool = AtomicBool::new(false);
39
40 /// A handle to a raw instance of the standard input stream of this process.
41 ///
42 /// This handle is not synchronized or buffered in any fashion. Constructed via
43 /// the `std::io::stdio::stdin_raw` function.
44 struct StdinRaw(stdio::Stdin);
45
46 /// A handle to a raw instance of the standard output stream of this process.
47 ///
48 /// This handle is not synchronized or buffered in any fashion. Constructed via
49 /// the `std::io::stdio::stdout_raw` function.
50 struct StdoutRaw(stdio::Stdout);
51
52 /// A handle to a raw instance of the standard output stream of this process.
53 ///
54 /// This handle is not synchronized or buffered in any fashion. Constructed via
55 /// the `std::io::stdio::stderr_raw` function.
56 struct StderrRaw(stdio::Stderr);
57
58 /// Constructs a new raw handle to the standard input of this process.
59 ///
60 /// The returned handle does not interact with any other handles created nor
61 /// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
62 /// handles is **not** available to raw handles returned from this function.
63 ///
64 /// The returned handle has no external synchronization or buffering.
65 #[unstable(feature = "libstd_sys_internals", issue = "none")]
66 const fn stdin_raw() -> StdinRaw {
67     StdinRaw(stdio::Stdin::new())
68 }
69
70 /// Constructs a new raw handle to the standard output stream of this process.
71 ///
72 /// The returned handle does not interact with any other handles created nor
73 /// handles returned by `std::io::stdout`. Note that data is buffered by the
74 /// `std::io::stdout` handles so writes which happen via this raw handle may
75 /// appear before previous writes.
76 ///
77 /// The returned handle has no external synchronization or buffering layered on
78 /// top.
79 #[unstable(feature = "libstd_sys_internals", issue = "none")]
80 const fn stdout_raw() -> StdoutRaw {
81     StdoutRaw(stdio::Stdout::new())
82 }
83
84 /// Constructs a new raw handle to the standard error stream of this process.
85 ///
86 /// The returned handle does not interact with any other handles created nor
87 /// handles returned by `std::io::stderr`.
88 ///
89 /// The returned handle has no external synchronization or buffering layered on
90 /// top.
91 #[unstable(feature = "libstd_sys_internals", issue = "none")]
92 const fn stderr_raw() -> StderrRaw {
93     StderrRaw(stdio::Stderr::new())
94 }
95
96 impl Read for StdinRaw {
97     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
98         handle_ebadf(self.0.read(buf), 0)
99     }
100
101     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
102         handle_ebadf(self.0.read_vectored(bufs), 0)
103     }
104
105     #[inline]
106     fn is_read_vectored(&self) -> bool {
107         self.0.is_read_vectored()
108     }
109
110     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
111         handle_ebadf(self.0.read_to_end(buf), 0)
112     }
113
114     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
115         handle_ebadf(self.0.read_to_string(buf), 0)
116     }
117 }
118
119 impl Write for StdoutRaw {
120     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
121         handle_ebadf(self.0.write(buf), buf.len())
122     }
123
124     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
125         let total = bufs.iter().map(|b| b.len()).sum();
126         handle_ebadf(self.0.write_vectored(bufs), total)
127     }
128
129     #[inline]
130     fn is_write_vectored(&self) -> bool {
131         self.0.is_write_vectored()
132     }
133
134     fn flush(&mut self) -> io::Result<()> {
135         handle_ebadf(self.0.flush(), ())
136     }
137
138     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
139         handle_ebadf(self.0.write_all(buf), ())
140     }
141
142     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
143         handle_ebadf(self.0.write_all_vectored(bufs), ())
144     }
145
146     fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
147         handle_ebadf(self.0.write_fmt(fmt), ())
148     }
149 }
150
151 impl Write for StderrRaw {
152     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
153         handle_ebadf(self.0.write(buf), buf.len())
154     }
155
156     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
157         let total = bufs.iter().map(|b| b.len()).sum();
158         handle_ebadf(self.0.write_vectored(bufs), total)
159     }
160
161     #[inline]
162     fn is_write_vectored(&self) -> bool {
163         self.0.is_write_vectored()
164     }
165
166     fn flush(&mut self) -> io::Result<()> {
167         handle_ebadf(self.0.flush(), ())
168     }
169
170     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
171         handle_ebadf(self.0.write_all(buf), ())
172     }
173
174     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
175         handle_ebadf(self.0.write_all_vectored(bufs), ())
176     }
177
178     fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
179         handle_ebadf(self.0.write_fmt(fmt), ())
180     }
181 }
182
183 fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
184     match r {
185         Err(ref e) if stdio::is_ebadf(e) => Ok(default),
186         r => r,
187     }
188 }
189
190 /// A handle to the standard input stream of a process.
191 ///
192 /// Each handle is a shared reference to a global buffer of input data to this
193 /// process. A handle can be `lock`'d to gain full access to [`BufRead`] methods
194 /// (e.g., `.lines()`). Reads to this handle are otherwise locked with respect
195 /// to other reads.
196 ///
197 /// This handle implements the `Read` trait, but beware that concurrent reads
198 /// of `Stdin` must be executed with care.
199 ///
200 /// Created by the [`io::stdin`] method.
201 ///
202 /// [`io::stdin`]: stdin
203 ///
204 /// ### Note: Windows Portability Considerations
205 ///
206 /// When operating in a console, the Windows implementation of this stream does not support
207 /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
208 /// an error.
209 ///
210 /// In a process with a detached console, such as one using
211 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
212 /// the contained handle will be null. In such cases, the standard library's `Read` and
213 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
214 /// standard library or via raw Windows API calls, will fail.
215 ///
216 /// # Examples
217 ///
218 /// ```no_run
219 /// use std::io;
220 ///
221 /// fn main() -> io::Result<()> {
222 ///     let mut buffer = String::new();
223 ///     let stdin = io::stdin(); // We get `Stdin` here.
224 ///     stdin.read_line(&mut buffer)?;
225 ///     Ok(())
226 /// }
227 /// ```
228 #[stable(feature = "rust1", since = "1.0.0")]
229 pub struct Stdin {
230     inner: &'static Mutex<BufReader<StdinRaw>>,
231 }
232
233 /// A locked reference to the [`Stdin`] handle.
234 ///
235 /// This handle implements both the [`Read`] and [`BufRead`] traits, and
236 /// is constructed via the [`Stdin::lock`] method.
237 ///
238 /// ### Note: Windows Portability Considerations
239 ///
240 /// When operating in a console, the Windows implementation of this stream does not support
241 /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
242 /// an error.
243 ///
244 /// In a process with a detached console, such as one using
245 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
246 /// the contained handle will be null. In such cases, the standard library's `Read` and
247 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
248 /// standard library or via raw Windows API calls, will fail.
249 ///
250 /// # Examples
251 ///
252 /// ```no_run
253 /// use std::io::{self, BufRead};
254 ///
255 /// fn main() -> io::Result<()> {
256 ///     let mut buffer = String::new();
257 ///     let stdin = io::stdin(); // We get `Stdin` here.
258 ///     {
259 ///         let mut handle = stdin.lock(); // We get `StdinLock` here.
260 ///         handle.read_line(&mut buffer)?;
261 ///     } // `StdinLock` is dropped here.
262 ///     Ok(())
263 /// }
264 /// ```
265 #[must_use = "if unused stdin will immediately unlock"]
266 #[stable(feature = "rust1", since = "1.0.0")]
267 pub struct StdinLock<'a> {
268     inner: MutexGuard<'a, BufReader<StdinRaw>>,
269 }
270
271 /// Constructs a new handle to the standard input of the current process.
272 ///
273 /// Each handle returned is a reference to a shared global buffer whose access
274 /// is synchronized via a mutex. If you need more explicit control over
275 /// locking, see the [`Stdin::lock`] method.
276 ///
277 /// ### Note: Windows Portability Considerations
278 ///
279 /// When operating in a console, the Windows implementation of this stream does not support
280 /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
281 /// an error.
282 ///
283 /// In a process with a detached console, such as one using
284 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
285 /// the contained handle will be null. In such cases, the standard library's `Read` and
286 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
287 /// standard library or via raw Windows API calls, will fail.
288 ///
289 /// # Examples
290 ///
291 /// Using implicit synchronization:
292 ///
293 /// ```no_run
294 /// use std::io;
295 ///
296 /// fn main() -> io::Result<()> {
297 ///     let mut buffer = String::new();
298 ///     io::stdin().read_line(&mut buffer)?;
299 ///     Ok(())
300 /// }
301 /// ```
302 ///
303 /// Using explicit synchronization:
304 ///
305 /// ```no_run
306 /// use std::io::{self, BufRead};
307 ///
308 /// fn main() -> io::Result<()> {
309 ///     let mut buffer = String::new();
310 ///     let stdin = io::stdin();
311 ///     let mut handle = stdin.lock();
312 ///
313 ///     handle.read_line(&mut buffer)?;
314 ///     Ok(())
315 /// }
316 /// ```
317 #[must_use]
318 #[stable(feature = "rust1", since = "1.0.0")]
319 pub fn stdin() -> Stdin {
320     static INSTANCE: OnceLock<Mutex<BufReader<StdinRaw>>> = OnceLock::new();
321     Stdin {
322         inner: INSTANCE.get_or_init(|| {
323             Mutex::new(BufReader::with_capacity(stdio::STDIN_BUF_SIZE, stdin_raw()))
324         }),
325     }
326 }
327
328 impl Stdin {
329     /// Locks this handle to the standard input stream, returning a readable
330     /// guard.
331     ///
332     /// The lock is released when the returned lock goes out of scope. The
333     /// returned guard also implements the [`Read`] and [`BufRead`] traits for
334     /// accessing the underlying data.
335     ///
336     /// # Examples
337     ///
338     /// ```no_run
339     /// use std::io::{self, BufRead};
340     ///
341     /// fn main() -> io::Result<()> {
342     ///     let mut buffer = String::new();
343     ///     let stdin = io::stdin();
344     ///     let mut handle = stdin.lock();
345     ///
346     ///     handle.read_line(&mut buffer)?;
347     ///     Ok(())
348     /// }
349     /// ```
350     #[stable(feature = "rust1", since = "1.0.0")]
351     pub fn lock(&self) -> StdinLock<'static> {
352         // Locks this handle with 'static lifetime. This depends on the
353         // implementation detail that the underlying `Mutex` is static.
354         StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
355     }
356
357     /// Locks this handle and reads a line of input, appending it to the specified buffer.
358     ///
359     /// For detailed semantics of this method, see the documentation on
360     /// [`BufRead::read_line`].
361     ///
362     /// # Examples
363     ///
364     /// ```no_run
365     /// use std::io;
366     ///
367     /// let mut input = String::new();
368     /// match io::stdin().read_line(&mut input) {
369     ///     Ok(n) => {
370     ///         println!("{n} bytes read");
371     ///         println!("{input}");
372     ///     }
373     ///     Err(error) => println!("error: {error}"),
374     /// }
375     /// ```
376     ///
377     /// You can run the example one of two ways:
378     ///
379     /// - Pipe some text to it, e.g., `printf foo | path/to/executable`
380     /// - Give it text interactively by running the executable directly,
381     ///   in which case it will wait for the Enter key to be pressed before
382     ///   continuing
383     #[stable(feature = "rust1", since = "1.0.0")]
384     pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
385         self.lock().read_line(buf)
386     }
387
388     /// Consumes this handle and returns an iterator over input lines.
389     ///
390     /// For detailed semantics of this method, see the documentation on
391     /// [`BufRead::lines`].
392     ///
393     /// # Examples
394     ///
395     /// ```no_run
396     /// use std::io;
397     ///
398     /// let lines = io::stdin().lines();
399     /// for line in lines {
400     ///     println!("got a line: {}", line.unwrap());
401     /// }
402     /// ```
403     #[must_use = "`self` will be dropped if the result is not used"]
404     #[stable(feature = "stdin_forwarders", since = "1.62.0")]
405     pub fn lines(self) -> Lines<StdinLock<'static>> {
406         self.lock().lines()
407     }
408 }
409
410 #[stable(feature = "std_debug", since = "1.16.0")]
411 impl fmt::Debug for Stdin {
412     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
413         f.debug_struct("Stdin").finish_non_exhaustive()
414     }
415 }
416
417 #[stable(feature = "rust1", since = "1.0.0")]
418 impl Read for Stdin {
419     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
420         self.lock().read(buf)
421     }
422     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
423         self.lock().read_vectored(bufs)
424     }
425     #[inline]
426     fn is_read_vectored(&self) -> bool {
427         self.lock().is_read_vectored()
428     }
429     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
430         self.lock().read_to_end(buf)
431     }
432     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
433         self.lock().read_to_string(buf)
434     }
435     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
436         self.lock().read_exact(buf)
437     }
438 }
439
440 // only used by platform-dependent io::copy specializations, i.e. unused on some platforms
441 #[cfg(any(target_os = "linux", target_os = "android"))]
442 impl StdinLock<'_> {
443     pub(crate) fn as_mut_buf(&mut self) -> &mut BufReader<impl Read> {
444         &mut self.inner
445     }
446 }
447
448 #[stable(feature = "rust1", since = "1.0.0")]
449 impl Read for StdinLock<'_> {
450     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
451         self.inner.read(buf)
452     }
453
454     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
455         self.inner.read_vectored(bufs)
456     }
457
458     #[inline]
459     fn is_read_vectored(&self) -> bool {
460         self.inner.is_read_vectored()
461     }
462
463     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
464         self.inner.read_to_end(buf)
465     }
466
467     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
468         self.inner.read_to_string(buf)
469     }
470
471     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
472         self.inner.read_exact(buf)
473     }
474 }
475
476 #[stable(feature = "rust1", since = "1.0.0")]
477 impl BufRead for StdinLock<'_> {
478     fn fill_buf(&mut self) -> io::Result<&[u8]> {
479         self.inner.fill_buf()
480     }
481
482     fn consume(&mut self, n: usize) {
483         self.inner.consume(n)
484     }
485
486     fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
487         self.inner.read_until(byte, buf)
488     }
489
490     fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
491         self.inner.read_line(buf)
492     }
493 }
494
495 #[stable(feature = "std_debug", since = "1.16.0")]
496 impl fmt::Debug for StdinLock<'_> {
497     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
498         f.debug_struct("StdinLock").finish_non_exhaustive()
499     }
500 }
501
502 /// A handle to the global standard output stream of the current process.
503 ///
504 /// Each handle shares a global buffer of data to be written to the standard
505 /// output stream. Access is also synchronized via a lock and explicit control
506 /// over locking is available via the [`lock`] method.
507 ///
508 /// Created by the [`io::stdout`] method.
509 ///
510 /// ### Note: Windows Portability Considerations
511 ///
512 /// When operating in a console, the Windows implementation of this stream does not support
513 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
514 /// an error.
515 ///
516 /// In a process with a detached console, such as one using
517 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
518 /// the contained handle will be null. In such cases, the standard library's `Read` and
519 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
520 /// standard library or via raw Windows API calls, will fail.
521 ///
522 /// [`lock`]: Stdout::lock
523 /// [`io::stdout`]: stdout
524 #[stable(feature = "rust1", since = "1.0.0")]
525 pub struct Stdout {
526     // FIXME: this should be LineWriter or BufWriter depending on the state of
527     //        stdout (tty or not). Note that if this is not line buffered it
528     //        should also flush-on-panic or some form of flush-on-abort.
529     inner: Pin<&'static ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>>,
530 }
531
532 /// A locked reference to the [`Stdout`] handle.
533 ///
534 /// This handle implements the [`Write`] trait, and is constructed via
535 /// the [`Stdout::lock`] method. See its documentation for more.
536 ///
537 /// ### Note: Windows Portability Considerations
538 ///
539 /// When operating in a console, the Windows implementation of this stream does not support
540 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
541 /// an error.
542 ///
543 /// In a process with a detached console, such as one using
544 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
545 /// the contained handle will be null. In such cases, the standard library's `Read` and
546 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
547 /// standard library or via raw Windows API calls, will fail.
548 #[must_use = "if unused stdout will immediately unlock"]
549 #[stable(feature = "rust1", since = "1.0.0")]
550 pub struct StdoutLock<'a> {
551     inner: ReentrantMutexGuard<'a, RefCell<LineWriter<StdoutRaw>>>,
552 }
553
554 static STDOUT: OnceLock<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = OnceLock::new();
555
556 /// Constructs a new handle to the standard output of the current process.
557 ///
558 /// Each handle returned is a reference to a shared global buffer whose access
559 /// is synchronized via a mutex. If you need more explicit control over
560 /// locking, see the [`Stdout::lock`] method.
561 ///
562 /// ### Note: Windows Portability Considerations
563 ///
564 /// When operating in a console, the Windows implementation of this stream does not support
565 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
566 /// an error.
567 ///
568 /// In a process with a detached console, such as one using
569 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
570 /// the contained handle will be null. In such cases, the standard library's `Read` and
571 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
572 /// standard library or via raw Windows API calls, will fail.
573 ///
574 /// # Examples
575 ///
576 /// Using implicit synchronization:
577 ///
578 /// ```no_run
579 /// use std::io::{self, Write};
580 ///
581 /// fn main() -> io::Result<()> {
582 ///     io::stdout().write_all(b"hello world")?;
583 ///
584 ///     Ok(())
585 /// }
586 /// ```
587 ///
588 /// Using explicit synchronization:
589 ///
590 /// ```no_run
591 /// use std::io::{self, Write};
592 ///
593 /// fn main() -> io::Result<()> {
594 ///     let stdout = io::stdout();
595 ///     let mut handle = stdout.lock();
596 ///
597 ///     handle.write_all(b"hello world")?;
598 ///
599 ///     Ok(())
600 /// }
601 /// ```
602 #[must_use]
603 #[stable(feature = "rust1", since = "1.0.0")]
604 pub fn stdout() -> Stdout {
605     Stdout {
606         inner: Pin::static_ref(&STDOUT).get_or_init_pin(
607             || unsafe { ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw()))) },
608             |mutex| unsafe { mutex.init() },
609         ),
610     }
611 }
612
613 pub fn cleanup() {
614     if let Some(instance) = STDOUT.get() {
615         // Flush the data and disable buffering during shutdown
616         // by replacing the line writer by one with zero
617         // buffering capacity.
618         // We use try_lock() instead of lock(), because someone
619         // might have leaked a StdoutLock, which would
620         // otherwise cause a deadlock here.
621         if let Some(lock) = Pin::static_ref(instance).try_lock() {
622             *lock.borrow_mut() = LineWriter::with_capacity(0, stdout_raw());
623         }
624     }
625 }
626
627 impl Stdout {
628     /// Locks this handle to the standard output stream, returning a writable
629     /// guard.
630     ///
631     /// The lock is released when the returned lock goes out of scope. The
632     /// returned guard also implements the `Write` trait for writing data.
633     ///
634     /// # Examples
635     ///
636     /// ```no_run
637     /// use std::io::{self, Write};
638     ///
639     /// fn main() -> io::Result<()> {
640     ///     let mut stdout = io::stdout().lock();
641     ///
642     ///     stdout.write_all(b"hello world")?;
643     ///
644     ///     Ok(())
645     /// }
646     /// ```
647     #[stable(feature = "rust1", since = "1.0.0")]
648     pub fn lock(&self) -> StdoutLock<'static> {
649         // Locks this handle with 'static lifetime. This depends on the
650         // implementation detail that the underlying `ReentrantMutex` is
651         // static.
652         StdoutLock { inner: self.inner.lock() }
653     }
654 }
655
656 #[stable(feature = "std_debug", since = "1.16.0")]
657 impl fmt::Debug for Stdout {
658     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
659         f.debug_struct("Stdout").finish_non_exhaustive()
660     }
661 }
662
663 #[stable(feature = "rust1", since = "1.0.0")]
664 impl Write for Stdout {
665     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
666         (&*self).write(buf)
667     }
668     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
669         (&*self).write_vectored(bufs)
670     }
671     #[inline]
672     fn is_write_vectored(&self) -> bool {
673         io::Write::is_write_vectored(&&*self)
674     }
675     fn flush(&mut self) -> io::Result<()> {
676         (&*self).flush()
677     }
678     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
679         (&*self).write_all(buf)
680     }
681     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
682         (&*self).write_all_vectored(bufs)
683     }
684     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
685         (&*self).write_fmt(args)
686     }
687 }
688
689 #[stable(feature = "write_mt", since = "1.48.0")]
690 impl Write for &Stdout {
691     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
692         self.lock().write(buf)
693     }
694     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
695         self.lock().write_vectored(bufs)
696     }
697     #[inline]
698     fn is_write_vectored(&self) -> bool {
699         self.lock().is_write_vectored()
700     }
701     fn flush(&mut self) -> io::Result<()> {
702         self.lock().flush()
703     }
704     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
705         self.lock().write_all(buf)
706     }
707     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
708         self.lock().write_all_vectored(bufs)
709     }
710     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
711         self.lock().write_fmt(args)
712     }
713 }
714
715 #[stable(feature = "rust1", since = "1.0.0")]
716 impl Write for StdoutLock<'_> {
717     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
718         self.inner.borrow_mut().write(buf)
719     }
720     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
721         self.inner.borrow_mut().write_vectored(bufs)
722     }
723     #[inline]
724     fn is_write_vectored(&self) -> bool {
725         self.inner.borrow_mut().is_write_vectored()
726     }
727     fn flush(&mut self) -> io::Result<()> {
728         self.inner.borrow_mut().flush()
729     }
730     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
731         self.inner.borrow_mut().write_all(buf)
732     }
733     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
734         self.inner.borrow_mut().write_all_vectored(bufs)
735     }
736 }
737
738 #[stable(feature = "std_debug", since = "1.16.0")]
739 impl fmt::Debug for StdoutLock<'_> {
740     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
741         f.debug_struct("StdoutLock").finish_non_exhaustive()
742     }
743 }
744
745 /// A handle to the standard error stream of a process.
746 ///
747 /// For more information, see the [`io::stderr`] method.
748 ///
749 /// [`io::stderr`]: stderr
750 ///
751 /// ### Note: Windows Portability Considerations
752 ///
753 /// When operating in a console, the Windows implementation of this stream does not support
754 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
755 /// an error.
756 ///
757 /// In a process with a detached console, such as one using
758 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
759 /// the contained handle will be null. In such cases, the standard library's `Read` and
760 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
761 /// standard library or via raw Windows API calls, will fail.
762 #[stable(feature = "rust1", since = "1.0.0")]
763 pub struct Stderr {
764     inner: Pin<&'static ReentrantMutex<RefCell<StderrRaw>>>,
765 }
766
767 /// A locked reference to the [`Stderr`] handle.
768 ///
769 /// This handle implements the [`Write`] trait and is constructed via
770 /// the [`Stderr::lock`] method. See its documentation for more.
771 ///
772 /// ### Note: Windows Portability Considerations
773 ///
774 /// When operating in a console, the Windows implementation of this stream does not support
775 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
776 /// an error.
777 ///
778 /// In a process with a detached console, such as one using
779 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
780 /// the contained handle will be null. In such cases, the standard library's `Read` and
781 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
782 /// standard library or via raw Windows API calls, will fail.
783 #[must_use = "if unused stderr will immediately unlock"]
784 #[stable(feature = "rust1", since = "1.0.0")]
785 pub struct StderrLock<'a> {
786     inner: ReentrantMutexGuard<'a, RefCell<StderrRaw>>,
787 }
788
789 /// Constructs a new handle to the standard error of the current process.
790 ///
791 /// This handle is not buffered.
792 ///
793 /// ### Note: Windows Portability Considerations
794 ///
795 /// When operating in a console, the Windows implementation of this stream does not support
796 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
797 /// an error.
798 ///
799 /// In a process with a detached console, such as one using
800 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
801 /// the contained handle will be null. In such cases, the standard library's `Read` and
802 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
803 /// standard library or via raw Windows API calls, will fail.
804 ///
805 /// # Examples
806 ///
807 /// Using implicit synchronization:
808 ///
809 /// ```no_run
810 /// use std::io::{self, Write};
811 ///
812 /// fn main() -> io::Result<()> {
813 ///     io::stderr().write_all(b"hello world")?;
814 ///
815 ///     Ok(())
816 /// }
817 /// ```
818 ///
819 /// Using explicit synchronization:
820 ///
821 /// ```no_run
822 /// use std::io::{self, Write};
823 ///
824 /// fn main() -> io::Result<()> {
825 ///     let stderr = io::stderr();
826 ///     let mut handle = stderr.lock();
827 ///
828 ///     handle.write_all(b"hello world")?;
829 ///
830 ///     Ok(())
831 /// }
832 /// ```
833 #[must_use]
834 #[stable(feature = "rust1", since = "1.0.0")]
835 pub fn stderr() -> Stderr {
836     // Note that unlike `stdout()` we don't use `at_exit` here to register a
837     // destructor. Stderr is not buffered , so there's no need to run a
838     // destructor for flushing the buffer
839     static INSTANCE: OnceLock<ReentrantMutex<RefCell<StderrRaw>>> = OnceLock::new();
840
841     Stderr {
842         inner: Pin::static_ref(&INSTANCE).get_or_init_pin(
843             || unsafe { ReentrantMutex::new(RefCell::new(stderr_raw())) },
844             |mutex| unsafe { mutex.init() },
845         ),
846     }
847 }
848
849 impl Stderr {
850     /// Locks this handle to the standard error stream, returning a writable
851     /// guard.
852     ///
853     /// The lock is released when the returned lock goes out of scope. The
854     /// returned guard also implements the [`Write`] trait for writing data.
855     ///
856     /// # Examples
857     ///
858     /// ```
859     /// use std::io::{self, Write};
860     ///
861     /// fn foo() -> io::Result<()> {
862     ///     let stderr = io::stderr();
863     ///     let mut handle = stderr.lock();
864     ///
865     ///     handle.write_all(b"hello world")?;
866     ///
867     ///     Ok(())
868     /// }
869     /// ```
870     #[stable(feature = "rust1", since = "1.0.0")]
871     pub fn lock(&self) -> StderrLock<'static> {
872         // Locks this handle with 'static lifetime. This depends on the
873         // implementation detail that the underlying `ReentrantMutex` is
874         // static.
875         StderrLock { inner: self.inner.lock() }
876     }
877 }
878
879 #[stable(feature = "std_debug", since = "1.16.0")]
880 impl fmt::Debug for Stderr {
881     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
882         f.debug_struct("Stderr").finish_non_exhaustive()
883     }
884 }
885
886 #[stable(feature = "rust1", since = "1.0.0")]
887 impl Write for Stderr {
888     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
889         (&*self).write(buf)
890     }
891     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
892         (&*self).write_vectored(bufs)
893     }
894     #[inline]
895     fn is_write_vectored(&self) -> bool {
896         io::Write::is_write_vectored(&&*self)
897     }
898     fn flush(&mut self) -> io::Result<()> {
899         (&*self).flush()
900     }
901     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
902         (&*self).write_all(buf)
903     }
904     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
905         (&*self).write_all_vectored(bufs)
906     }
907     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
908         (&*self).write_fmt(args)
909     }
910 }
911
912 #[stable(feature = "write_mt", since = "1.48.0")]
913 impl Write for &Stderr {
914     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
915         self.lock().write(buf)
916     }
917     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
918         self.lock().write_vectored(bufs)
919     }
920     #[inline]
921     fn is_write_vectored(&self) -> bool {
922         self.lock().is_write_vectored()
923     }
924     fn flush(&mut self) -> io::Result<()> {
925         self.lock().flush()
926     }
927     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
928         self.lock().write_all(buf)
929     }
930     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
931         self.lock().write_all_vectored(bufs)
932     }
933     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
934         self.lock().write_fmt(args)
935     }
936 }
937
938 #[stable(feature = "rust1", since = "1.0.0")]
939 impl Write for StderrLock<'_> {
940     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
941         self.inner.borrow_mut().write(buf)
942     }
943     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
944         self.inner.borrow_mut().write_vectored(bufs)
945     }
946     #[inline]
947     fn is_write_vectored(&self) -> bool {
948         self.inner.borrow_mut().is_write_vectored()
949     }
950     fn flush(&mut self) -> io::Result<()> {
951         self.inner.borrow_mut().flush()
952     }
953     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
954         self.inner.borrow_mut().write_all(buf)
955     }
956     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
957         self.inner.borrow_mut().write_all_vectored(bufs)
958     }
959 }
960
961 #[stable(feature = "std_debug", since = "1.16.0")]
962 impl fmt::Debug for StderrLock<'_> {
963     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
964         f.debug_struct("StderrLock").finish_non_exhaustive()
965     }
966 }
967
968 /// Sets the thread-local output capture buffer and returns the old one.
969 #[unstable(
970     feature = "internal_output_capture",
971     reason = "this function is meant for use in the test crate \
972         and may disappear in the future",
973     issue = "none"
974 )]
975 #[doc(hidden)]
976 pub fn set_output_capture(sink: Option<LocalStream>) -> Option<LocalStream> {
977     if sink.is_none() && !OUTPUT_CAPTURE_USED.load(Ordering::Relaxed) {
978         // OUTPUT_CAPTURE is definitely None since OUTPUT_CAPTURE_USED is false.
979         return None;
980     }
981     OUTPUT_CAPTURE_USED.store(true, Ordering::Relaxed);
982     OUTPUT_CAPTURE.with(move |slot| slot.replace(sink))
983 }
984
985 /// Write `args` to the capture buffer if enabled and possible, or `global_s`
986 /// otherwise. `label` identifies the stream in a panic message.
987 ///
988 /// This function is used to print error messages, so it takes extra
989 /// care to avoid causing a panic when `local_s` is unusable.
990 /// For instance, if the TLS key for the local stream is
991 /// already destroyed, or if the local stream is locked by another
992 /// thread, it will just fall back to the global stream.
993 ///
994 /// However, if the actual I/O causes an error, this function does panic.
995 fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
996 where
997     T: Write,
998 {
999     if OUTPUT_CAPTURE_USED.load(Ordering::Relaxed)
1000         && OUTPUT_CAPTURE.try_with(|s| {
1001             // Note that we completely remove a local sink to write to in case
1002             // our printing recursively panics/prints, so the recursive
1003             // panic/print goes to the global sink instead of our local sink.
1004             s.take().map(|w| {
1005                 let _ = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
1006                 s.set(Some(w));
1007             })
1008         }) == Ok(Some(()))
1009     {
1010         // Successfully wrote to capture buffer.
1011         return;
1012     }
1013
1014     if let Err(e) = global_s().write_fmt(args) {
1015         panic!("failed printing to {label}: {e}");
1016     }
1017 }
1018
1019 #[unstable(
1020     feature = "print_internals",
1021     reason = "implementation detail which may disappear or be replaced at any time",
1022     issue = "none"
1023 )]
1024 #[doc(hidden)]
1025 #[cfg(not(test))]
1026 pub fn _print(args: fmt::Arguments<'_>) {
1027     print_to(args, stdout, "stdout");
1028 }
1029
1030 #[unstable(
1031     feature = "print_internals",
1032     reason = "implementation detail which may disappear or be replaced at any time",
1033     issue = "none"
1034 )]
1035 #[doc(hidden)]
1036 #[cfg(not(test))]
1037 pub fn _eprint(args: fmt::Arguments<'_>) {
1038     print_to(args, stderr, "stderr");
1039 }
1040
1041 #[cfg(test)]
1042 pub use realstd::io::{_eprint, _print};