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