summaryrefslogtreecommitdiff
path: root/libbb/xfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/xfuncs.c')
-rw-r--r--libbb/xfuncs.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index aec165f..d93dd2a 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -210,34 +210,40 @@ char* FAST_FUNC xmalloc_ttyname(int fd)
return buf;
}
-/* It is perfectly ok to pass in a NULL for either width or for
- * height, in which case that value will not be set. */
-int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *height)
+static int wh_helper(int value, int def_val, const char *env_name, int *err)
{
- struct winsize win = { 0, 0, 0, 0 };
- int ret = ioctl(fd, TIOCGWINSZ, &win);
-
- if (height) {
- if (!win.ws_row) {
- char *s = getenv("LINES");
- if (s) win.ws_row = atoi(s);
- }
- if (win.ws_row <= 1 || win.ws_row >= 30000)
- win.ws_row = 24;
- *height = (int) win.ws_row;
- }
-
- if (width) {
- if (!win.ws_col) {
- char *s = getenv("COLUMNS");
- if (s) win.ws_col = atoi(s);
+ if (value == 0) {
+ char *s = getenv(env_name);
+ if (s) {
+ value = atoi(s);
+ /* If LINES/COLUMNS are set, pretent that there is
+ * no error getting w/h, this prevents some ugly
+ * cursor tricks by our callers */
+ *err = 0;
}
- if (win.ws_col <= 1 || win.ws_col >= 30000)
- win.ws_col = 80;
- *width = (int) win.ws_col;
}
+ if (value <= 1 || value >= 30000)
+ value = def_val;
+ return value;
+}
- return ret;
+/* It is perfectly ok to pass in a NULL for either width or for
+ * height, in which case that value will not be set. */
+int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *height)
+{
+ struct winsize win;
+ int err;
+
+ win.ws_row = 0;
+ win.ws_col = 0;
+ /* I've seen ioctl returning 0, but row/col is (still?) 0.
+ * We treat that as an error too. */
+ err = ioctl(fd, TIOCGWINSZ, &win) != 0 || win.ws_row == 0;
+ if (height)
+ *height = wh_helper(win.ws_row, 24, "LINES", &err);
+ if (width)
+ *width = wh_helper(win.ws_col, 80, "COLUMNS", &err);
+ return err;
}
int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)