diff options
| author | Josh Triplett <josh@joshtriplett.org> | 2022-06-12 14:10:18 -0700 |
|---|---|---|
| committer | Josh Triplett <josh@joshtriplett.org> | 2022-10-15 00:35:38 +0100 |
| commit | 326ef470a8b379a180d6dc4bbef08990698a737a (patch) | |
| tree | 1466bde52b4eb3e910ec2811981bd656f9e9c757 /library/std/src/io/stdio.rs | |
| parent | bf15a9e5263fcea065a7ae9c179b2d24c2deb670 (diff) | |
| download | rust-326ef470a8b379a180d6dc4bbef08990698a737a.tar.gz rust-326ef470a8b379a180d6dc4bbef08990698a737a.zip | |
Add `IsTerminal` trait to determine if a descriptor or handle is a terminal
The UNIX and WASI implementations use `isatty`. The Windows implementation uses the same logic the `atty` crate uses, including the hack needed to detect msys terminals. Implement this trait for `File` and for `Stdin`/`Stdout`/`Stderr` and their locked counterparts on all platforms. On UNIX and WASI, implement it for `BorrowedFd`/`OwnedFd`. On Windows, implement it for `BorrowedHandle`/`OwnedHandle`. Based on https://github.com/rust-lang/rust/pull/91121 Co-authored-by: Matt Wilkinson <mattwilki17@gmail.com>
Diffstat (limited to 'library/std/src/io/stdio.rs')
| -rw-r--r-- | library/std/src/io/stdio.rs | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 4ccb2bf3231..1141a957d87 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -7,6 +7,7 @@ use crate::io::prelude::*; use crate::cell::{Cell, RefCell}; use crate::fmt; +use crate::fs::File; use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines}; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sync::{Arc, Mutex, MutexGuard, OnceLock}; @@ -1035,6 +1036,34 @@ pub(crate) fn attempt_print_to_stderr(args: fmt::Arguments<'_>) { let _ = stderr().write_fmt(args); } +/// Trait to determine if a descriptor/handle refers to a terminal/tty. +#[unstable(feature = "is_terminal", issue = "98070")] +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),*$(,)?) => {$( + #[unstable(feature = "sealed", issue = "none")] + impl crate::sealed::Sealed for $t {} + + #[unstable(feature = "is_terminal", issue = "98070")] + impl IsTerminal for $t { + #[inline] + fn is_terminal(&self) -> bool { + crate::sys::io::is_terminal(self) + } + } + )*} +} + +impl_is_terminal!(File, Stdin, StdinLock<'_>, Stdout, StdoutLock<'_>, Stderr, StderrLock<'_>); + #[unstable( feature = "print_internals", reason = "implementation detail which may disappear or be replaced at any time", |
