std/io/
stdio.rs

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