diff options
Diffstat (limited to 'third_party/rust/termion/src/sys/unix')
-rw-r--r-- | third_party/rust/termion/src/sys/unix/attr.rs | 29 | ||||
-rw-r--r-- | third_party/rust/termion/src/sys/unix/mod.rs | 33 | ||||
-rw-r--r-- | third_party/rust/termion/src/sys/unix/size.rs | 48 | ||||
-rw-r--r-- | third_party/rust/termion/src/sys/unix/tty.rs | 17 |
4 files changed, 127 insertions, 0 deletions
diff --git a/third_party/rust/termion/src/sys/unix/attr.rs b/third_party/rust/termion/src/sys/unix/attr.rs new file mode 100644 index 0000000000..5e21fbac8e --- /dev/null +++ b/third_party/rust/termion/src/sys/unix/attr.rs @@ -0,0 +1,29 @@ +use std::{io, mem}; + +use super::{cvt, Termios}; +use super::libc::c_int; + +pub fn get_terminal_attr() -> io::Result<Termios> { + extern "C" { + pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int; + } + unsafe { + let mut termios = mem::zeroed(); + cvt(tcgetattr(0, &mut termios))?; + Ok(termios) + } +} + +pub fn set_terminal_attr(termios: &Termios) -> io::Result<()> { + extern "C" { + pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int; + } + cvt(unsafe { tcsetattr(0, 0, termios) }).and(Ok(())) +} + +pub fn raw_terminal_attr(termios: &mut Termios) { + extern "C" { + pub fn cfmakeraw(termptr: *mut Termios); + } + unsafe { cfmakeraw(termios) } +} diff --git a/third_party/rust/termion/src/sys/unix/mod.rs b/third_party/rust/termion/src/sys/unix/mod.rs new file mode 100644 index 0000000000..08d73feb12 --- /dev/null +++ b/third_party/rust/termion/src/sys/unix/mod.rs @@ -0,0 +1,33 @@ +extern crate libc; + +use std::io; + +pub use self::libc::termios as Termios; + +pub mod attr; +pub mod size; +pub mod tty; + +// Support functions for converting libc return values to io errors { +trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +macro_rules! impl_is_minus_one { + ($($t:ident)*) => ($(impl IsMinusOne for $t { + fn is_minus_one(&self) -> bool { + *self == -1 + } + })*) + } + +impl_is_minus_one! { i8 i16 i32 i64 isize } + +fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> { + if t.is_minus_one() { + Err(io::Error::last_os_error()) + } else { + Ok(t) + } +} +// } End of support functions diff --git a/third_party/rust/termion/src/sys/unix/size.rs b/third_party/rust/termion/src/sys/unix/size.rs new file mode 100644 index 0000000000..9c2aaf1a8a --- /dev/null +++ b/third_party/rust/termion/src/sys/unix/size.rs @@ -0,0 +1,48 @@ +use std::{io, mem}; + +use super::cvt; +use super::libc::{c_ushort, ioctl, STDOUT_FILENO}; + +#[repr(C)] +struct TermSize { + row: c_ushort, + col: c_ushort, + _x: c_ushort, + _y: c_ushort, +} + +#[cfg(target_os = "linux")] +pub const TIOCGWINSZ: usize = 0x00005413; + +#[cfg(not(target_os = "linux"))] +pub const TIOCGWINSZ: usize = 0x40087468; + +// Since attributes on non-item statements is not stable yet, we use a function. +#[cfg(not(target_os = "android"))] +#[cfg(not(target_os = "redox"))] +#[cfg(target_pointer_width = "64")] +#[cfg(not(target_env = "musl"))] +fn tiocgwinsz() -> u64 { + TIOCGWINSZ as u64 +} +#[cfg(not(target_os = "android"))] +#[cfg(not(target_os = "redox"))] +#[cfg(target_pointer_width = "32")] +#[cfg(not(target_env = "musl"))] +fn tiocgwinsz() -> u32 { + TIOCGWINSZ as u32 +} + +#[cfg(any(target_env = "musl", target_os = "android"))] +fn tiocgwinsz() -> i32 { + TIOCGWINSZ as i32 +} + +/// Get the size of the terminal. +pub fn terminal_size() -> io::Result<(u16, u16)> { + unsafe { + let mut size: TermSize = mem::zeroed(); + cvt(ioctl(STDOUT_FILENO, tiocgwinsz(), &mut size as *mut _))?; + Ok((size.col as u16, size.row as u16)) + } +} diff --git a/third_party/rust/termion/src/sys/unix/tty.rs b/third_party/rust/termion/src/sys/unix/tty.rs new file mode 100644 index 0000000000..2be9363470 --- /dev/null +++ b/third_party/rust/termion/src/sys/unix/tty.rs @@ -0,0 +1,17 @@ +use std::{fs, io}; +use std::os::unix::io::AsRawFd; + +use super::libc; + + +/// Is this stream a TTY? +pub fn is_tty<T: AsRawFd>(stream: &T) -> bool { + unsafe { libc::isatty(stream.as_raw_fd()) == 1 } +} + +/// Get the TTY device. +/// +/// This allows for getting stdio representing _only_ the TTY, and not other streams. +pub fn get_tty() -> io::Result<fs::File> { + fs::OpenOptions::new().read(true).write(true).open("/dev/tty") +} |