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