Skip to content

Commit 7a02b5f

Browse files
committed
Clarify that the WINCH deficiency is in telnet, not Linux
The problem with Linux not sending WINCH to a pty when the font size changes is due to the telnet protocol not including the pixel size. (Ssh does this correctly.)
1 parent 6c4da46 commit 7a02b5f

File tree

1 file changed

+46
-29
lines changed

1 file changed

+46
-29
lines changed

Diff for: chkwinch.sh

+46-29
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#
66
# Note that the Linux kernel actually includes space in struct winsize
77
# for PIXELS as well as rows and columns, but they are labelled as "unused".
8+
# However, that is not exactly true. The kernel skips sending SIGWINCH
9+
# if the window has not changed size. But, "size" is not just the rows
10+
# and columns. If the number of pixels change, SIGWINCH will be sent.
811

912
# Possible points of failure:
1013
# * Some terminals may fail to send SIGWINCH when fontsize changes.
@@ -24,7 +27,7 @@
2427

2528
# Test as working fine over ssh.
2629
#
27-
# It does not work over telnet. (But it should.)
30+
# It does not work over telnet. (Because telnet does not send pixel size.)
2831
# For more about telnet, please see the end of this file.
2932

3033
timeout=.25
@@ -69,40 +72,54 @@ while :; do sleep .1; done
6972
# for both client and server), this script fails. The symptoms are
7073
# odd. Turning on 'show option' shows that a new window size *is* sent
7174
# every time the font size change. However, it is not getting turned
72-
# into a WINCH signal. This is likely because something is detecting
73-
# that the rows and columns have not changed and is deciding not to
74-
# send the signal. I checked the telnetd source and it seems to always
75-
# use the TIOCSWINSZ ioctl, so that is probably fine. Could it be the
76-
# Linux kernel itself is optimizing the ioctl out as unnecessary? If
77-
# so, it's odd that it only happens with telnet, since ssh also
78-
# allocates a pty and uses an ioctl.
79-
80-
# Future research: What would it take to get the Linux Kernel to
75+
# into a WINCH signal. This is because the telnet protocol does not
76+
# include the size of the window in pixels, so telnetd just uses a
77+
# fake number when it calls the TIOCSWINSZ ioctl. Since the fake
78+
# number is always the same, the Linux kernel thinks the terminal has
79+
# not actually changed size and ignores the ioctl.
80+
#
81+
# Note that the ssh protocol handles this correctly and sends both
82+
# rows/columns and the pixel size.
83+
#
84+
# Future research: What would it take to get the telnet protocol to
8185
# support pixels for the window size as is mentioned in ioctl_tty(2):
8286

83-
# Get and set window size
84-
# Window sizes are kept in the kernel, but not used by the kernel (except
85-
# in the case of virtual consoles, where the kernel will update the win‐
86-
# dow size when the size of the virtual console changes, for example, by
87-
# loading a new font).
87+
# Get and set window size
88+
89+
# Window sizes are kept in the kernel, but not used by the kernel (except
90+
# in the case of virtual consoles, where the kernel will update the win‐
91+
# dow size when the size of the virtual console changes, for example, by
92+
# loading a new font).
8893

89-
# The following constants and structure are defined in <sys/ioctl.h>.
94+
# The following constants and structure are defined in <sys/ioctl.h>.
9095

91-
# TIOCGWINSZ struct winsize *argp
92-
# Get window size.
96+
# TIOCGWINSZ struct winsize *argp
97+
# Get window size.
9398

94-
# TIOCSWINSZ const struct winsize *argp
95-
# Set window size.
99+
# TIOCSWINSZ const struct winsize *argp
100+
# Set window size.
96101

97-
# The struct used by these ioctls is defined as
102+
# The struct used by these ioctls is defined as
98103

99-
# struct winsize {
100-
# unsigned short ws_row;
101-
# unsigned short ws_col;
102-
# unsigned short ws_xpixel; /* unused */
103-
# unsigned short ws_ypixel; /* unused */
104-
# };
104+
# struct winsize {
105+
# unsigned short ws_row;
106+
# unsigned short ws_col;
107+
# unsigned short ws_xpixel; /* unused */
108+
# unsigned short ws_ypixel; /* unused */
109+
# };
105110

106-
# When the window size changes, a SIGWINCH signal is sent to the fore‐
107-
# ground process group.
111+
# When the window size changes, a SIGWINCH signal is sent to the fore‐
112+
# ground process group.
108113

114+
# Telnet already has NAWS (Negotiate About Window Size) which sends
115+
# the rows and columns. Ideally, we'd just tack on the extra pixel
116+
# size to NAWS, and telnet daemons that can handle it would use the
117+
# data and ones that cannot would (hopefully) ignore it.
118+
#
119+
# However, I suspect that will not be possible and it may be necessary
120+
# to create a completely new option "GNAWS: Graphical Negotiate About
121+
# Window Size" that would supercede NAWS.
122+
#
123+
# Whatever the solution is, it would need to send rows and columns and
124+
# pixel size simultaneously so that the TIOCSWINSZ ioctl only gets
125+
# called once.

0 commit comments

Comments
 (0)