1//! Making it a little more convenient and safe to query whether
2//! something is a terminal teletype or not.
3//! This module defines the IsTty trait and the is_tty method to
4//! return true if the item represents a terminal.
5
6#[cfg(unix)]
7use std::os::unix::io::AsRawFd;
8#[cfg(windows)]
9use std::os::windows::io::AsRawHandle;
10
11#[cfg(windows)]
12use winapi::um::consoleapi::GetConsoleMode;
13
14/// Adds the `is_tty` method to types that might represent a terminal
15///
16/// ```rust
17/// use std::io::stdout;
18/// use crossterm::tty::IsTty;
19///
20/// let is_tty: bool = stdout().is_tty();
21/// ```
22pub trait IsTty {
23 /// Returns true when an instance is a terminal teletype, otherwise false.
24 fn is_tty(&self) -> bool;
25}
26
27/// On UNIX, the `isatty()` function returns true if a file
28/// descriptor is a terminal.
29#[cfg(unix)]
30impl<S: AsRawFd> IsTty for S {
31 fn is_tty(&self) -> bool {
32 let fd: i32 = self.as_raw_fd();
33 unsafe { libc::isatty(fd) == 1 }
34 }
35}
36
37/// On windows, `GetConsoleMode` will return true if we are in a terminal.
38/// Otherwise false.
39#[cfg(windows)]
40impl<S: AsRawHandle> IsTty for S {
41 fn is_tty(&self) -> bool {
42 let mut mode = 0;
43 let ok = unsafe { GetConsoleMode(self.as_raw_handle() as *mut _, &mut mode) };
44 ok == 1
45 }
46}
47