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