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