1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
// SPDX-License-Identifier: Apache-2.0 OR MIT
use core::fmt;
use crate::{fd::AsFd, io, sys};
/// Constructs a new handle to the standard input of the current process.
///
/// Unlike [`std::io::stdin`], this function returns the `Result`.
///
/// # Platform-specific behavior
///
/// Currently, this function will always success on MIPS/MIPS64, On other architectures,
/// this may fail if semihosting is only partially supported.
///
/// Also, we have found that reading from stdin does not work well on MIPS/MIPS64.
///
/// [`std::io::stdin`]: https://doc.rust-lang.org/std/io/fn.stdin.html
pub fn stdin() -> io::Result<Stdin> {
sys::stdin().map(Stdin)
}
/// Constructs a new handle to the standard output of the current process.
///
/// Unlike [`std::io::stdout`], this function returns the `Result`.
///
/// # Platform-specific behavior
///
/// Currently, this function will always success on MIPS/MIPS64, On other architectures,
/// this may fail if semihosting is only partially supported.
///
/// [`std::io::stdout`]: https://doc.rust-lang.org/std/io/fn.stdout.html
pub fn stdout() -> io::Result<Stdout> {
sys::stdout().map(Stdout)
}
/// Constructs a new handle to the standard error of the current process.
///
/// Unlike [`std::io::stderr`], this function returns the `Result`.
///
/// # Platform-specific behavior
///
/// Currently, this function will always success on MIPS/MIPS64, On other architectures,
/// this may fail if semihosting is only partially supported.
///
/// [`std::io::stderr`]: https://doc.rust-lang.org/std/io/fn.stderr.html
pub fn stderr() -> io::Result<Stderr> {
sys::stderr().map(Stderr)
}
/// A handle to the standard input stream of a process.
///
/// Created by the [`io::stdin`] method.
pub struct Stdin(sys::StdioFd);
/// A handle to the standard output stream of a process.
///
/// Created by the [`io::stdout`] method.
pub struct Stdout(sys::StdioFd);
/// A handle to the standard error stream of a process.
///
/// Created by the [`io::stderr`] method.
pub struct Stderr(sys::StdioFd);
impl_as_fd!(Stdin, Stdout, Stderr);
impl io::Read for Stdin {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
sys::read(self.as_fd(), buf)
}
}
impl io::Write for Stdout {
fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
sys::write(self.as_fd(), bytes)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl io::Write for Stderr {
fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
sys::write(self.as_fd(), bytes)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl fmt::Debug for Stdin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Stdin").finish_non_exhaustive()
}
}
impl fmt::Debug for Stdout {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Stdout").finish_non_exhaustive()
}
}
impl fmt::Debug for Stderr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Stderr").finish_non_exhaustive()
}
}
/// Trait to determine if a descriptor/handle refers to a terminal/tty.
pub trait IsTerminal: crate::sealed::Sealed {
/// Returns `true` if the descriptor/handle refers to a terminal/tty.
///
/// On platforms where Rust does not know how to detect a terminal yet, this will return
/// `false`. This will also return `false` if an unexpected error occurred, such as from
/// passing an invalid file descriptor.
fn is_terminal(&self) -> bool;
}
macro_rules! impl_is_terminal {
($($t:ty),*$(,)?) => {$(
impl crate::sealed::Sealed for $t {}
impl crate::io::IsTerminal for $t {
#[inline]
fn is_terminal(&self) -> bool {
use crate::fd::AsFd;
crate::sys::is_terminal(self.as_fd())
}
}
)*}
}
impl_is_terminal!(Stdin, Stdout, Stderr);
#[cfg(feature = "fs")]
impl_is_terminal!(crate::fs::File);