2019-02-14 12:36:01 +00:00
|
|
|
#![cfg_attr(test, allow(unused))]
|
|
|
|
|
2020-08-27 13:45:01 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests;
|
|
|
|
|
2019-02-10 19:23:21 +00:00
|
|
|
use crate::io::prelude::*;
|
2015-02-25 07:27:20 +00:00
|
|
|
|
2020-11-03 21:59:04 +00:00
|
|
|
use crate::cell::{Cell, RefCell};
|
2019-02-10 19:23:21 +00:00
|
|
|
use crate::fmt;
|
2022-01-20 21:37:44 +00:00
|
|
|
use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
|
Remove std::io::lazy::Lazy in favour of SyncOnceCell
The (internal) std::io::lazy::Lazy was used to lazily initialize the
stdout and stdin buffers (and mutexes). It uses atexit() to register a
destructor to flush the streams on exit, and mark the streams as
'closed'. Using the stream afterwards would result in a panic.
Stdout uses a LineWriter which contains a BufWriter that will flush the
buffer on drop. This one is important to be executed during shutdown,
to make sure no buffered output is lost. It also forbids access to
stdout afterwards, since the buffer is already flushed and gone.
Stdin uses a BufReader, which does not implement Drop. It simply forgets
any previously read data that was not read from the buffer yet. This
means that in the case of stdin, the atexit() function's only effect is
making stdin inaccessible to the program, such that later accesses
result in a panic. This is uncessary, as it'd have been safe to access
stdin during shutdown of the program.
---
This change removes the entire io::lazy module in favour of
SyncOnceCell. SyncOnceCell's fast path is much faster (a single atomic
operation) than locking a sys_common::Mutex on every access like Lazy
did.
However, SyncOnceCell does not use atexit() to drop the contained object
during shutdown.
As noted above, this is not a problem for stdin. It simply means stdin
is now usable during shutdown.
The atexit() call for stdout is moved to the stdio module. Unlike the
now-removed Lazy struct, SyncOnceCell does not have a 'gone and
unusable' state that panics. Instead of adding this again, this simply
replaces the buffer with one with zero capacity. This effectively
flushes the old buffer *and* makes any writes afterwards pass through
directly without touching a buffer, making print!() available during
shutdown without panicking.
2020-09-24 15:45:50 +00:00
|
|
|
use crate::lazy::SyncOnceCell;
|
2020-10-10 18:20:14 +00:00
|
|
|
use crate::pin::Pin;
|
2020-09-27 13:19:42 +00:00
|
|
|
use crate::sync::atomic::{AtomicBool, Ordering};
|
2020-11-03 19:48:25 +00:00
|
|
|
use crate::sync::{Arc, Mutex, MutexGuard};
|
2019-02-10 19:23:21 +00:00
|
|
|
use crate::sys::stdio;
|
|
|
|
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
|
2015-02-25 07:27:20 +00:00
|
|
|
|
2020-11-03 20:44:21 +00:00
|
|
|
type LocalStream = Arc<Mutex<Vec<u8>>>;
|
2015-03-08 22:30:15 +00:00
|
|
|
|
2019-02-14 12:36:01 +00:00
|
|
|
thread_local! {
|
2020-11-03 23:11:14 +00:00
|
|
|
/// Used by the test crate to capture the output of the print macros and panics.
|
|
|
|
static OUTPUT_CAPTURE: Cell<Option<LocalStream>> = {
|
2020-11-03 21:59:04 +00:00
|
|
|
Cell::new(None)
|
2019-02-14 12:36:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-03 23:11:14 +00:00
|
|
|
/// Flag to indicate OUTPUT_CAPTURE is used.
|
2020-09-27 13:32:07 +00:00
|
|
|
///
|
2020-11-03 23:11:14 +00:00
|
|
|
/// If it is None and was never set on any thread, this flag is set to false,
|
|
|
|
/// and OUTPUT_CAPTURE can be safely ignored on all threads, saving some time
|
|
|
|
/// and memory registering an unused thread local.
|
2020-09-27 13:32:07 +00:00
|
|
|
///
|
2020-11-03 23:11:14 +00:00
|
|
|
/// Note about memory ordering: This contains information about whether a
|
|
|
|
/// thread local variable might be in use. Although this is a global flag, the
|
2020-09-27 13:32:07 +00:00
|
|
|
/// memory ordering between threads does not matter: we only want this flag to
|
2020-11-03 23:11:14 +00:00
|
|
|
/// have a consistent order between set_output_capture and print_to *within
|
2020-09-27 13:32:07 +00:00
|
|
|
/// the same thread*. Within the same thread, things always have a perfectly
|
|
|
|
/// consistent order. So Ordering::Relaxed is fine.
|
2020-11-03 23:11:14 +00:00
|
|
|
static OUTPUT_CAPTURE_USED: AtomicBool = AtomicBool::new(false);
|
2020-09-27 13:32:07 +00:00
|
|
|
|
2015-02-25 07:27:20 +00:00
|
|
|
/// A handle to a raw instance of the standard input stream of this process.
|
|
|
|
///
|
|
|
|
/// This handle is not synchronized or buffered in any fashion. Constructed via
|
2015-03-15 01:08:09 +00:00
|
|
|
/// the `std::io::stdio::stdin_raw` function.
|
|
|
|
struct StdinRaw(stdio::Stdin);
|
2015-02-25 07:27:20 +00:00
|
|
|
|
|
|
|
/// A handle to a raw instance of the standard output stream of this process.
|
|
|
|
///
|
|
|
|
/// This handle is not synchronized or buffered in any fashion. Constructed via
|
2015-03-15 01:08:09 +00:00
|
|
|
/// the `std::io::stdio::stdout_raw` function.
|
|
|
|
struct StdoutRaw(stdio::Stdout);
|
2015-02-25 07:27:20 +00:00
|
|
|
|
|
|
|
/// A handle to a raw instance of the standard output stream of this process.
|
|
|
|
///
|
|
|
|
/// This handle is not synchronized or buffered in any fashion. Constructed via
|
2015-03-15 01:08:09 +00:00
|
|
|
/// the `std::io::stdio::stderr_raw` function.
|
|
|
|
struct StderrRaw(stdio::Stderr);
|
2015-02-25 07:27:20 +00:00
|
|
|
|
2015-04-13 14:21:32 +00:00
|
|
|
/// Constructs a new raw handle to the standard input of this process.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
|
|
|
/// The returned handle does not interact with any other handles created nor
|
|
|
|
/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
|
|
|
|
/// handles is **not** available to raw handles returned from this function.
|
|
|
|
///
|
|
|
|
/// The returned handle has no external synchronization or buffering.
|
2020-08-20 00:00:00 +00:00
|
|
|
#[unstable(feature = "libstd_sys_internals", issue = "none")]
|
|
|
|
const fn stdin_raw() -> StdinRaw {
|
2020-08-20 00:00:00 +00:00
|
|
|
StdinRaw(stdio::Stdin::new())
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
|
2015-08-12 00:58:15 +00:00
|
|
|
/// Constructs a new raw handle to the standard output stream of this process.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
|
|
|
/// The returned handle does not interact with any other handles created nor
|
|
|
|
/// handles returned by `std::io::stdout`. Note that data is buffered by the
|
2015-08-12 00:58:15 +00:00
|
|
|
/// `std::io::stdout` handles so writes which happen via this raw handle may
|
2015-02-25 07:27:20 +00:00
|
|
|
/// appear before previous writes.
|
|
|
|
///
|
|
|
|
/// The returned handle has no external synchronization or buffering layered on
|
|
|
|
/// top.
|
2020-08-20 00:00:00 +00:00
|
|
|
#[unstable(feature = "libstd_sys_internals", issue = "none")]
|
|
|
|
const fn stdout_raw() -> StdoutRaw {
|
2020-08-20 00:00:00 +00:00
|
|
|
StdoutRaw(stdio::Stdout::new())
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
|
2015-08-12 00:58:15 +00:00
|
|
|
/// Constructs a new raw handle to the standard error stream of this process.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
|
|
|
/// The returned handle does not interact with any other handles created nor
|
2015-08-12 00:58:15 +00:00
|
|
|
/// handles returned by `std::io::stderr`.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
|
|
|
/// The returned handle has no external synchronization or buffering layered on
|
|
|
|
/// top.
|
2020-08-20 00:00:00 +00:00
|
|
|
#[unstable(feature = "libstd_sys_internals", issue = "none")]
|
|
|
|
const fn stderr_raw() -> StderrRaw {
|
2020-08-20 00:00:00 +00:00
|
|
|
StderrRaw(stdio::Stderr::new())
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
|
|
|
|
impl Read for StdinRaw {
|
2019-12-22 22:42:04 +00:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.read(buf), 0)
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2017-05-15 01:29:18 +00:00
|
|
|
|
2019-04-27 15:34:08 +00:00
|
|
|
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.read_vectored(bufs), 0)
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
}
|
|
|
|
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_read_vectored(&self) -> bool {
|
|
|
|
self.0.is_read_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
|
|
|
|
2020-05-28 19:02:48 +00:00
|
|
|
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.read_to_end(buf), 0)
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.read_to_string(buf), 0)
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
|
2015-02-25 07:27:20 +00:00
|
|
|
impl Write for StdoutRaw {
|
2019-12-22 22:42:04 +00:00
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write(buf), buf.len())
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
let total = bufs.iter().map(|b| b.len()).sum();
|
|
|
|
handle_ebadf(self.0.write_vectored(bufs), total)
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
}
|
|
|
|
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
|
|
|
self.0.is_write_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
|
|
|
|
2019-12-22 22:42:04 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.flush(), ())
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
|
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write_all(buf), ())
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write_all_vectored(bufs), ())
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write_fmt(fmt), ())
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
|
2015-02-25 07:27:20 +00:00
|
|
|
impl Write for StderrRaw {
|
2019-12-22 22:42:04 +00:00
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write(buf), buf.len())
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
2020-08-21 00:00:00 +00:00
|
|
|
let total = bufs.iter().map(|b| b.len()).sum();
|
|
|
|
handle_ebadf(self.0.write_vectored(bufs), total)
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
}
|
|
|
|
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
|
|
|
self.0.is_write_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
|
|
|
|
2019-12-22 22:42:04 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.flush(), ())
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
|
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write_all(buf), ())
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write_all_vectored(bufs), ())
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
|
2020-08-21 00:00:00 +00:00
|
|
|
handle_ebadf(self.0.write_fmt(fmt), ())
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
2015-06-10 04:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
|
|
|
|
match r {
|
2017-11-01 19:50:13 +00:00
|
|
|
Err(ref e) if stdio::is_ebadf(e) => Ok(default),
|
2019-12-22 22:42:04 +00:00
|
|
|
r => r,
|
2015-06-10 04:39:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 07:27:20 +00:00
|
|
|
/// A handle to the standard input stream of a process.
|
|
|
|
///
|
|
|
|
/// Each handle is a shared reference to a global buffer of input data to this
|
2015-12-30 10:41:04 +00:00
|
|
|
/// process. A handle can be `lock`'d to gain full access to [`BufRead`] methods
|
2018-11-27 02:59:49 +00:00
|
|
|
/// (e.g., `.lines()`). Reads to this handle are otherwise locked with respect
|
2016-03-23 23:39:01 +00:00
|
|
|
/// to other reads.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
|
|
|
/// This handle implements the `Read` trait, but beware that concurrent reads
|
|
|
|
/// of `Stdin` must be executed with care.
|
2015-04-22 20:57:08 +00:00
|
|
|
///
|
2015-12-30 10:41:04 +00:00
|
|
|
/// Created by the [`io::stdin`] method.
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2020-08-18 17:36:52 +00:00
|
|
|
/// [`io::stdin`]: stdin
|
2019-02-04 06:38:43 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
2020-06-26 11:31:36 +00:00
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
2020-06-26 11:31:36 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
|
|
|
///
|
2020-06-26 11:31:36 +00:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2021-08-06 15:59:02 +00:00
|
|
|
/// use std::io;
|
2020-06-26 11:31:36 +00:00
|
|
|
///
|
|
|
|
/// fn main() -> io::Result<()> {
|
|
|
|
/// let mut buffer = String::new();
|
|
|
|
/// let mut stdin = io::stdin(); // We get `Stdin` here.
|
2021-08-06 15:59:02 +00:00
|
|
|
/// stdin.read_line(&mut buffer)?;
|
2020-06-26 11:31:36 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub struct Stdin {
|
2020-09-24 17:09:33 +00:00
|
|
|
inner: &'static Mutex<BufReader<StdinRaw>>,
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2021-02-18 01:58:15 +00:00
|
|
|
/// A locked reference to the [`Stdin`] handle.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2015-12-30 10:41:04 +00:00
|
|
|
/// This handle implements both the [`Read`] and [`BufRead`] traits, and
|
|
|
|
/// is constructed via the [`Stdin::lock`] method.
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
2020-06-26 11:31:36 +00:00
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
2020-06-26 11:31:36 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
|
|
|
///
|
2020-06-26 11:31:36 +00:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2021-08-06 15:59:02 +00:00
|
|
|
/// use std::io::{self, BufRead};
|
2020-06-26 11:31:36 +00:00
|
|
|
///
|
|
|
|
/// fn main() -> io::Result<()> {
|
|
|
|
/// let mut buffer = String::new();
|
|
|
|
/// let stdin = io::stdin(); // We get `Stdin` here.
|
|
|
|
/// {
|
2021-02-18 02:11:57 +00:00
|
|
|
/// let mut handle = stdin.lock(); // We get `StdinLock` here.
|
2021-08-06 15:59:02 +00:00
|
|
|
/// handle.read_line(&mut buffer)?;
|
2020-06-26 11:31:36 +00:00
|
|
|
/// } // `StdinLock` is dropped here.
|
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2021-10-09 03:31:57 +00:00
|
|
|
#[must_use = "if unused stdin will immediately unlock"]
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub struct StdinLock<'a> {
|
2020-08-21 00:00:00 +00:00
|
|
|
inner: MutexGuard<'a, BufReader<StdinRaw>>,
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 22:31:08 +00:00
|
|
|
/// Constructs a new handle to the standard input of the current process.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2015-07-08 22:31:08 +00:00
|
|
|
/// Each handle returned is a reference to a shared global buffer whose access
|
|
|
|
/// is synchronized via a mutex. If you need more explicit control over
|
2019-09-11 12:03:40 +00:00
|
|
|
/// locking, see the [`Stdin::lock`] method.
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
|
|
|
///
|
2015-07-08 22:31:08 +00:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Using implicit synchronization:
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2021-08-06 15:59:02 +00:00
|
|
|
/// use std::io;
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
|
|
|
/// let mut buffer = String::new();
|
2021-08-06 15:59:02 +00:00
|
|
|
/// io::stdin().read_line(&mut buffer)?;
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2015-07-08 22:31:08 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Using explicit synchronization:
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2021-08-06 15:59:02 +00:00
|
|
|
/// use std::io::{self, BufRead};
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
|
|
|
/// let mut buffer = String::new();
|
|
|
|
/// let stdin = io::stdin();
|
|
|
|
/// let mut handle = stdin.lock();
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2021-08-06 15:59:02 +00:00
|
|
|
/// handle.read_line(&mut buffer)?;
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2015-07-08 22:31:08 +00:00
|
|
|
/// ```
|
2021-10-31 02:58:27 +00:00
|
|
|
#[must_use]
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub fn stdin() -> Stdin {
|
2020-09-24 17:09:33 +00:00
|
|
|
static INSTANCE: SyncOnceCell<Mutex<BufReader<StdinRaw>>> = SyncOnceCell::new();
|
Remove std::io::lazy::Lazy in favour of SyncOnceCell
The (internal) std::io::lazy::Lazy was used to lazily initialize the
stdout and stdin buffers (and mutexes). It uses atexit() to register a
destructor to flush the streams on exit, and mark the streams as
'closed'. Using the stream afterwards would result in a panic.
Stdout uses a LineWriter which contains a BufWriter that will flush the
buffer on drop. This one is important to be executed during shutdown,
to make sure no buffered output is lost. It also forbids access to
stdout afterwards, since the buffer is already flushed and gone.
Stdin uses a BufReader, which does not implement Drop. It simply forgets
any previously read data that was not read from the buffer yet. This
means that in the case of stdin, the atexit() function's only effect is
making stdin inaccessible to the program, such that later accesses
result in a panic. This is uncessary, as it'd have been safe to access
stdin during shutdown of the program.
---
This change removes the entire io::lazy module in favour of
SyncOnceCell. SyncOnceCell's fast path is much faster (a single atomic
operation) than locking a sys_common::Mutex on every access like Lazy
did.
However, SyncOnceCell does not use atexit() to drop the contained object
during shutdown.
As noted above, this is not a problem for stdin. It simply means stdin
is now usable during shutdown.
The atexit() call for stdout is moved to the stdio module. Unlike the
now-removed Lazy struct, SyncOnceCell does not have a 'gone and
unusable' state that panics. Instead of adding this again, this simply
replaces the buffer with one with zero capacity. This effectively
flushes the old buffer *and* makes any writes afterwards pass through
directly without touching a buffer, making print!() available during
shutdown without panicking.
2020-09-24 15:45:50 +00:00
|
|
|
Stdin {
|
2020-09-24 17:09:33 +00:00
|
|
|
inner: INSTANCE.get_or_init(|| {
|
|
|
|
Mutex::new(BufReader::with_capacity(stdio::STDIN_BUF_SIZE, stdin_raw()))
|
|
|
|
}),
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Stdin {
|
2015-04-13 14:21:32 +00:00
|
|
|
/// Locks this handle to the standard input stream, returning a readable
|
2015-02-25 07:27:20 +00:00
|
|
|
/// guard.
|
|
|
|
///
|
|
|
|
/// The lock is released when the returned lock goes out of scope. The
|
2015-12-30 10:41:04 +00:00
|
|
|
/// returned guard also implements the [`Read`] and [`BufRead`] traits for
|
2015-02-25 07:27:20 +00:00
|
|
|
/// accessing the underlying data.
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2016-07-29 22:56:14 +00:00
|
|
|
/// # Examples
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2021-08-06 15:59:02 +00:00
|
|
|
/// use std::io::{self, BufRead};
|
2016-07-29 22:56:14 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
|
|
|
/// let mut buffer = String::new();
|
|
|
|
/// let stdin = io::stdin();
|
|
|
|
/// let mut handle = stdin.lock();
|
2016-07-29 22:56:14 +00:00
|
|
|
///
|
2021-08-06 15:59:02 +00:00
|
|
|
/// handle.read_line(&mut buffer)?;
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2016-07-29 22:56:14 +00:00
|
|
|
/// ```
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2022-02-13 15:19:42 +00:00
|
|
|
pub fn lock(&self) -> StdinLock<'static> {
|
|
|
|
// Locks this handle with 'static lifetime. This depends on the
|
|
|
|
// implementation detail that the underlying `Mutex` is static.
|
|
|
|
StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
|
2020-02-23 20:19:25 +00:00
|
|
|
/// Locks this handle and reads a line of input, appending it to the specified buffer.
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
///
|
|
|
|
/// For detailed semantics of this method, see the documentation on
|
2015-12-30 10:41:04 +00:00
|
|
|
/// [`BufRead::read_line`].
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2015-06-27 20:58:49 +00:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// use std::io;
|
|
|
|
///
|
|
|
|
/// let mut input = String::new();
|
|
|
|
/// match io::stdin().read_line(&mut input) {
|
|
|
|
/// Ok(n) => {
|
2022-02-12 19:16:17 +00:00
|
|
|
/// println!("{n} bytes read");
|
|
|
|
/// println!("{input}");
|
2015-06-27 20:58:49 +00:00
|
|
|
/// }
|
2022-02-12 19:16:17 +00:00
|
|
|
/// Err(error) => println!("error: {error}"),
|
2015-06-27 20:58:49 +00:00
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// You can run the example one of two ways:
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// - Pipe some text to it, e.g., `printf foo | path/to/executable`
|
2015-06-27 20:58:49 +00:00
|
|
|
/// - Give it text interactively by running the executable directly,
|
2015-12-23 15:46:59 +00:00
|
|
|
/// in which case it will wait for the Enter key to be pressed before
|
2015-06-27 20:58:49 +00:00
|
|
|
/// continuing
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-07-08 19:53:45 +00:00
|
|
|
pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
self.lock().read_line(buf)
|
|
|
|
}
|
2021-07-01 23:05:24 +00:00
|
|
|
|
2021-06-17 18:39:13 +00:00
|
|
|
/// Consumes this handle and returns an iterator over input lines.
|
|
|
|
///
|
|
|
|
/// For detailed semantics of this method, see the documentation on
|
|
|
|
/// [`BufRead::lines`].
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// use std::io;
|
|
|
|
///
|
|
|
|
/// let lines = io::stdin().lines();
|
|
|
|
/// for line in lines {
|
|
|
|
/// println!("got a line: {}", line.unwrap());
|
|
|
|
/// }
|
|
|
|
/// ```
|
2021-10-10 23:50:52 +00:00
|
|
|
#[must_use = "`self` will be dropped if the result is not used"]
|
2022-04-06 15:26:33 +00:00
|
|
|
#[stable(feature = "stdin_forwarders", since = "1.62.0")]
|
2021-06-17 18:39:13 +00:00
|
|
|
pub fn lines(self) -> Lines<StdinLock<'static>> {
|
2022-02-13 15:19:42 +00:00
|
|
|
self.lock().lines()
|
2021-06-17 18:39:13 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "std_debug", since = "1.16.0")]
|
2016-11-25 18:21:49 +00:00
|
|
|
impl fmt::Debug for Stdin {
|
2019-03-01 08:34:11 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2021-04-05 11:31:11 +00:00
|
|
|
f.debug_struct("Stdin").finish_non_exhaustive()
|
2016-11-25 18:21:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
impl Read for Stdin {
|
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
|
|
self.lock().read(buf)
|
|
|
|
}
|
2019-04-27 15:34:08 +00:00
|
|
|
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
self.lock().read_vectored(bufs)
|
|
|
|
}
|
2017-05-15 01:29:18 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_read_vectored(&self) -> bool {
|
|
|
|
self.lock().is_read_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
2015-02-25 07:27:20 +00:00
|
|
|
self.lock().read_to_end(buf)
|
|
|
|
}
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
2015-02-25 07:27:20 +00:00
|
|
|
self.lock().read_to_string(buf)
|
|
|
|
}
|
2015-07-20 03:23:37 +00:00
|
|
|
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
|
|
|
self.lock().read_exact(buf)
|
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2020-08-07 23:30:03 +00:00
|
|
|
// only used by platform-dependent io::copy specializations, i.e. unused on some platforms
|
|
|
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
2020-07-28 22:35:01 +00:00
|
|
|
impl StdinLock<'_> {
|
|
|
|
pub(crate) fn as_mut_buf(&mut self) -> &mut BufReader<impl Read> {
|
|
|
|
&mut self.inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl Read for StdinLock<'_> {
|
2015-02-25 07:27:20 +00:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
|
|
self.inner.read(buf)
|
|
|
|
}
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
|
2019-04-27 15:34:08 +00:00
|
|
|
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
self.inner.read_vectored(bufs)
|
|
|
|
}
|
|
|
|
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_read_vectored(&self) -> bool {
|
|
|
|
self.inner.is_read_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
|
|
|
|
2020-05-28 19:02:48 +00:00
|
|
|
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
|
|
|
self.inner.read_to_end(buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
|
|
|
self.inner.read_to_string(buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
|
|
|
self.inner.read_exact(buf)
|
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2015-06-10 04:39:36 +00:00
|
|
|
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl BufRead for StdinLock<'_> {
|
2019-12-22 22:42:04 +00:00
|
|
|
fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
|
|
|
self.inner.fill_buf()
|
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
|
2019-12-22 22:42:04 +00:00
|
|
|
fn consume(&mut self, n: usize) {
|
|
|
|
self.inner.consume(n)
|
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
|
|
|
|
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
|
|
|
|
self.inner.read_until(byte, buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
|
|
|
|
self.inner.read_line(buf)
|
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "std_debug", since = "1.16.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl fmt::Debug for StdinLock<'_> {
|
2019-03-01 08:34:11 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2021-04-05 11:31:11 +00:00
|
|
|
f.debug_struct("StdinLock").finish_non_exhaustive()
|
2016-11-25 18:21:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 07:27:20 +00:00
|
|
|
/// A handle to the global standard output stream of the current process.
|
|
|
|
///
|
|
|
|
/// Each handle shares a global buffer of data to be written to the standard
|
|
|
|
/// output stream. Access is also synchronized via a lock and explicit control
|
2017-03-12 18:04:52 +00:00
|
|
|
/// over locking is available via the [`lock`] method.
|
2015-04-22 20:57:08 +00:00
|
|
|
///
|
2015-12-30 10:41:04 +00:00
|
|
|
/// Created by the [`io::stdout`] method.
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
|
|
|
///
|
2020-08-18 17:36:52 +00:00
|
|
|
/// [`lock`]: Stdout::lock
|
|
|
|
/// [`io::stdout`]: stdout
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub struct Stdout {
|
|
|
|
// FIXME: this should be LineWriter or BufWriter depending on the state of
|
|
|
|
// stdout (tty or not). Note that if this is not line buffered it
|
|
|
|
// should also flush-on-panic or some form of flush-on-abort.
|
2020-10-10 18:20:14 +00:00
|
|
|
inner: Pin<&'static ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>>,
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2021-02-18 01:58:15 +00:00
|
|
|
/// A locked reference to the [`Stdout`] handle.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2015-12-30 10:41:04 +00:00
|
|
|
/// This handle implements the [`Write`] trait, and is constructed via
|
2021-02-22 10:48:32 +00:00
|
|
|
/// the [`Stdout::lock`] method. See its documentation for more.
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
2022-01-21 20:43:07 +00:00
|
|
|
///
|
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
2021-10-09 03:31:57 +00:00
|
|
|
#[must_use = "if unused stdout will immediately unlock"]
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub struct StdoutLock<'a> {
|
2020-08-21 00:00:00 +00:00
|
|
|
inner: ReentrantMutexGuard<'a, RefCell<LineWriter<StdoutRaw>>>,
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2021-04-11 05:05:39 +00:00
|
|
|
static STDOUT: SyncOnceCell<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = SyncOnceCell::new();
|
|
|
|
|
2015-07-08 22:31:08 +00:00
|
|
|
/// Constructs a new handle to the standard output of the current process.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
|
|
|
/// Each handle returned is a reference to a shared global buffer whose access
|
2015-07-08 22:31:08 +00:00
|
|
|
/// is synchronized via a mutex. If you need more explicit control over
|
2019-09-11 12:03:40 +00:00
|
|
|
/// locking, see the [`Stdout::lock`] method.
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
|
|
|
///
|
2015-07-08 22:31:08 +00:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Using implicit synchronization:
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2015-07-08 22:31:08 +00:00
|
|
|
/// use std::io::{self, Write};
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
2019-03-28 18:28:39 +00:00
|
|
|
/// io::stdout().write_all(b"hello world")?;
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2015-07-08 22:31:08 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Using explicit synchronization:
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2015-07-08 22:31:08 +00:00
|
|
|
/// use std::io::{self, Write};
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
|
|
|
/// let stdout = io::stdout();
|
|
|
|
/// let mut handle = stdout.lock();
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2019-03-28 18:28:39 +00:00
|
|
|
/// handle.write_all(b"hello world")?;
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2015-07-08 22:31:08 +00:00
|
|
|
/// ```
|
2021-10-31 02:58:27 +00:00
|
|
|
#[must_use]
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub fn stdout() -> Stdout {
|
Remove std::io::lazy::Lazy in favour of SyncOnceCell
The (internal) std::io::lazy::Lazy was used to lazily initialize the
stdout and stdin buffers (and mutexes). It uses atexit() to register a
destructor to flush the streams on exit, and mark the streams as
'closed'. Using the stream afterwards would result in a panic.
Stdout uses a LineWriter which contains a BufWriter that will flush the
buffer on drop. This one is important to be executed during shutdown,
to make sure no buffered output is lost. It also forbids access to
stdout afterwards, since the buffer is already flushed and gone.
Stdin uses a BufReader, which does not implement Drop. It simply forgets
any previously read data that was not read from the buffer yet. This
means that in the case of stdin, the atexit() function's only effect is
making stdin inaccessible to the program, such that later accesses
result in a panic. This is uncessary, as it'd have been safe to access
stdin during shutdown of the program.
---
This change removes the entire io::lazy module in favour of
SyncOnceCell. SyncOnceCell's fast path is much faster (a single atomic
operation) than locking a sys_common::Mutex on every access like Lazy
did.
However, SyncOnceCell does not use atexit() to drop the contained object
during shutdown.
As noted above, this is not a problem for stdin. It simply means stdin
is now usable during shutdown.
The atexit() call for stdout is moved to the stdio module. Unlike the
now-removed Lazy struct, SyncOnceCell does not have a 'gone and
unusable' state that panics. Instead of adding this again, this simply
replaces the buffer with one with zero capacity. This effectively
flushes the old buffer *and* makes any writes afterwards pass through
directly without touching a buffer, making print!() available during
shutdown without panicking.
2020-09-24 15:45:50 +00:00
|
|
|
Stdout {
|
2021-04-11 05:05:39 +00:00
|
|
|
inner: Pin::static_ref(&STDOUT).get_or_init_pin(
|
|
|
|
|| unsafe { ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw()))) },
|
2020-10-10 18:20:14 +00:00
|
|
|
|mutex| unsafe { mutex.init() },
|
|
|
|
),
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-11 05:05:39 +00:00
|
|
|
pub fn cleanup() {
|
|
|
|
if let Some(instance) = STDOUT.get() {
|
|
|
|
// Flush the data and disable buffering during shutdown
|
|
|
|
// by replacing the line writer by one with zero
|
|
|
|
// buffering capacity.
|
|
|
|
// We use try_lock() instead of lock(), because someone
|
|
|
|
// might have leaked a StdoutLock, which would
|
|
|
|
// otherwise cause a deadlock here.
|
|
|
|
if let Some(lock) = Pin::static_ref(instance).try_lock() {
|
|
|
|
*lock.borrow_mut() = LineWriter::with_capacity(0, stdout_raw());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 07:27:20 +00:00
|
|
|
impl Stdout {
|
2015-04-13 14:21:32 +00:00
|
|
|
/// Locks this handle to the standard output stream, returning a writable
|
2015-02-25 07:27:20 +00:00
|
|
|
/// guard.
|
|
|
|
///
|
|
|
|
/// The lock is released when the returned lock goes out of scope. The
|
|
|
|
/// returned guard also implements the `Write` trait for writing data.
|
2016-07-29 22:57:20 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2016-07-29 22:57:20 +00:00
|
|
|
/// use std::io::{self, Write};
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
2022-02-13 15:19:42 +00:00
|
|
|
/// let mut stdout = io::stdout().lock();
|
2016-07-29 22:57:20 +00:00
|
|
|
///
|
2022-02-13 15:19:42 +00:00
|
|
|
/// stdout.write_all(b"hello world")?;
|
2016-07-29 22:57:20 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2016-07-29 22:57:20 +00:00
|
|
|
/// ```
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2022-02-13 15:19:42 +00:00
|
|
|
pub fn lock(&self) -> StdoutLock<'static> {
|
|
|
|
// Locks this handle with 'static lifetime. This depends on the
|
|
|
|
// implementation detail that the underlying `ReentrantMutex` is
|
|
|
|
// static.
|
2020-03-12 18:39:30 +00:00
|
|
|
StdoutLock { inner: self.inner.lock() }
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "std_debug", since = "1.16.0")]
|
2016-11-25 18:21:49 +00:00
|
|
|
impl fmt::Debug for Stdout {
|
2019-03-01 08:34:11 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2021-04-05 11:31:11 +00:00
|
|
|
f.debug_struct("Stdout").finish_non_exhaustive()
|
2016-11-25 18:21:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
impl Write for Stdout {
|
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write(buf)
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_vectored(bufs)
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
}
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
2020-09-11 09:11:34 +00:00
|
|
|
io::Write::is_write_vectored(&&*self)
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).flush()
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_all(buf)
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_all_vectored(bufs)
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
2020-06-17 23:48:51 +00:00
|
|
|
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_fmt(args)
|
2020-06-17 23:48:51 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-09-02 21:25:09 +00:00
|
|
|
|
2020-09-21 06:52:59 +00:00
|
|
|
#[stable(feature = "write_mt", since = "1.48.0")]
|
2020-09-02 21:25:09 +00:00
|
|
|
impl Write for &Stdout {
|
2015-02-25 07:27:20 +00:00
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
|
|
self.lock().write(buf)
|
|
|
|
}
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
self.lock().write_vectored(bufs)
|
|
|
|
}
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
|
|
|
self.lock().is_write_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
|
|
self.lock().flush()
|
|
|
|
}
|
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
|
|
|
self.lock().write_all(buf)
|
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
|
|
|
self.lock().write_all_vectored(bufs)
|
|
|
|
}
|
2020-06-17 23:48:51 +00:00
|
|
|
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
|
|
|
|
self.lock().write_fmt(args)
|
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-09-02 21:25:09 +00:00
|
|
|
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl Write for StdoutLock<'_> {
|
2015-02-25 07:27:20 +00:00
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
2016-03-10 19:09:02 +00:00
|
|
|
self.inner.borrow_mut().write(buf)
|
2015-04-03 21:46:54 +00:00
|
|
|
}
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
self.inner.borrow_mut().write_vectored(bufs)
|
|
|
|
}
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
|
|
|
self.inner.borrow_mut().is_write_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
2015-04-03 21:46:54 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
|
|
self.inner.borrow_mut().flush()
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
|
|
|
self.inner.borrow_mut().write_all(buf)
|
|
|
|
}
|
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
|
|
|
self.inner.borrow_mut().write_all_vectored(bufs)
|
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "std_debug", since = "1.16.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl fmt::Debug for StdoutLock<'_> {
|
2019-03-01 08:34:11 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2021-04-05 11:31:11 +00:00
|
|
|
f.debug_struct("StdoutLock").finish_non_exhaustive()
|
2016-11-25 18:21:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 07:27:20 +00:00
|
|
|
/// A handle to the standard error stream of a process.
|
|
|
|
///
|
2015-12-30 10:41:04 +00:00
|
|
|
/// For more information, see the [`io::stderr`] method.
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2020-08-18 17:36:52 +00:00
|
|
|
/// [`io::stderr`]: stderr
|
2019-02-04 06:38:43 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
2022-01-21 20:43:07 +00:00
|
|
|
///
|
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub struct Stderr {
|
2020-10-10 18:20:14 +00:00
|
|
|
inner: Pin<&'static ReentrantMutex<RefCell<StderrRaw>>>,
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2021-02-18 01:58:15 +00:00
|
|
|
/// A locked reference to the [`Stderr`] handle.
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2021-02-18 01:58:15 +00:00
|
|
|
/// This handle implements the [`Write`] trait and is constructed via
|
2021-02-22 10:48:32 +00:00
|
|
|
/// the [`Stderr::lock`] method. See its documentation for more.
|
2015-12-24 00:52:27 +00:00
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
2022-01-21 20:43:07 +00:00
|
|
|
///
|
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
2021-10-09 03:31:57 +00:00
|
|
|
#[must_use = "if unused stderr will immediately unlock"]
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub struct StderrLock<'a> {
|
2020-08-21 00:00:00 +00:00
|
|
|
inner: ReentrantMutexGuard<'a, RefCell<StderrRaw>>,
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 22:31:08 +00:00
|
|
|
/// Constructs a new handle to the standard error of the current process.
|
|
|
|
///
|
|
|
|
/// This handle is not buffered.
|
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// ### Note: Windows Portability Considerations
|
|
|
|
///
|
2019-02-04 06:38:43 +00:00
|
|
|
/// When operating in a console, the Windows implementation of this stream does not support
|
|
|
|
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
|
|
|
|
/// an error.
|
|
|
|
///
|
2022-01-21 20:43:07 +00:00
|
|
|
/// In a process with a detached console, such as one using
|
|
|
|
/// `#![windows_subsystem = "windows"]`, or in a child process spawned from such a process,
|
|
|
|
/// the contained handle will be null. In such cases, the standard library's `Read` and
|
|
|
|
/// `Write` will do nothing and silently succeed. All other I/O operations, via the
|
|
|
|
/// standard library or via raw Windows API calls, will fail.
|
|
|
|
///
|
2015-07-08 22:31:08 +00:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Using implicit synchronization:
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2015-07-08 22:31:08 +00:00
|
|
|
/// use std::io::{self, Write};
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
2019-03-28 18:28:39 +00:00
|
|
|
/// io::stderr().write_all(b"hello world")?;
|
2015-07-08 22:31:08 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2015-07-08 22:31:08 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Using explicit synchronization:
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// ```no_run
|
2015-07-08 22:31:08 +00:00
|
|
|
/// use std::io::{self, Write};
|
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// fn main() -> io::Result<()> {
|
|
|
|
/// let stderr = io::stderr();
|
|
|
|
/// let mut handle = stderr.lock();
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2019-03-28 18:28:39 +00:00
|
|
|
/// handle.write_all(b"hello world")?;
|
2015-02-25 07:27:20 +00:00
|
|
|
///
|
2018-03-25 02:56:07 +00:00
|
|
|
/// Ok(())
|
|
|
|
/// }
|
2015-07-08 22:31:08 +00:00
|
|
|
/// ```
|
2021-10-31 02:58:27 +00:00
|
|
|
#[must_use]
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
pub fn stderr() -> Stderr {
|
2020-10-10 18:13:03 +00:00
|
|
|
// Note that unlike `stdout()` we don't use `at_exit` here to register a
|
|
|
|
// destructor. Stderr is not buffered , so there's no need to run a
|
|
|
|
// destructor for flushing the buffer
|
Remove std::io::lazy::Lazy in favour of SyncOnceCell
The (internal) std::io::lazy::Lazy was used to lazily initialize the
stdout and stdin buffers (and mutexes). It uses atexit() to register a
destructor to flush the streams on exit, and mark the streams as
'closed'. Using the stream afterwards would result in a panic.
Stdout uses a LineWriter which contains a BufWriter that will flush the
buffer on drop. This one is important to be executed during shutdown,
to make sure no buffered output is lost. It also forbids access to
stdout afterwards, since the buffer is already flushed and gone.
Stdin uses a BufReader, which does not implement Drop. It simply forgets
any previously read data that was not read from the buffer yet. This
means that in the case of stdin, the atexit() function's only effect is
making stdin inaccessible to the program, such that later accesses
result in a panic. This is uncessary, as it'd have been safe to access
stdin during shutdown of the program.
---
This change removes the entire io::lazy module in favour of
SyncOnceCell. SyncOnceCell's fast path is much faster (a single atomic
operation) than locking a sys_common::Mutex on every access like Lazy
did.
However, SyncOnceCell does not use atexit() to drop the contained object
during shutdown.
As noted above, this is not a problem for stdin. It simply means stdin
is now usable during shutdown.
The atexit() call for stdout is moved to the stdio module. Unlike the
now-removed Lazy struct, SyncOnceCell does not have a 'gone and
unusable' state that panics. Instead of adding this again, this simply
replaces the buffer with one with zero capacity. This effectively
flushes the old buffer *and* makes any writes afterwards pass through
directly without touching a buffer, making print!() available during
shutdown without panicking.
2020-09-24 15:45:50 +00:00
|
|
|
static INSTANCE: SyncOnceCell<ReentrantMutex<RefCell<StderrRaw>>> = SyncOnceCell::new();
|
|
|
|
|
|
|
|
Stderr {
|
2020-10-10 18:20:14 +00:00
|
|
|
inner: Pin::static_ref(&INSTANCE).get_or_init_pin(
|
|
|
|
|| unsafe { ReentrantMutex::new(RefCell::new(stderr_raw())) },
|
|
|
|
|mutex| unsafe { mutex.init() },
|
|
|
|
),
|
Remove std::io::lazy::Lazy in favour of SyncOnceCell
The (internal) std::io::lazy::Lazy was used to lazily initialize the
stdout and stdin buffers (and mutexes). It uses atexit() to register a
destructor to flush the streams on exit, and mark the streams as
'closed'. Using the stream afterwards would result in a panic.
Stdout uses a LineWriter which contains a BufWriter that will flush the
buffer on drop. This one is important to be executed during shutdown,
to make sure no buffered output is lost. It also forbids access to
stdout afterwards, since the buffer is already flushed and gone.
Stdin uses a BufReader, which does not implement Drop. It simply forgets
any previously read data that was not read from the buffer yet. This
means that in the case of stdin, the atexit() function's only effect is
making stdin inaccessible to the program, such that later accesses
result in a panic. This is uncessary, as it'd have been safe to access
stdin during shutdown of the program.
---
This change removes the entire io::lazy module in favour of
SyncOnceCell. SyncOnceCell's fast path is much faster (a single atomic
operation) than locking a sys_common::Mutex on every access like Lazy
did.
However, SyncOnceCell does not use atexit() to drop the contained object
during shutdown.
As noted above, this is not a problem for stdin. It simply means stdin
is now usable during shutdown.
The atexit() call for stdout is moved to the stdio module. Unlike the
now-removed Lazy struct, SyncOnceCell does not have a 'gone and
unusable' state that panics. Instead of adding this again, this simply
replaces the buffer with one with zero capacity. This effectively
flushes the old buffer *and* makes any writes afterwards pass through
directly without touching a buffer, making print!() available during
shutdown without panicking.
2020-09-24 15:45:50 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Stderr {
|
2015-04-13 14:21:32 +00:00
|
|
|
/// Locks this handle to the standard error stream, returning a writable
|
2015-02-25 07:27:20 +00:00
|
|
|
/// guard.
|
|
|
|
///
|
|
|
|
/// The lock is released when the returned lock goes out of scope. The
|
2020-08-18 17:36:52 +00:00
|
|
|
/// returned guard also implements the [`Write`] trait for writing data.
|
2016-07-29 22:53:18 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::io::{self, Write};
|
|
|
|
///
|
|
|
|
/// fn foo() -> io::Result<()> {
|
|
|
|
/// let stderr = io::stderr();
|
|
|
|
/// let mut handle = stderr.lock();
|
|
|
|
///
|
2019-03-28 18:28:39 +00:00
|
|
|
/// handle.write_all(b"hello world")?;
|
2016-07-29 22:53:18 +00:00
|
|
|
///
|
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2022-02-13 15:19:42 +00:00
|
|
|
pub fn lock(&self) -> StderrLock<'static> {
|
|
|
|
// Locks this handle with 'static lifetime. This depends on the
|
|
|
|
// implementation detail that the underlying `ReentrantMutex` is
|
|
|
|
// static.
|
2020-03-12 18:39:30 +00:00
|
|
|
StderrLock { inner: self.inner.lock() }
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "std_debug", since = "1.16.0")]
|
2016-11-25 18:21:49 +00:00
|
|
|
impl fmt::Debug for Stderr {
|
2019-03-01 08:34:11 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2021-04-05 11:31:11 +00:00
|
|
|
f.debug_struct("Stderr").finish_non_exhaustive()
|
2016-11-25 18:21:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 07:27:20 +00:00
|
|
|
impl Write for Stderr {
|
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write(buf)
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_vectored(bufs)
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
}
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
2020-09-11 09:11:34 +00:00
|
|
|
io::Write::is_write_vectored(&&*self)
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).flush()
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_all(buf)
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_all_vectored(bufs)
|
2020-05-28 19:02:48 +00:00
|
|
|
}
|
2020-06-17 23:48:51 +00:00
|
|
|
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
|
2020-09-11 09:11:34 +00:00
|
|
|
(&*self).write_fmt(args)
|
2020-06-17 23:48:51 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-09-02 21:25:09 +00:00
|
|
|
|
2020-09-21 06:52:59 +00:00
|
|
|
#[stable(feature = "write_mt", since = "1.48.0")]
|
2020-09-02 21:25:09 +00:00
|
|
|
impl Write for &Stderr {
|
2015-02-25 07:27:20 +00:00
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
|
|
self.lock().write(buf)
|
|
|
|
}
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
self.lock().write_vectored(bufs)
|
|
|
|
}
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
|
|
|
self.lock().is_write_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
|
|
self.lock().flush()
|
|
|
|
}
|
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
|
|
|
self.lock().write_all(buf)
|
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
|
|
|
self.lock().write_all_vectored(bufs)
|
|
|
|
}
|
2020-06-17 23:48:51 +00:00
|
|
|
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> {
|
|
|
|
self.lock().write_fmt(args)
|
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-09-02 21:25:09 +00:00
|
|
|
|
std: Stabilize the `io` module
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.
This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.
Stable APIs:
* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`
Unstable APIs:
(reasons can be found in the commit itself)
* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`
Deprecated APIs
* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`
Changes in functionality:
* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
by folding functionality into the corresponding trait.
[breaking-change]
2015-03-11 21:16:46 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl Write for StderrLock<'_> {
|
2015-02-25 07:27:20 +00:00
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
2016-03-10 19:09:02 +00:00
|
|
|
self.inner.borrow_mut().write(buf)
|
2015-04-03 21:46:54 +00:00
|
|
|
}
|
2019-04-27 15:34:08 +00:00
|
|
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
std: Add `{read,write}_vectored` for more types
This commit implements the `{read,write}_vectored` methods on more types
in the standard library, namely:
* `std::fs::File`
* `std::process::ChildStd{in,out,err}`
* `std::io::Std{in,out,err}`
* `std::io::Std{in,out,err}Lock`
* `std::io::Std{in,out,err}Raw`
Where supported the OS implementations hook up to native support,
otherwise it falls back to the already-defaulted implementation.
2019-04-10 19:51:25 +00:00
|
|
|
self.inner.borrow_mut().write_vectored(bufs)
|
|
|
|
}
|
2020-01-03 19:26:05 +00:00
|
|
|
#[inline]
|
2020-03-12 01:02:52 +00:00
|
|
|
fn is_write_vectored(&self) -> bool {
|
|
|
|
self.inner.borrow_mut().is_write_vectored()
|
2020-01-03 19:26:05 +00:00
|
|
|
}
|
2015-04-03 21:46:54 +00:00
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
|
|
self.inner.borrow_mut().flush()
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2020-05-28 19:02:48 +00:00
|
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
|
|
|
self.inner.borrow_mut().write_all(buf)
|
|
|
|
}
|
|
|
|
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
|
|
|
self.inner.borrow_mut().write_all_vectored(bufs)
|
|
|
|
}
|
2015-02-25 07:27:20 +00:00
|
|
|
}
|
2015-03-11 22:24:14 +00:00
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "std_debug", since = "1.16.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl fmt::Debug for StderrLock<'_> {
|
2019-03-01 08:34:11 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2021-04-05 11:31:11 +00:00
|
|
|
f.debug_struct("StderrLock").finish_non_exhaustive()
|
2016-11-25 18:21:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-03 23:11:14 +00:00
|
|
|
/// Sets the thread-local output capture buffer and returns the old one.
|
2019-12-22 22:42:04 +00:00
|
|
|
#[unstable(
|
2020-11-03 23:11:14 +00:00
|
|
|
feature = "internal_output_capture",
|
|
|
|
reason = "this function is meant for use in the test crate \
|
|
|
|
and may disappear in the future",
|
2019-12-22 22:42:04 +00:00
|
|
|
issue = "none"
|
|
|
|
)]
|
2015-03-08 22:30:15 +00:00
|
|
|
#[doc(hidden)]
|
2020-11-03 23:11:14 +00:00
|
|
|
pub fn set_output_capture(sink: Option<LocalStream>) -> Option<LocalStream> {
|
|
|
|
if sink.is_none() && !OUTPUT_CAPTURE_USED.load(Ordering::Relaxed) {
|
|
|
|
// OUTPUT_CAPTURE is definitely None since OUTPUT_CAPTURE_USED is false.
|
2020-09-27 13:35:35 +00:00
|
|
|
return None;
|
|
|
|
}
|
2020-11-03 23:11:14 +00:00
|
|
|
OUTPUT_CAPTURE_USED.store(true, Ordering::Relaxed);
|
|
|
|
OUTPUT_CAPTURE.with(move |slot| slot.replace(sink))
|
2020-08-05 01:42:36 +00:00
|
|
|
}
|
|
|
|
|
2020-11-03 23:11:14 +00:00
|
|
|
/// Write `args` to the capture buffer if enabled and possible, or `global_s`
|
2017-04-13 14:48:09 +00:00
|
|
|
/// otherwise. `label` identifies the stream in a panic message.
|
|
|
|
///
|
|
|
|
/// This function is used to print error messages, so it takes extra
|
2019-10-20 21:13:41 +00:00
|
|
|
/// care to avoid causing a panic when `local_s` is unusable.
|
2018-02-28 23:07:27 +00:00
|
|
|
/// For instance, if the TLS key for the local stream is
|
|
|
|
/// already destroyed, or if the local stream is locked by another
|
2017-04-13 14:48:09 +00:00
|
|
|
/// thread, it will just fall back to the global stream.
|
|
|
|
///
|
|
|
|
/// However, if the actual I/O causes an error, this function does panic.
|
2020-11-03 23:11:14 +00:00
|
|
|
fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
|
|
|
|
where
|
2018-02-28 17:59:12 +00:00
|
|
|
T: Write,
|
|
|
|
{
|
2020-11-03 23:11:14 +00:00
|
|
|
if OUTPUT_CAPTURE_USED.load(Ordering::Relaxed)
|
|
|
|
&& OUTPUT_CAPTURE.try_with(|s| {
|
2020-11-03 20:44:21 +00:00
|
|
|
// Note that we completely remove a local sink to write to in case
|
|
|
|
// our printing recursively panics/prints, so the recursive
|
|
|
|
// panic/print goes to the global sink instead of our local sink.
|
|
|
|
s.take().map(|w| {
|
|
|
|
let _ = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
|
2020-11-03 21:59:04 +00:00
|
|
|
s.set(Some(w));
|
2020-11-03 20:44:21 +00:00
|
|
|
})
|
|
|
|
}) == Ok(Some(()))
|
|
|
|
{
|
2021-12-14 14:23:34 +00:00
|
|
|
// Successfully wrote to capture buffer.
|
2020-11-03 20:44:21 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Err(e) = global_s().write_fmt(args) {
|
2022-02-12 19:16:17 +00:00
|
|
|
panic!("failed printing to {label}: {e}");
|
2015-03-08 22:30:15 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-18 16:03:17 +00:00
|
|
|
|
2019-12-22 22:42:04 +00:00
|
|
|
#[unstable(
|
|
|
|
feature = "print_internals",
|
|
|
|
reason = "implementation detail which may disappear or be replaced at any time",
|
|
|
|
issue = "none"
|
|
|
|
)]
|
2017-04-13 14:48:09 +00:00
|
|
|
#[doc(hidden)]
|
2019-02-14 12:36:01 +00:00
|
|
|
#[cfg(not(test))]
|
2019-03-01 08:34:11 +00:00
|
|
|
pub fn _print(args: fmt::Arguments<'_>) {
|
2020-11-03 23:11:14 +00:00
|
|
|
print_to(args, stdout, "stdout");
|
2017-04-13 14:48:09 +00:00
|
|
|
}
|
|
|
|
|
2019-12-22 22:42:04 +00:00
|
|
|
#[unstable(
|
|
|
|
feature = "print_internals",
|
|
|
|
reason = "implementation detail which may disappear or be replaced at any time",
|
|
|
|
issue = "none"
|
|
|
|
)]
|
2017-01-21 18:38:11 +00:00
|
|
|
#[doc(hidden)]
|
2019-02-14 12:36:01 +00:00
|
|
|
#[cfg(not(test))]
|
2019-03-01 08:34:11 +00:00
|
|
|
pub fn _eprint(args: fmt::Arguments<'_>) {
|
2020-11-03 23:11:14 +00:00
|
|
|
print_to(args, stderr, "stderr");
|
2017-01-21 18:38:11 +00:00
|
|
|
}
|
|
|
|
|
2019-02-14 12:36:01 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
pub use realstd::io::{_eprint, _print};
|