| 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)]
|
| 7 | use std::os::unix::io::AsRawFd;
|
| 8 | #[cfg (windows)]
|
| 9 | use std::os::windows::io::AsRawHandle;
|
| 10 |
|
| 11 | #[cfg (windows)]
|
| 12 | use 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 | /// ```
|
| 22 | pub 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 (all(unix, feature = "libc" ))]
|
| 30 | impl<S: AsRawFd> IsTty for S {
|
| 31 | fn is_tty(&self) -> bool {
|
| 32 | let fd = self.as_raw_fd();
|
| 33 | unsafe { libc::isatty(fd) == 1 }
|
| 34 | }
|
| 35 | }
|
| 36 |
|
| 37 | #[cfg (all(unix, not(feature = "libc" )))]
|
| 38 | impl<S: AsRawFd> IsTty for S {
|
| 39 | fn is_tty(&self) -> bool {
|
| 40 | let fd = self.as_raw_fd();
|
| 41 | rustix::termios::isatty(fd:unsafe { std::os::unix::io::BorrowedFd::borrow_raw(fd) })
|
| 42 | }
|
| 43 | }
|
| 44 |
|
| 45 | /// On windows, `GetConsoleMode` will return true if we are in a terminal.
|
| 46 | /// Otherwise false.
|
| 47 | #[cfg (windows)]
|
| 48 | impl<S: AsRawHandle> IsTty for S {
|
| 49 | fn is_tty(&self) -> bool {
|
| 50 | let mut mode = 0;
|
| 51 | let ok = unsafe { GetConsoleMode(self.as_raw_handle() as *mut _, &mut mode) };
|
| 52 | ok == 1
|
| 53 | }
|
| 54 | }
|
| 55 | |