1 #![cfg_attr(test, allow(unused))]
3 use crate::io::prelude::*;
5 use crate::cell::RefCell;
7 use crate::io::lazy::Lazy;
8 use crate::io::{self, Initializer, BufReader, LineWriter};
9 use crate::sync::{Arc, Mutex, MutexGuard};
10 use crate::sys::stdio;
11 use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
12 use crate::thread::LocalKey;
14 /// Stdout used by print! and println! macros
16 static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = {
21 /// Stderr used by eprint! and eprintln! macros, and panics
23 static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = {
28 /// A handle to a raw instance of the standard input stream of this process.
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);
34 /// A handle to a raw instance of the standard output stream of this process.
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);
40 /// A handle to a raw instance of the standard output stream of this process.
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);
46 /// Constructs a new raw handle to the standard input of this process.
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.
52 /// The returned handle has no external synchronization or buffering.
53 fn stdin_raw() -> io::Result<StdinRaw> { stdio::Stdin::new().map(StdinRaw) }
55 /// Constructs a new raw handle to the standard output stream of this process.
57 /// The returned handle does not interact with any other handles created nor
58 /// handles returned by `std::io::stdout`. Note that data is buffered by the
59 /// `std::io::stdout` handles so writes which happen via this raw handle may
60 /// appear before previous writes.
62 /// The returned handle has no external synchronization or buffering layered on
64 fn stdout_raw() -> io::Result<StdoutRaw> { stdio::Stdout::new().map(StdoutRaw) }
66 /// Constructs a new raw handle to the standard error stream of this process.
68 /// The returned handle does not interact with any other handles created nor
69 /// handles returned by `std::io::stderr`.
71 /// The returned handle has no external synchronization or buffering layered on
73 fn stderr_raw() -> io::Result<StderrRaw> { stdio::Stderr::new().map(StderrRaw) }
75 impl Read for StdinRaw {
76 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
79 unsafe fn initializer(&self) -> Initializer {
83 impl Write for StdoutRaw {
84 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
85 fn flush(&mut self) -> io::Result<()> { self.0.flush() }
87 impl Write for StderrRaw {
88 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
89 fn flush(&mut self) -> io::Result<()> { self.0.flush() }
97 impl<W: io::Write> io::Write for Maybe<W> {
98 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
100 Maybe::Real(ref mut w) => handle_ebadf(w.write(buf), buf.len()),
101 Maybe::Fake => Ok(buf.len())
105 fn flush(&mut self) -> io::Result<()> {
107 Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()),
108 Maybe::Fake => Ok(())
113 impl<R: io::Read> io::Read for Maybe<R> {
114 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
116 Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), 0),
122 fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
124 Err(ref e) if stdio::is_ebadf(e) => Ok(default),
129 /// A handle to the standard input stream of a process.
131 /// Each handle is a shared reference to a global buffer of input data to this
132 /// process. A handle can be `lock`'d to gain full access to [`BufRead`] methods
133 /// (e.g., `.lines()`). Reads to this handle are otherwise locked with respect
136 /// This handle implements the `Read` trait, but beware that concurrent reads
137 /// of `Stdin` must be executed with care.
139 /// Created by the [`io::stdin`] method.
141 /// [`io::stdin`]: fn.stdin.html
142 /// [`BufRead`]: trait.BufRead.html
144 /// ### Note: Windows Portability Consideration
145 /// When operating in a console, the Windows implementation of this stream does not support
146 /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
148 #[stable(feature = "rust1", since = "1.0.0")]
150 inner: Arc<Mutex<BufReader<Maybe<StdinRaw>>>>,
153 /// A locked reference to the `Stdin` handle.
155 /// This handle implements both the [`Read`] and [`BufRead`] traits, and
156 /// is constructed via the [`Stdin::lock`] method.
158 /// [`Read`]: trait.Read.html
159 /// [`BufRead`]: trait.BufRead.html
160 /// [`Stdin::lock`]: struct.Stdin.html#method.lock
162 /// ### Note: Windows Portability Consideration
163 /// When operating in a console, the Windows implementation of this stream does not support
164 /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
166 #[stable(feature = "rust1", since = "1.0.0")]
167 pub struct StdinLock<'a> {
168 inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>,
171 /// Constructs a new handle to the standard input of the current process.
173 /// Each handle returned is a reference to a shared global buffer whose access
174 /// is synchronized via a mutex. If you need more explicit control over
175 /// locking, see the [`lock() method`][lock].
177 /// [lock]: struct.Stdin.html#method.lock
179 /// ### Note: Windows Portability Consideration
180 /// When operating in a console, the Windows implementation of this stream does not support
181 /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
186 /// Using implicit synchronization:
189 /// use std::io::{self, Read};
191 /// fn main() -> io::Result<()> {
192 /// let mut buffer = String::new();
193 /// io::stdin().read_to_string(&mut buffer)?;
198 /// Using explicit synchronization:
201 /// use std::io::{self, Read};
203 /// fn main() -> io::Result<()> {
204 /// let mut buffer = String::new();
205 /// let stdin = io::stdin();
206 /// let mut handle = stdin.lock();
208 /// handle.read_to_string(&mut buffer)?;
212 #[stable(feature = "rust1", since = "1.0.0")]
213 pub fn stdin() -> Stdin {
214 static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = Lazy::new();
217 INSTANCE.get(stdin_init).expect("cannot access stdin during shutdown")
221 fn stdin_init() -> Arc<Mutex<BufReader<Maybe<StdinRaw>>>> {
222 // This must not reentrantly access `INSTANCE`
223 let stdin = match stdin_raw() {
224 Ok(stdin) => Maybe::Real(stdin),
228 Arc::new(Mutex::new(BufReader::with_capacity(stdio::STDIN_BUF_SIZE, stdin)))
233 /// Locks this handle to the standard input stream, returning a readable
236 /// The lock is released when the returned lock goes out of scope. The
237 /// returned guard also implements the [`Read`] and [`BufRead`] traits for
238 /// accessing the underlying data.
240 /// [`Read`]: trait.Read.html
241 /// [`BufRead`]: trait.BufRead.html
246 /// use std::io::{self, Read};
248 /// fn main() -> io::Result<()> {
249 /// let mut buffer = String::new();
250 /// let stdin = io::stdin();
251 /// let mut handle = stdin.lock();
253 /// handle.read_to_string(&mut buffer)?;
257 #[stable(feature = "rust1", since = "1.0.0")]
258 pub fn lock(&self) -> StdinLock {
259 StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
262 /// Locks this handle and reads a line of input into the specified buffer.
264 /// For detailed semantics of this method, see the documentation on
265 /// [`BufRead::read_line`].
267 /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line
274 /// let mut input = String::new();
275 /// match io::stdin().read_line(&mut input) {
277 /// println!("{} bytes read", n);
278 /// println!("{}", input);
280 /// Err(error) => println!("error: {}", error),
284 /// You can run the example one of two ways:
286 /// - Pipe some text to it, e.g., `printf foo | path/to/executable`
287 /// - Give it text interactively by running the executable directly,
288 /// in which case it will wait for the Enter key to be pressed before
290 #[stable(feature = "rust1", since = "1.0.0")]
291 pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
292 self.lock().read_line(buf)
296 #[stable(feature = "std_debug", since = "1.16.0")]
297 impl fmt::Debug for Stdin {
298 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
299 f.pad("Stdin { .. }")
303 #[stable(feature = "rust1", since = "1.0.0")]
304 impl Read for Stdin {
305 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
306 self.lock().read(buf)
309 unsafe fn initializer(&self) -> Initializer {
312 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
313 self.lock().read_to_end(buf)
315 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
316 self.lock().read_to_string(buf)
318 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
319 self.lock().read_exact(buf)
323 #[stable(feature = "rust1", since = "1.0.0")]
324 impl Read for StdinLock<'_> {
325 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
329 unsafe fn initializer(&self) -> Initializer {
334 #[stable(feature = "rust1", since = "1.0.0")]
335 impl BufRead for StdinLock<'_> {
336 fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
337 fn consume(&mut self, n: usize) { self.inner.consume(n) }
340 #[stable(feature = "std_debug", since = "1.16.0")]
341 impl fmt::Debug for StdinLock<'_> {
342 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
343 f.pad("StdinLock { .. }")
347 /// A handle to the global standard output stream of the current process.
349 /// Each handle shares a global buffer of data to be written to the standard
350 /// output stream. Access is also synchronized via a lock and explicit control
351 /// over locking is available via the [`lock`] method.
353 /// Created by the [`io::stdout`] method.
355 /// ### Note: Windows Portability Consideration
356 /// When operating in a console, the Windows implementation of this stream does not support
357 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
360 /// [`lock`]: #method.lock
361 /// [`io::stdout`]: fn.stdout.html
362 #[stable(feature = "rust1", since = "1.0.0")]
364 // FIXME: this should be LineWriter or BufWriter depending on the state of
365 // stdout (tty or not). Note that if this is not line buffered it
366 // should also flush-on-panic or some form of flush-on-abort.
367 inner: Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>,
370 /// A locked reference to the `Stdout` handle.
372 /// This handle implements the [`Write`] trait, and is constructed via
373 /// the [`Stdout::lock`] method.
375 /// ### Note: Windows Portability Consideration
376 /// When operating in a console, the Windows implementation of this stream does not support
377 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
380 /// [`Write`]: trait.Write.html
381 /// [`Stdout::lock`]: struct.Stdout.html#method.lock
382 #[stable(feature = "rust1", since = "1.0.0")]
383 pub struct StdoutLock<'a> {
384 inner: ReentrantMutexGuard<'a, RefCell<LineWriter<Maybe<StdoutRaw>>>>,
387 /// Constructs a new handle to the standard output of the current process.
389 /// Each handle returned is a reference to a shared global buffer whose access
390 /// is synchronized via a mutex. If you need more explicit control over
391 /// locking, see the [Stdout::lock] method.
393 /// [Stdout::lock]: struct.Stdout.html#method.lock
395 /// ### Note: Windows Portability Consideration
396 /// When operating in a console, the Windows implementation of this stream does not support
397 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
402 /// Using implicit synchronization:
405 /// use std::io::{self, Write};
407 /// fn main() -> io::Result<()> {
408 /// io::stdout().write(b"hello world")?;
414 /// Using explicit synchronization:
417 /// use std::io::{self, Write};
419 /// fn main() -> io::Result<()> {
420 /// let stdout = io::stdout();
421 /// let mut handle = stdout.lock();
423 /// handle.write(b"hello world")?;
428 #[stable(feature = "rust1", since = "1.0.0")]
429 pub fn stdout() -> Stdout {
430 static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>> = Lazy::new();
433 INSTANCE.get(stdout_init).expect("cannot access stdout during shutdown")
437 fn stdout_init() -> Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>> {
438 // This must not reentrantly access `INSTANCE`
439 let stdout = match stdout_raw() {
440 Ok(stdout) => Maybe::Real(stdout),
443 Arc::new(ReentrantMutex::new(RefCell::new(LineWriter::new(stdout))))
448 /// Locks this handle to the standard output stream, returning a writable
451 /// The lock is released when the returned lock goes out of scope. The
452 /// returned guard also implements the `Write` trait for writing data.
457 /// use std::io::{self, Write};
459 /// fn main() -> io::Result<()> {
460 /// let stdout = io::stdout();
461 /// let mut handle = stdout.lock();
463 /// handle.write(b"hello world")?;
468 #[stable(feature = "rust1", since = "1.0.0")]
469 pub fn lock(&self) -> StdoutLock {
470 StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
474 #[stable(feature = "std_debug", since = "1.16.0")]
475 impl fmt::Debug for Stdout {
476 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
477 f.pad("Stdout { .. }")
481 #[stable(feature = "rust1", since = "1.0.0")]
482 impl Write for Stdout {
483 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
484 self.lock().write(buf)
486 fn flush(&mut self) -> io::Result<()> {
489 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
490 self.lock().write_all(buf)
492 fn write_fmt(&mut self, args: fmt::Arguments) -> io::Result<()> {
493 self.lock().write_fmt(args)
496 #[stable(feature = "rust1", since = "1.0.0")]
497 impl Write for StdoutLock<'_> {
498 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
499 self.inner.borrow_mut().write(buf)
501 fn flush(&mut self) -> io::Result<()> {
502 self.inner.borrow_mut().flush()
506 #[stable(feature = "std_debug", since = "1.16.0")]
507 impl fmt::Debug for StdoutLock<'_> {
508 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
509 f.pad("StdoutLock { .. }")
513 /// A handle to the standard error stream of a process.
515 /// For more information, see the [`io::stderr`] method.
517 /// [`io::stderr`]: fn.stderr.html
519 /// ### Note: Windows Portability Consideration
520 /// When operating in a console, the Windows implementation of this stream does not support
521 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
523 #[stable(feature = "rust1", since = "1.0.0")]
525 inner: Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>>,
528 /// A locked reference to the `Stderr` handle.
530 /// This handle implements the `Write` trait and is constructed via
531 /// the [`Stderr::lock`] method.
533 /// [`Stderr::lock`]: struct.Stderr.html#method.lock
535 /// ### Note: Windows Portability Consideration
536 /// When operating in a console, the Windows implementation of this stream does not support
537 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
539 #[stable(feature = "rust1", since = "1.0.0")]
540 pub struct StderrLock<'a> {
541 inner: ReentrantMutexGuard<'a, RefCell<Maybe<StderrRaw>>>,
544 /// Constructs a new handle to the standard error of the current process.
546 /// This handle is not buffered.
548 /// ### Note: Windows Portability Consideration
549 /// When operating in a console, the Windows implementation of this stream does not support
550 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
555 /// Using implicit synchronization:
558 /// use std::io::{self, Write};
560 /// fn main() -> io::Result<()> {
561 /// io::stderr().write(b"hello world")?;
567 /// Using explicit synchronization:
570 /// use std::io::{self, Write};
572 /// fn main() -> io::Result<()> {
573 /// let stderr = io::stderr();
574 /// let mut handle = stderr.lock();
576 /// handle.write(b"hello world")?;
581 #[stable(feature = "rust1", since = "1.0.0")]
582 pub fn stderr() -> Stderr {
583 static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> = Lazy::new();
586 INSTANCE.get(stderr_init).expect("cannot access stderr during shutdown")
590 fn stderr_init() -> Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> {
591 // This must not reentrantly access `INSTANCE`
592 let stderr = match stderr_raw() {
593 Ok(stderr) => Maybe::Real(stderr),
596 Arc::new(ReentrantMutex::new(RefCell::new(stderr)))
601 /// Locks this handle to the standard error stream, returning a writable
604 /// The lock is released when the returned lock goes out of scope. The
605 /// returned guard also implements the `Write` trait for writing data.
610 /// use std::io::{self, Write};
612 /// fn foo() -> io::Result<()> {
613 /// let stderr = io::stderr();
614 /// let mut handle = stderr.lock();
616 /// handle.write(b"hello world")?;
621 #[stable(feature = "rust1", since = "1.0.0")]
622 pub fn lock(&self) -> StderrLock {
623 StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
627 #[stable(feature = "std_debug", since = "1.16.0")]
628 impl fmt::Debug for Stderr {
629 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
630 f.pad("Stderr { .. }")
634 #[stable(feature = "rust1", since = "1.0.0")]
635 impl Write for Stderr {
636 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
637 self.lock().write(buf)
639 fn flush(&mut self) -> io::Result<()> {
642 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
643 self.lock().write_all(buf)
645 fn write_fmt(&mut self, args: fmt::Arguments) -> io::Result<()> {
646 self.lock().write_fmt(args)
649 #[stable(feature = "rust1", since = "1.0.0")]
650 impl Write for StderrLock<'_> {
651 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
652 self.inner.borrow_mut().write(buf)
654 fn flush(&mut self) -> io::Result<()> {
655 self.inner.borrow_mut().flush()
659 #[stable(feature = "std_debug", since = "1.16.0")]
660 impl fmt::Debug for StderrLock<'_> {
661 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
662 f.pad("StderrLock { .. }")
666 /// Resets the thread-local stderr handle to the specified writer
668 /// This will replace the current thread's stderr handle, returning the old
669 /// handle. All future calls to `panic!` and friends will emit their output to
670 /// this specified handle.
672 /// Note that this does not need to be called for all new threads; the default
673 /// output handle is to the process's stderr stream.
674 #[unstable(feature = "set_stdio",
675 reason = "this function may disappear completely or be replaced \
676 with a more general mechanism",
679 pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
681 LOCAL_STDERR.with(move |slot| {
682 mem::replace(&mut *slot.borrow_mut(), sink)
683 }).and_then(|mut s| {
689 /// Resets the thread-local stdout handle to the specified writer
691 /// This will replace the current thread's stdout handle, returning the old
692 /// handle. All future calls to `print!` and friends will emit their output to
693 /// this specified handle.
695 /// Note that this does not need to be called for all new threads; the default
696 /// output handle is to the process's stdout stream.
697 #[unstable(feature = "set_stdio",
698 reason = "this function may disappear completely or be replaced \
699 with a more general mechanism",
702 pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
704 LOCAL_STDOUT.with(move |slot| {
705 mem::replace(&mut *slot.borrow_mut(), sink)
706 }).and_then(|mut s| {
712 /// Write `args` to output stream `local_s` if possible, `global_s`
713 /// otherwise. `label` identifies the stream in a panic message.
715 /// This function is used to print error messages, so it takes extra
716 /// care to avoid causing a panic when `local_stream` is unusable.
717 /// For instance, if the TLS key for the local stream is
718 /// already destroyed, or if the local stream is locked by another
719 /// thread, it will just fall back to the global stream.
721 /// However, if the actual I/O causes an error, this function does panic.
723 args: fmt::Arguments,
724 local_s: &'static LocalKey<RefCell<Option<Box<dyn Write+Send>>>>,
731 let result = local_s.try_with(|s| {
732 if let Ok(mut borrowed) = s.try_borrow_mut() {
733 if let Some(w) = borrowed.as_mut() {
734 return w.write_fmt(args);
737 global_s().write_fmt(args)
738 }).unwrap_or_else(|_| {
739 global_s().write_fmt(args)
742 if let Err(e) = result {
743 panic!("failed printing to {}: {}", label, e);
747 #[unstable(feature = "print_internals",
748 reason = "implementation detail which may disappear or be replaced at any time",
752 pub fn _print(args: fmt::Arguments) {
753 print_to(args, &LOCAL_STDOUT, stdout, "stdout");
756 #[unstable(feature = "print_internals",
757 reason = "implementation detail which may disappear or be replaced at any time",
761 pub fn _eprint(args: fmt::Arguments) {
762 print_to(args, &LOCAL_STDERR, stderr, "stderr");
766 pub use realstd::io::{_eprint, _print};
770 use crate::panic::{UnwindSafe, RefUnwindSafe};
775 fn stdout_unwind_safe() {
776 assert_unwind_safe::<Stdout>();
779 fn stdoutlock_unwind_safe() {
780 assert_unwind_safe::<StdoutLock>();
781 assert_unwind_safe::<StdoutLock<'static>>();
784 fn stderr_unwind_safe() {
785 assert_unwind_safe::<Stderr>();
788 fn stderrlock_unwind_safe() {
789 assert_unwind_safe::<StderrLock>();
790 assert_unwind_safe::<StderrLock<'static>>();
793 fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {}
796 #[cfg_attr(target_os = "emscripten", ignore)]
797 fn panic_doesnt_poison() {
806 }).join().unwrap_err();