]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/stdio.rs
Rollup merge of #101967 - jmillikin:linux-abstract-socket-addr, r=joshtriplett
[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::fs::File;
11 use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
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: &'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: STDOUT
607             .get_or_init(|| ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw())))),
608     }
609 }
610
611 // Flush the data and disable buffering during shutdown
612 // by replacing the line writer by one with zero
613 // buffering capacity.
614 pub fn cleanup() {
615     let mut initialized = false;
616     let stdout = STDOUT.get_or_init(|| {
617         initialized = true;
618         ReentrantMutex::new(RefCell::new(LineWriter::with_capacity(0, stdout_raw())))
619     });
620
621     if !initialized {
622         // The buffer was previously initialized, overwrite it here.
623         // We use try_lock() instead of lock(), because someone
624         // might have leaked a StdoutLock, which would
625         // otherwise cause a deadlock here.
626         if let Some(lock) = stdout.try_lock() {
627             *lock.borrow_mut() = LineWriter::with_capacity(0, stdout_raw());
628         }
629     }
630 }
631
632 impl Stdout {
633     /// Locks this handle to the standard output stream, returning a writable
634     /// guard.
635     ///
636     /// The lock is released when the returned lock goes out of scope. The
637     /// returned guard also implements the `Write` trait for writing data.
638     ///
639     /// # Examples
640     ///
641     /// ```no_run
642     /// use std::io::{self, Write};
643     ///
644     /// fn main() -> io::Result<()> {
645     ///     let mut stdout = io::stdout().lock();
646     ///
647     ///     stdout.write_all(b"hello world")?;
648     ///
649     ///     Ok(())
650     /// }
651     /// ```
652     #[stable(feature = "rust1", since = "1.0.0")]
653     pub fn lock(&self) -> StdoutLock<'static> {
654         // Locks this handle with 'static lifetime. This depends on the
655         // implementation detail that the underlying `ReentrantMutex` is
656         // static.
657         StdoutLock { inner: self.inner.lock() }
658     }
659 }
660
661 #[stable(feature = "std_debug", since = "1.16.0")]
662 impl fmt::Debug for Stdout {
663     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
664         f.debug_struct("Stdout").finish_non_exhaustive()
665     }
666 }
667
668 #[stable(feature = "rust1", since = "1.0.0")]
669 impl Write for Stdout {
670     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
671         (&*self).write(buf)
672     }
673     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
674         (&*self).write_vectored(bufs)
675     }
676     #[inline]
677     fn is_write_vectored(&self) -> bool {
678         io::Write::is_write_vectored(&&*self)
679     }
680     fn flush(&mut self) -> io::Result<()> {
681         (&*self).flush()
682     }
683     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
684         (&*self).write_all(buf)
685     }
686     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
687         (&*self).write_all_vectored(bufs)
688     }
689     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
690         (&*self).write_fmt(args)
691     }
692 }
693
694 #[stable(feature = "write_mt", since = "1.48.0")]
695 impl Write for &Stdout {
696     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
697         self.lock().write(buf)
698     }
699     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
700         self.lock().write_vectored(bufs)
701     }
702     #[inline]
703     fn is_write_vectored(&self) -> bool {
704         self.lock().is_write_vectored()
705     }
706     fn flush(&mut self) -> io::Result<()> {
707         self.lock().flush()
708     }
709     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
710         self.lock().write_all(buf)
711     }
712     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
713         self.lock().write_all_vectored(bufs)
714     }
715     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
716         self.lock().write_fmt(args)
717     }
718 }
719
720 #[stable(feature = "rust1", since = "1.0.0")]
721 impl Write for StdoutLock<'_> {
722     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
723         self.inner.borrow_mut().write(buf)
724     }
725     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
726         self.inner.borrow_mut().write_vectored(bufs)
727     }
728     #[inline]
729     fn is_write_vectored(&self) -> bool {
730         self.inner.borrow_mut().is_write_vectored()
731     }
732     fn flush(&mut self) -> io::Result<()> {
733         self.inner.borrow_mut().flush()
734     }
735     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
736         self.inner.borrow_mut().write_all(buf)
737     }
738     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
739         self.inner.borrow_mut().write_all_vectored(bufs)
740     }
741 }
742
743 #[stable(feature = "std_debug", since = "1.16.0")]
744 impl fmt::Debug for StdoutLock<'_> {
745     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
746         f.debug_struct("StdoutLock").finish_non_exhaustive()
747     }
748 }
749
750 /// A handle to the standard error stream of a process.
751 ///
752 /// For more information, see the [`io::stderr`] method.
753 ///
754 /// [`io::stderr`]: stderr
755 ///
756 /// ### Note: Windows Portability Considerations
757 ///
758 /// When operating in a console, the Windows implementation of this stream does not support
759 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
760 /// an error.
761 ///
762 /// In a process with a detached console, such as one using
763 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
764 /// the contained handle will be null. In such cases, the standard library's `Read` and
765 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
766 /// standard library or via raw Windows API calls, will fail.
767 #[stable(feature = "rust1", since = "1.0.0")]
768 pub struct Stderr {
769     inner: &'static ReentrantMutex<RefCell<StderrRaw>>,
770 }
771
772 /// A locked reference to the [`Stderr`] handle.
773 ///
774 /// This handle implements the [`Write`] trait and is constructed via
775 /// the [`Stderr::lock`] method. See its documentation for more.
776 ///
777 /// ### Note: Windows Portability Considerations
778 ///
779 /// When operating in a console, the Windows implementation of this stream does not support
780 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
781 /// an error.
782 ///
783 /// In a process with a detached console, such as one using
784 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
785 /// the contained handle will be null. In such cases, the standard library's `Read` and
786 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
787 /// standard library or via raw Windows API calls, will fail.
788 #[must_use = "if unused stderr will immediately unlock"]
789 #[stable(feature = "rust1", since = "1.0.0")]
790 pub struct StderrLock<'a> {
791     inner: ReentrantMutexGuard<'a, RefCell<StderrRaw>>,
792 }
793
794 /// Constructs a new handle to the standard error of the current process.
795 ///
796 /// This handle is not buffered.
797 ///
798 /// ### Note: Windows Portability Considerations
799 ///
800 /// When operating in a console, the Windows implementation of this stream does not support
801 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
802 /// an error.
803 ///
804 /// In a process with a detached console, such as one using
805 /// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
806 /// the contained handle will be null. In such cases, the standard library's `Read` and
807 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
808 /// standard library or via raw Windows API calls, will fail.
809 ///
810 /// # Examples
811 ///
812 /// Using implicit synchronization:
813 ///
814 /// ```no_run
815 /// use std::io::{self, Write};
816 ///
817 /// fn main() -> io::Result<()> {
818 ///     io::stderr().write_all(b"hello world")?;
819 ///
820 ///     Ok(())
821 /// }
822 /// ```
823 ///
824 /// Using explicit synchronization:
825 ///
826 /// ```no_run
827 /// use std::io::{self, Write};
828 ///
829 /// fn main() -> io::Result<()> {
830 ///     let stderr = io::stderr();
831 ///     let mut handle = stderr.lock();
832 ///
833 ///     handle.write_all(b"hello world")?;
834 ///
835 ///     Ok(())
836 /// }
837 /// ```
838 #[must_use]
839 #[stable(feature = "rust1", since = "1.0.0")]
840 pub fn stderr() -> Stderr {
841     // Note that unlike `stdout()` we don't use `at_exit` here to register a
842     // destructor. Stderr is not buffered, so there's no need to run a
843     // destructor for flushing the buffer
844     static INSTANCE: ReentrantMutex<RefCell<StderrRaw>> =
845         ReentrantMutex::new(RefCell::new(stderr_raw()));
846
847     Stderr { inner: &INSTANCE }
848 }
849
850 impl Stderr {
851     /// Locks this handle to the standard error stream, returning a writable
852     /// guard.
853     ///
854     /// The lock is released when the returned lock goes out of scope. The
855     /// returned guard also implements the [`Write`] trait for writing data.
856     ///
857     /// # Examples
858     ///
859     /// ```
860     /// use std::io::{self, Write};
861     ///
862     /// fn foo() -> io::Result<()> {
863     ///     let stderr = io::stderr();
864     ///     let mut handle = stderr.lock();
865     ///
866     ///     handle.write_all(b"hello world")?;
867     ///
868     ///     Ok(())
869     /// }
870     /// ```
871     #[stable(feature = "rust1", since = "1.0.0")]
872     pub fn lock(&self) -> StderrLock<'static> {
873         // Locks this handle with 'static lifetime. This depends on the
874         // implementation detail that the underlying `ReentrantMutex` is
875         // static.
876         StderrLock { inner: self.inner.lock() }
877     }
878 }
879
880 #[stable(feature = "std_debug", since = "1.16.0")]
881 impl fmt::Debug for Stderr {
882     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
883         f.debug_struct("Stderr").finish_non_exhaustive()
884     }
885 }
886
887 #[stable(feature = "rust1", since = "1.0.0")]
888 impl Write for Stderr {
889     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
890         (&*self).write(buf)
891     }
892     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
893         (&*self).write_vectored(bufs)
894     }
895     #[inline]
896     fn is_write_vectored(&self) -> bool {
897         io::Write::is_write_vectored(&&*self)
898     }
899     fn flush(&mut self) -> io::Result<()> {
900         (&*self).flush()
901     }
902     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
903         (&*self).write_all(buf)
904     }
905     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
906         (&*self).write_all_vectored(bufs)
907     }
908     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
909         (&*self).write_fmt(args)
910     }
911 }
912
913 #[stable(feature = "write_mt", since = "1.48.0")]
914 impl Write for &Stderr {
915     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
916         self.lock().write(buf)
917     }
918     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
919         self.lock().write_vectored(bufs)
920     }
921     #[inline]
922     fn is_write_vectored(&self) -> bool {
923         self.lock().is_write_vectored()
924     }
925     fn flush(&mut self) -> io::Result<()> {
926         self.lock().flush()
927     }
928     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
929         self.lock().write_all(buf)
930     }
931     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
932         self.lock().write_all_vectored(bufs)
933     }
934     fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
935         self.lock().write_fmt(args)
936     }
937 }
938
939 #[stable(feature = "rust1", since = "1.0.0")]
940 impl Write for StderrLock<'_> {
941     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
942         self.inner.borrow_mut().write(buf)
943     }
944     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
945         self.inner.borrow_mut().write_vectored(bufs)
946     }
947     #[inline]
948     fn is_write_vectored(&self) -> bool {
949         self.inner.borrow_mut().is_write_vectored()
950     }
951     fn flush(&mut self) -> io::Result<()> {
952         self.inner.borrow_mut().flush()
953     }
954     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
955         self.inner.borrow_mut().write_all(buf)
956     }
957     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
958         self.inner.borrow_mut().write_all_vectored(bufs)
959     }
960 }
961
962 #[stable(feature = "std_debug", since = "1.16.0")]
963 impl fmt::Debug for StderrLock<'_> {
964     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
965         f.debug_struct("StderrLock").finish_non_exhaustive()
966     }
967 }
968
969 /// Sets the thread-local output capture buffer and returns the old one.
970 #[unstable(
971     feature = "internal_output_capture",
972     reason = "this function is meant for use in the test crate \
973         and may disappear in the future",
974     issue = "none"
975 )]
976 #[doc(hidden)]
977 pub fn set_output_capture(sink: Option<LocalStream>) -> Option<LocalStream> {
978     if sink.is_none() && !OUTPUT_CAPTURE_USED.load(Ordering::Relaxed) {
979         // OUTPUT_CAPTURE is definitely None since OUTPUT_CAPTURE_USED is false.
980         return None;
981     }
982     OUTPUT_CAPTURE_USED.store(true, Ordering::Relaxed);
983     OUTPUT_CAPTURE.with(move |slot| slot.replace(sink))
984 }
985
986 /// Write `args` to the capture buffer if enabled and possible, or `global_s`
987 /// otherwise. `label` identifies the stream in a panic message.
988 ///
989 /// This function is used to print error messages, so it takes extra
990 /// care to avoid causing a panic when `OUTPUT_CAPTURE` is unusable.
991 /// For instance, if the TLS key for output capturing is already destroyed, or
992 /// if the local stream is in use by another thread, it will just fall back to
993 /// the global stream.
994 ///
995 /// However, if the actual I/O causes an error, this function does panic.
996 ///
997 /// Writing to non-blocking stdout/stderr can cause an error, which will lead
998 /// this function to panic.
999 fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
1000 where
1001     T: Write,
1002 {
1003     if print_to_buffer_if_capture_used(args) {
1004         // Successfully wrote to capture buffer.
1005         return;
1006     }
1007
1008     if let Err(e) = global_s().write_fmt(args) {
1009         panic!("failed printing to {label}: {e}");
1010     }
1011 }
1012
1013 fn print_to_buffer_if_capture_used(args: fmt::Arguments<'_>) -> bool {
1014     OUTPUT_CAPTURE_USED.load(Ordering::Relaxed)
1015         && OUTPUT_CAPTURE.try_with(|s| {
1016             // Note that we completely remove a local sink to write to in case
1017             // our printing recursively panics/prints, so the recursive
1018             // panic/print goes to the global sink instead of our local sink.
1019             s.take().map(|w| {
1020                 let _ = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
1021                 s.set(Some(w));
1022             })
1023         }) == Ok(Some(()))
1024 }
1025
1026 /// Used by impl Termination for Result to print error after `main` or a test
1027 /// has returned. Should avoid panicking, although we can't help it if one of
1028 /// the Display impls inside args decides to.
1029 pub(crate) fn attempt_print_to_stderr(args: fmt::Arguments<'_>) {
1030     if print_to_buffer_if_capture_used(args) {
1031         return;
1032     }
1033
1034     // Ignore error if the write fails, for example because stderr is already
1035     // closed. There is not much point panicking at this point.
1036     let _ = stderr().write_fmt(args);
1037 }
1038
1039 /// Trait to determine if a descriptor/handle refers to a terminal/tty.
1040 #[unstable(feature = "is_terminal", issue = "98070")]
1041 pub trait IsTerminal: crate::sealed::Sealed {
1042     /// Returns `true` if the descriptor/handle refers to a terminal/tty.
1043     ///
1044     /// On platforms where Rust does not know how to detect a terminal yet, this will return
1045     /// `false`. This will also return `false` if an unexpected error occurred, such as from
1046     /// passing an invalid file descriptor.
1047     fn is_terminal(&self) -> bool;
1048 }
1049
1050 macro_rules! impl_is_terminal {
1051     ($($t:ty),*$(,)?) => {$(
1052         #[unstable(feature = "sealed", issue = "none")]
1053         impl crate::sealed::Sealed for $t {}
1054
1055         #[unstable(feature = "is_terminal", issue = "98070")]
1056         impl IsTerminal for $t {
1057             #[inline]
1058             fn is_terminal(&self) -> bool {
1059                 crate::sys::io::is_terminal(self)
1060             }
1061         }
1062     )*}
1063 }
1064
1065 impl_is_terminal!(File, Stdin, StdinLock<'_>, Stdout, StdoutLock<'_>, Stderr, StderrLock<'_>);
1066
1067 #[unstable(
1068     feature = "print_internals",
1069     reason = "implementation detail which may disappear or be replaced at any time",
1070     issue = "none"
1071 )]
1072 #[doc(hidden)]
1073 #[cfg(not(test))]
1074 pub fn _print(args: fmt::Arguments<'_>) {
1075     print_to(args, stdout, "stdout");
1076 }
1077
1078 #[unstable(
1079     feature = "print_internals",
1080     reason = "implementation detail which may disappear or be replaced at any time",
1081     issue = "none"
1082 )]
1083 #[doc(hidden)]
1084 #[cfg(not(test))]
1085 pub fn _eprint(args: fmt::Arguments<'_>) {
1086     print_to(args, stderr, "stderr");
1087 }
1088
1089 #[cfg(test)]
1090 pub use realstd::io::{_eprint, _print};