summaryrefslogtreecommitdiff
path: root/src/stty.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1994-01-24 20:46:23 +0000
committerJim Meyering <jim@meyering.net>1994-01-24 20:46:23 +0000
commit370edcd71f9fe1eac7ac62799a7114f630de09e3 (patch)
tree1e81e3e7a070055f3610744aa2be6ab26facad01 /src/stty.c
parenta63a148116d71ba64dc34f73c1826bb1073fd495 (diff)
downloadcoreutils-370edcd71f9fe1eac7ac62799a7114f630de09e3.tar.xz
merge with 1.9.2e
Diffstat (limited to 'src/stty.c')
-rw-r--r--src/stty.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/stty.c b/src/stty.c
index 414a2304a..98f503f6d 100644
--- a/src/stty.c
+++ b/src/stty.c
@@ -1089,6 +1089,47 @@ set_window_size (rows, cols)
if (cols >= 0)
win.ws_col = cols;
}
+
+#ifdef TIOCSSIZE
+ /* The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
+ This comment from sys/ttold.h describes Sun's twisted logic - a better
+ test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
+ At any rate, the problem is gone in Solaris 2.x.
+
+ Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
+ but they can be disambiguated by checking whether a "struct ttysize"
+ structure's "ts_lines" field is greater than 64K or not. If so,
+ it's almost certainly a "struct winsize" instead.
+
+ At any rate, the bug manifests itself when ws_row == 0; the symptom is
+ that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
+ ws_ypixel. Since GNU stty sets rows and columns separately, this bug
+ caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
+ "stty cols 0 rows 0" would do the right thing. On a little-endian
+ machine like the sun386i, the problem is the same, but for ws_col == 0.
+
+ The workaround is to do the ioctl once with row and col = 1 to set the
+ pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
+
+ if (win.ws_row == 0 || win.ws_col == 0)
+ {
+ struct ttysize ttysz;
+
+ ttysz.ts_lines = win.ws_row;
+ ttysz.ts_cols = win.ws_col;
+
+ win.ws_row = 1;
+ win.ws_col = 1;
+
+ if (ioctl (0, TIOCSWINSZ, (char *) &win))
+ error (1, errno, "standard input");
+
+ if (ioctl (0, TIOCSSIZE, (char *) &ttysz))
+ error (1, errno, "standard input");
+ return;
+ }
+#endif
+
if (ioctl (0, TIOCSWINSZ, (char *) &win))
error (1, errno, "standard input");
}