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