I am working on embedded system using C
and linux
. User can connect to the device via SSH or a console serial cable. He can do this through PuTTY or Tera Term. My question is, after he is connected, how can I know his window's width? I have tried different approaches, they work if I simulate my system on a linux pc, but none of them work on the device:
ioctl()
struct winsize ws;
ioctl(..., TIOCGWINSZ, &ws);
This method works on pc, but it always returns 0 on the device.
tgetnum()
setupterm((char *)0, 1, (int *)0);
CGR_INT columns = tgetnum("co");
This method works on pc, but it always returns 80x24 on the device.
getmaxyx()
CGR_INT xdim;
CGR_INT ydim;
initscr();
refresh();
getmaxyx(stdscr, ydim, xdim);
This method works on pc, but it always returns 0 on the device
TIOCGWINSZ is the way to go. Your device in question has to announce its size, otherwise this just can't work. Take xterm as an example:
device —— ttyS driver —— ttyS0 devnode —— screen/minicom
xterm —— pty devnode —— pty driver —— pts devnode —— bash
xterm does ioctl(TIOCSWINSZ) the first time it is spawned to let the tty driver know the window size. bash and programs spawned from it can then inquire it. If you resize the xterm window, it will tell the tty driver the new size, and xterm also emits SIGWINCH to its child process (bash in this case) to notify it of the size change.
None of this happens with devices (such as yours) that have no idea what they are connected to in the first place. Neither does the tty driver know what is connected to it. (Nor does it usually care.) xterm can tell the driver the size, because it can issue an ioctl, but ioctls are not transported via serial for example. What it would in theory take is a specialized kernel driver that knows how to communicate size changes with your particular device (perhaps a protocol on top of serial so that no rewrite of a core component is needed).
Note that the connected device may not even have a concept of a fixed region—e.g. a printer could be considered to have practically infinitely many lines.
ncurses just assumes 80x24 if it sees 0x0, because the programmer defined it that way. That size may not be correct, and in practice usually is not because people can resize their windows (even if they can't, like on tty1, they can still use stuff like screen(1) and shrink the size to something less than 80x24).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With