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