diff options
| author | Zack Weinberg <zackw@panix.com> | 2017-01-21 13:38:11 -0500 |
|---|---|---|
| committer | Zack Weinberg <zackw@panix.com> | 2017-05-10 09:29:16 -0400 |
| commit | 76127275a09d970169952bcf616f966faa9ed6db (patch) | |
| tree | def3a13636f3b6fa69cc4cf4fe7782da05994082 /src/libstd/io | |
| parent | 2b97174ada7fb1854269558ed2cf3b089e58beee (diff) | |
Add `eprint!` and `eprintln!` macros to the prelude.
These are exactly the same as `print!` and `println!` except that they write to stderr instead of stdout. Issue #39228.
Diffstat (limited to 'src/libstd/io')
| -rw-r--r-- | src/libstd/io/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/io/stdio.rs | 36 |
2 files changed, 38 insertions, 0 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e2832873e2e..b6d3c920fb9 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -290,6 +290,8 @@ pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat}; pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::stdio::{StdoutLock, StderrLock, StdinLock}; +#[unstable(feature = "eprint", issue="39228")] +pub use self::stdio::_eprint; #[unstable(feature = "libstd_io_internals", issue = "0")] #[doc(no_inline, hidden)] pub use self::stdio::{set_panic, set_print}; diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 38ad23e14b3..de80cb49804 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -694,6 +694,42 @@ pub fn _print(args: fmt::Arguments) { } } +#[unstable(feature = "eprint_internal", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "0")] +#[doc(hidden)] +pub fn _eprint(args: fmt::Arguments) { + // As an implementation of the `eprintln!` macro, we want to try our best to + // not panic wherever possible and get the output somewhere. There are + // currently two possible vectors for panics we take care of here: + // + // 1. If the TLS key for the local stderr has been destroyed, accessing it + // would cause a panic. Note that we just lump in the uninitialized case + // here for convenience, we're not trying to avoid a panic. + // 2. If the local stderr is currently in use (e.g. we're in the middle of + // already printing) then accessing again would cause a panic. + // + // If, however, the actual I/O causes an error, we do indeed panic. + use panicking::LOCAL_STDERR; + let result = match LOCAL_STDERR.state() { + LocalKeyState::Uninitialized | + LocalKeyState::Destroyed => stderr().write_fmt(args), + LocalKeyState::Valid => { + LOCAL_STDERR.with(|s| { + if let Ok(mut borrowed) = s.try_borrow_mut() { + if let Some(w) = borrowed.as_mut() { + return w.write_fmt(args); + } + } + stderr().write_fmt(args) + }) + } + }; + if let Err(e) = result { + panic!("failed printing to stderr: {}", e); + } +} + #[cfg(test)] mod tests { use thread; |
