While researching this problem, in the comments I found someone mentioning ANSI escape codes to get the terminal size. Since I will be using ANSI escape sequences, I thought this would be a much more elegant way to get the terminal size than ioctl()
or getenv()
.
Here is a very good post about ioctl(), and this is the comment that piqued my interest:
Just stumbled upon this answer, and my jaw dropped when I realized that getenv("COLUMNS") works perfectly when running under watch(1). So now I have a set of fallbacks, all from the TIOCWINSZ ioctl, to getenv if not a tty, down to the classic ANSI escape "move cursor to 9999,9999 and the query cursor pos. The last one works on serial consoles for embedded systems :)
Now, I did find some posts (1, 2) about ANSI, but none answer the specific question I have - how to actually do it?
Using this chart, I deduced that in order to move the cursor to the extreme right and down position, I would need the CUP
(CSI n ; m H
) "Cursor Position" command, which would probably translate to something like \x1b[9999;9999H
. This is the easy part since it is a command.
The second part is where I have a big problem. Even if I could deduce that I need the DSR
(CSI 6n
) "Device Status Report" command, and that it goes \x1b[6n
, how does this querying work, i.e., how can I take the data and store it in a variable, preferrably without disrupting the other data that is being displayed on the terminal?