diff --git a/examples/event-read.rs b/examples/event-read.rs index f4de7784a..dee4ab538 100644 --- a/examples/event-read.rs +++ b/examples/event-read.rs @@ -38,18 +38,23 @@ fn print_events() -> Result<()> { } fn main() -> Result<()> { + let result = std::panic::catch_unwind(|| { + println!("{}", HELP); - enable_raw_mode()?; + enable_raw_mode().expect("Can not enable raw mode"); let mut stdout = stdout(); - execute!(stdout, EnableMouseCapture)?; + execute!(stdout, EnableMouseCapture).expect("Can not enablemouse"); if let Err(e) = print_events() { println!("Error: {:?}\r", e); } - execute!(stdout, DisableMouseCapture)?; + execute!(stdout, DisableMouseCapture).expect("Can not disable mouse"); + }); - disable_raw_mode() + println!("result: {:?}", result); + disable_raw_mode().expect("Can not disable raw mode"); + Ok(()) } diff --git a/examples/test.rs b/examples/test.rs new file mode 100644 index 000000000..d9c12530b --- /dev/null +++ b/examples/test.rs @@ -0,0 +1,29 @@ +use mio::Interest; +use signal_hook::iterator::Signals; +use std::path::Path; +use std::io; + +fn main () { + let poll = Poll::new()?; + let registry = poll.registry(); + + let tty_raw_fd = input_fd.raw_fd(); + let mut tty_ev = SourceFd(&tty_raw_fd); + registry.register(&mut tty_ev, TTY_TOKEN, Interest::READABLE)?; + + let mut signals = Signals::new(&[signal_hook::SIGWINCH])?; + registry.register(&mut signals, SIGNAL_TOKEN, Interest::READABLE)?; + +} + + +fn open_rw>(path: P) -> io::Result { + use std::fs::OpenOptions; + + let file = OpenOptions::new() + .read(true) + .write(true) + .open(path)?; + + Ok(file.into_raw_fd()) +} \ No newline at end of file diff --git a/src/event/read.rs b/src/event/read.rs index ec2d895df..06d1181e9 100644 --- a/src/event/read.rs +++ b/src/event/read.rs @@ -24,7 +24,12 @@ impl Default for InternalEventReader { #[cfg(unix)] let source = UnixInternalEventSource::new(); - let source = source.ok().map(|x| Box::new(x) as Box); + let source = match source { + Ok(source) => Some(Box::new(source) as Box), + Err(e) => { + panic!("Event source can not be initialized: {:?}", e); + } + }; InternalEventReader { source, diff --git a/src/event/source/unix.rs b/src/event/source/unix.rs index bd6755c4c..cf5276775 100644 --- a/src/event/source/unix.rs +++ b/src/event/source/unix.rs @@ -40,7 +40,7 @@ pub(crate) struct UnixInternalEventSource { impl UnixInternalEventSource { pub fn new() -> Result { - Ok(UnixInternalEventSource::from_file_descriptor(tty_fd()?)?) + Ok(UnixInternalEventSource::from_file_descriptor(tty_fd(false)?)?) } pub(crate) fn from_file_descriptor(input_fd: FileDesc) -> Result { diff --git a/src/event/sys/unix/file_descriptor.rs b/src/event/sys/unix/file_descriptor.rs index c80557123..4cc762ada 100644 --- a/src/event/sys/unix/file_descriptor.rs +++ b/src/event/sys/unix/file_descriptor.rs @@ -6,6 +6,8 @@ use std::{ use libc::size_t; use crate::{ErrorKind, Result}; +use std::io::stdin; +use std::path::Path; /// A file descriptor wrapper. /// @@ -64,19 +66,35 @@ impl Drop for FileDesc { } /// Creates a file descriptor pointing to the standard input or `/dev/tty`. -pub fn tty_fd() -> Result { - let (fd, close_on_drop) = if unsafe { libc::isatty(libc::STDIN_FILENO) == 1 } { - (libc::STDIN_FILENO, false) - } else { - ( - fs::OpenOptions::new() - .read(true) - .write(true) - .open("/dev/tty")? - .into_raw_fd(), - true, - ) +pub fn tty_fd(close_on_drop: bool) -> Result { + use crate::tty::IsTty; + + let fd = match open_rw("/dev/tty") { + Ok(tty) => { + println!("Can open"); + tty + } + Err(e) => { + println!("Can not open"); + if stdin().is_tty() { + libc::STDIN_FILENO + } else { + return Err(ErrorKind::IoError(io::Error::new(io::ErrorKind::Other, "Failed to initialize input source. Crossterm first tried to open `/dev/tty` wereafter `libc::STDIN_FILENO`, but both could not be used."))); + } + } }; Ok(FileDesc::new(fd, close_on_drop)) } + + +fn open_rw>(path: P) -> io::Result { + use std::fs::OpenOptions; + + let file = OpenOptions::new() + .read(true) + .write(true) + .open(path)?; + + Ok(file.into_raw_fd()) +} diff --git a/src/terminal/sys/unix.rs b/src/terminal/sys/unix.rs index 5fddd627b..321d96cb5 100644 --- a/src/terminal/sys/unix.rs +++ b/src/terminal/sys/unix.rs @@ -1,11 +1,11 @@ //! UNIX related logic for terminal manipulation. use std::{io, mem, process, sync::Mutex}; -use crate::event::sys::unix::file_descriptor::FileDesc; +use crate::event::sys::unix::file_descriptor::{tty_fd, FileDesc}; use lazy_static::lazy_static; use libc::{ - cfmakeraw, ioctl, tcgetattr, tcsetattr, termios as Termios, winsize, STDIN_FILENO, - STDOUT_FILENO, TCSANOW, TIOCGWINSZ, + cfmakeraw, ioctl, tcgetattr, tcsetattr, termios as Termios, winsize, STDOUT_FILENO, TCSANOW, + TIOCGWINSZ, }; use crate::error::{ErrorKind, Result}; @@ -117,15 +117,18 @@ fn raw_terminal_attr(termios: &mut Termios) { } fn get_terminal_attr() -> Result { + let fd = tty_fd(true)?; + unsafe { let mut termios = mem::zeroed(); - wrap_with_result(tcgetattr(STDIN_FILENO, &mut termios))?; + wrap_with_result(tcgetattr(fd.raw_fd(), &mut termios))?; Ok(termios) } } fn set_terminal_attr(termios: &Termios) -> Result { - wrap_with_result(unsafe { tcsetattr(STDIN_FILENO, TCSANOW, termios) }) + let fd = tty_fd(true)?; + wrap_with_result(unsafe { tcsetattr(fd.raw_fd(), TCSANOW, termios) }) } pub fn wrap_with_result(result: i32) -> Result {