use std::io;
use std::os::fd::AsRawFd;
use std::os::fd::BorrowedFd;
pub use libc::termios as Termios;
pub fn get_terminal_attr(fd: BorrowedFd) -> io::Result<Termios> {
unsafe {
let mut termios = std::mem::zeroed();
if libc::tcgetattr(fd.as_raw_fd(), &mut termios) < 0 {
return Err(io::Error::last_os_error());
}
Ok(termios)
}
}
pub fn set_terminal_attr(fd: BorrowedFd, termios: &Termios) -> io::Result<()> {
if unsafe { libc::tcsetattr(fd.as_raw_fd(), libc::TCSANOW, termios) } < 0 {
return Err(io::Error::last_os_error());
}
Ok(())
}
pub fn make_raw(termios: &mut Termios) {
unsafe { libc::cfmakeraw(termios) };
}
pub fn get_window_size(fd: BorrowedFd) -> io::Result<(u16, u16)> {
unsafe {
let mut winsize: libc::winsize = std::mem::zeroed();
if libc::ioctl(fd.as_raw_fd(), libc::TIOCGWINSZ, &mut winsize) < 0 {
return Err(io::Error::last_os_error());
}
Ok((winsize.ws_col, winsize.ws_row))
}
}
pub fn poll_input(fd: BorrowedFd, timeout_ms: i32) -> io::Result<bool> {
unsafe {
let mut fds = libc::pollfd {
fd: fd.as_raw_fd(),
events: libc::POLLIN,
revents: 0,
};
let ret = libc::poll(&mut fds, 1, timeout_ms);
if ret < 0 {
return Err(io::Error::last_os_error());
}
Ok(ret > 0 && (fds.revents & libc::POLLIN) != 0)
}
}