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