aboutsummaryrefslogtreecommitdiff
path: root/libbb/xfuncs.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-04-18 22:09:30 -0700
committerDenys Vlasenko <vda.linux@googlemail.com>2010-04-18 22:09:30 -0700
commitc175c4664734e5a363d8cc8668c08f551eff1485 (patch)
tree7a71009d3d5a9b3a0e8be65bf020f4605cee4bae /libbb/xfuncs.c
parentdef4783a8a8b00f58d224ff6735d3532809aeb54 (diff)
downloadbusybox-c175c4664734e5a363d8cc8668c08f551eff1485.tar.gz
vi: discover window size even on serial consoles. optional
function old new delta edit_file 671 761 +90 wh_helper - 57 +57 query_screen_dimensions 54 63 +9 ar_main 533 542 +9 refresh 767 773 +6 vi_main 242 243 +1 text_yank 56 54 -2 get_terminal_width_height 180 135 -45 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 5/2 up/down: 172/-47) Total: 125 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
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 aec165f06..d93dd2af9 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)