From d24f4d99e8abef9430076da55b24a2478ae1bb28 Mon Sep 17 00:00:00 2001 From: Sascha Wilde Date: Fri, 17 May 2024 17:03:42 +0200 Subject: [PATCH 1/2] If ioctl TIOCGWINSZ returns 0,0 try to use env vars instead. For some terminals (for example Emacs eshell/eterm) the ioctl with TIOCGWINSZ might falsely return 0 columns and 0 rows. If this happens we now try to use LINES and COLUMNS environment variables. Fixes #891 --- src/terminal/sys/unix.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/terminal/sys/unix.rs b/src/terminal/sys/unix.rs index ed545c5b..7839c3be 100644 --- a/src/terminal/sys/unix.rs +++ b/src/terminal/sys/unix.rs @@ -13,7 +13,7 @@ use std::fs::File; use std::os::unix::io::{IntoRawFd, RawFd}; -use std::{io, mem, process}; +use std::{env, io, mem, process}; // Some(Termios) -> we're in the raw mode and this is the previous mode // None -> we're not in the raw mode @@ -53,6 +53,10 @@ pub(crate) fn window_size() -> io::Result { }; if wrap_with_result(unsafe { ioctl(fd, TIOCGWINSZ.into(), &mut size) }).is_ok() { + if size.ws_row == 0 && size.ws_col == 0 { + size.ws_row = env::var("LINES").unwrap_or("0".to_string()).parse::().unwrap(); + size.ws_col = env::var("COLUMNS").unwrap_or("0".to_string()).parse::().unwrap(); + } return Ok(size.into()); } From 4a61d417aaaadd8dfd38f6305aaf771dc51de2d4 Mon Sep 17 00:00:00 2001 From: Sascha Wilde Date: Wed, 22 May 2024 17:15:51 +0200 Subject: [PATCH 2/2] Improvements suggested by Josh McKinney. - Added comment with rational for window size fallback mechanism. - Only unwrap once during parsing of env vars. --- src/terminal/sys/unix.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/terminal/sys/unix.rs b/src/terminal/sys/unix.rs index 7839c3be..ed43f808 100644 --- a/src/terminal/sys/unix.rs +++ b/src/terminal/sys/unix.rs @@ -53,9 +53,13 @@ pub(crate) fn window_size() -> io::Result { }; if wrap_with_result(unsafe { ioctl(fd, TIOCGWINSZ.into(), &mut size) }).is_ok() { + // For some terminals (for example Emacs eshell/eterm) the + // ioctl with TIOCGWINSZ might falsely return 0 columns and 0 + // rows. If this happens we try to use environment variables + // to determine the window size. if size.ws_row == 0 && size.ws_col == 0 { - size.ws_row = env::var("LINES").unwrap_or("0".to_string()).parse::().unwrap(); - size.ws_col = env::var("COLUMNS").unwrap_or("0".to_string()).parse::().unwrap(); + size.ws_row = env::var("LINES").map_or(Ok(0), |v| v.parse()).unwrap_or(0); + size.ws_col = env::var("COLUMNS").map_or(Ok(0), |v| v.parse()).unwrap_or(0); } return Ok(size.into()); }