diff --git a/src/os/mod.rs b/src/os/mod.rs index e5ba15f..94ebd17 100644 --- a/src/os/mod.rs +++ b/src/os/mod.rs @@ -13,7 +13,7 @@ use unix as os; use windows as os; /// Checks if stdout is a terminal -pub use os::istty; +pub use os::is_terminal; /// Enables ANSI support on Windows terminals /// @@ -23,13 +23,6 @@ pub use os::enable_ansi; /// Gets the size of the terminal pub use os::get_terminal_size; - -/// Struct representing a raw terminal -/// -/// This was done due to weirdness in the termios API (you have to store the original state of the -/// terminal to restore it) -pub use os::RawTerminal; - /// Enables raw mode /// /// Disables input echoing, line feeding, etc. diff --git a/src/os/unix.rs b/src/os/unix.rs index c386273..1a247e4 100644 --- a/src/os/unix.rs +++ b/src/os/unix.rs @@ -6,16 +6,15 @@ unsafe extern "C" { fn ioctl(fd: c_int, request: c_ulong, argp: *mut u8) -> c_int; fn tcgetattr(fd: c_int, termios_p: *mut Termios) -> c_int; fn tcsetattr(fd: c_int, optional_actions: c_int, termios: *mut Termios) -> c_int; - fn cfmakeraw(termios: *mut Termios); } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "redox"))] const TIOCGWINSZ: c_ulong = 0x5413; #[cfg(any(target_os = "macos", target_os = "freebsd"))] const TIOCGWINSZ: c_ulong = 0x40087468; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "redox"))] const NCCS: usize = 32; #[cfg(any(target_os = "macos", target_os = "freebsd"))] @@ -24,9 +23,9 @@ const NCCS: usize = 20; const STDIN_FILENO: c_int = 0; const STDOUT_FILENO: c_int = 1; -const ECHO: c_uint = 0; -const ICANON: c_uint = 0; -const ISIG: c_uint = 0; +const ECHO: c_uint = 8; +const ICANON: c_uint = 2; +const ISIG: c_uint = 1; #[repr(C)] #[derive(Debug, Clone, Copy)] @@ -47,31 +46,7 @@ struct Termios { cc: [u8; NCCS], } -#[repr(transparent)] -pub struct RawTerminal { - orig_termios: Termios, -} - -impl RawTerminal { - pub fn new() -> io::Result { - let mut orig_termios = unsafe { std::mem::zeroed::() }; - get_attributes(STDIN_FILENO, &mut orig_termios)?; - - let mut current_termios = orig_termios.clone(); - unsafe { cfmakeraw(&raw mut current_termios) }; - set_attributes(STDIN_FILENO, &mut current_termios)?; - - Ok(RawTerminal { orig_termios }) - } -} - -impl Drop for RawTerminal { - fn drop(&mut self) { - _ = set_attributes(STDIN_FILENO, &mut self.orig_termios); - } -} - -pub fn istty() -> bool { +#[must_use] pub fn is_terminal() -> bool { unsafe { isatty(1) != 0 } } @@ -83,7 +58,7 @@ pub fn enable_ansi() -> io::Result<()> { pub fn get_terminal_size() -> io::Result<(c_ushort, c_ushort)> { let mut winsize = unsafe { std::mem::zeroed::() }; - let ioctl_result = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &raw mut winsize as *mut u8) }; + let ioctl_result = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, (&raw mut winsize).cast::()) }; if ioctl_result == 0 { Ok((winsize.col, winsize.row)) @@ -116,7 +91,7 @@ fn get_attributes(fd: c_int, termios: &mut Termios) -> io::Result<()> { } fn set_attributes(fd: c_int, termios: &mut Termios) -> io::Result<()> { - if unsafe { tcsetattr(fd, 0, termios as *mut _) } != 0 { + if unsafe { tcsetattr(fd, 0, std::ptr::from_mut(termios)) } != 0 { return Err(io::Error::last_os_error()) } Ok(()) diff --git a/src/os/windows.rs b/src/os/windows.rs index 205d441..1d934d2 100644 --- a/src/os/windows.rs +++ b/src/os/windows.rs @@ -37,30 +37,7 @@ struct ConsoleScreenBufferInfo { dwMaximumWindowSizeY: u16, } -pub struct RawTerminal { } - -impl RawTerminal { - pub fn new() -> io::Result { - let handle = get_std_handle(STD_INPUT_HANDLE)?; - let mut dwMode = 0; - get_console_mode(handle, &raw mut dwMode)?; - dwMode &= !(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); - set_console_mode(handle, &raw mut dwMode)?; - Ok(RawTerminal { }) - } -} - -impl Drop for RawTerminal { - fn drop(&mut self) { - let handle = get_std_handle(STD_INPUT_HANDLE).unwrap(); - let mut dwMode = 0; - _ = get_console_mode(handle, &raw mut dwMode); - dwMode |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; - _ = set_console_mode(handle, &raw mut dwMode); - } -} - -pub fn istty() -> bool { +pub fn is_terminal() -> bool { let handle = get_std_handle(STD_OUTPUT_HANDLE); match handle { Ok(handle) => { diff --git a/test.c b/test.c new file mode 100644 index 0000000..9ad847f --- /dev/null +++ b/test.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int main() { + printf("ECHO: 0x%x\n", ECHO); + printf("ICANON: 0x%x\n", ICANON); + printf("ISIG: 0x%x\n", ISIG); + + printf("\nNCCS: 0x%x\n", NCCS); + printf("TIOCFWINSZ: 0x%x\n", TIOCGWINSZ); + return 0; +} diff --git a/test.o b/test.o new file mode 100755 index 0000000..ffe01e3 Binary files /dev/null and b/test.o differ