Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Everytime someone set a different size for a virtual console, less recognize window-resolution (I'm assuming that ...); according to that it changes how many lines of text it should visualize. How that parameter is computed?

share|improve this question
    
Uhm ...ok, yet where I can find that procedure that's executed? –  giuscri Oct 1 '13 at 14:28
add comment

3 Answers

up vote 15 down vote accepted

If you're looking for a way to check from a script, you can do either of these:

  • Run tput cols and tput lines, as manatwork suggests
  • check the values of $LINES and $COLUMNS

But if you want the details, here we go:

For virtual terminals (xterm, et al) there is an ioctl() system call that will tell you what size the window is. If it can, less uses this call. Furthermore, when you change the size of the window, whatever's running in that window receives a SIGWINCH signal that lets less know that it should check for a new window size. For instance, I started a less running (as process ID 16663), connected to it with strace, and resized the window. This is what I saw:

$ strace -p 16663
Process 16663 attached - interrupt to quit
read(3, 0xbfb1f10f, 1)                  = ? ERESTARTSYS (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
rt_sigaction(SIGWINCH, {0x805cf10, [WINCH], SA_RESTART}, {0x805cf10, [WINCH], SA_RESTART}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(2, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0

This is also what tput cols and tput lines do behind the scenes, if they can. For more info on this method, see man tty-ioctl and search for TIOCGWINSZ.

For other terminals such as those connected to serial ports, though, there's no way to get this info directly. In that case, less starts looking for clues in the environment variables.

  • LINES and COLUMNS will often be set to the terminal dimensions. In fact, if bash or zsh can find the terminal dimensions, it will automatically set these variables itself, to make it easy for not-so-clever programs to see the terminal size. However, most other shells, including dash and tcsh, do not set these variables.
  • TERM is usually set to the terminal type, in which case the terminfo database may contain instructions for asking the terminal its size over the serial connection. For more info, see man tput for the command to control the terminal, and man terminfo for a list of things you can tell the terminal to do.
share|improve this answer
1  
$LINES and $COLUMNS were both undefined in tcsh, my shell of choice; though tput cols|lines worked just fine. The variables worked in bash and zsh, though. Caveat scriptor. –  Garrett Albright Oct 1 '13 at 22:37
2  
@Garrett - there are many reasons not to use [t]csh, that's just one of the minor/trivial reasons. –  cas Oct 2 '13 at 1:57
1  
@GarrettAlbright and @Craig-sanders : indeed, read www-uxsup.csx.cam.ac.uk/misc/csh.html (the infamous "Csh programming considered harmful"), which have eye-opening scary examples, and especially its last sentence: While some vendors have fixed some of the csh's bugs (the tcsh also does much better here), most of its problems can never be solved because they're a result of braindead design decisions. Do yourself a favor, and if you have to write a shell script, do it in the Bourne shell. Add to that the fact: system scripts should be sh-compatible (not [t]csh/bash/ksh/...-compatible)! –  Olivier Dulac Oct 2 '13 at 15:22
    
Yeah, your shell is l33t4r than my shell. Got it. Think I'll suffer the unhipness and stick with tcsh until if/when others become worth the friction of relearning stuff and porting my .tcshrc. In the meantime, it helps if everyone remembers that shells don't start and end with bash. –  Garrett Albright Oct 2 '13 at 22:05
    
@GarrettAlbright No, really, [t]csh sucks. We're your friends and we care about you. This is an intervention. –  ntc2 Nov 15 '13 at 1:28
show 1 more comment

If you take a look at the source code, you will know less calls ioctl() to retrieve the window size on Linux.

#ifdef TIOCGWINSZ
    {
        struct winsize w;
        if (ioctl(2, TIOCGWINSZ, &w) == 0)
        {
            if (w.ws_row > 0)
                sys_height = w.ws_row;
            if (w.ws_col > 0)
                sys_width = w.ws_col;
        }
    }
#else
#ifdef WIOCGETD
    {
        struct uwdata w;
        if (ioctl(2, WIOCGETD, &w) == 0)
        {
            if (w.uw_height > 0)
                sys_height = w.uw_height / w.uw_vs;
            if (w.uw_width > 0)
                sys_width = w.uw_width / w.uw_hs;
        }
    }
#endif
share|improve this answer
add comment

I am not sure if this is the information that you are looking for. I guess less registers a signal handler for SIGWINCH. When the dimension of terminal changes, it gets a SIGWINCH signal and probe the tty information for current dimension of the terminal. http://www.gnu.org/software/libc/manual/html_node/Miscellaneous-Signals.html

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.