Section 18.12. Terminal Window Size

team bbl


18.12. Terminal Window Size

Most UNIX systems provide a way to keep track of the current terminal window size and to have the kernel notify the foreground process group when the size changes. The kernel maintains a winsize structure for every terminal and pseudo terminal:

    struct winsize {      unsigned short ws_row;       /* rows, in characters */      unsigned short ws_col;       /* columns, in characters */      unsigned short ws_xpixel;    /* horizontal size, pixels (unused) */      unsigned short ws_ypixel;    /* vertical size, pixels (unused) */    }; 

The rules for this structure are as follows.

  • We can fetch the current value of this structure using an ioctl (Section 3.15) of TIOCGWINSZ.

  • We can store a new value of this structure in the kernel using an ioctl of TIOCSWINSZ. If this new value differs from the current value stored in the kernel, a SIGWINCH signal is sent to the foreground process group. (Note from Figure 10.1 that the default action for this signal is to be ignored.)

  • Other than storing the current value of the structure and generating a signal when the value changes, the kernel does nothing else with this structure. Interpreting the structure is entirely up to the application.

The reason for providing this feature is to notify applications (such as the vi editor) when the window size changes. When it receives the signal, the application can fetch the new size and redraw the screen.

Example

Figure 18.22 shows a program that prints the current window size and goes to sleep. Each time the window size changes, SIGWINCH is caught and the new size is printed. We have to terminate this program with a signal.

Running the program in Figure 18.22 on a windowed terminal gives us

 $ ./a.out 35 rows, 80 columns       initial size SIGWINCH received         change window size: signal is caught 40 rows, 123 columns SIGWINCH received         and again 42 rows, 33 columns ^? $                      type the interrupt key to terminate 

Figure 18.22. Print window size
 #include "apue.h" #include <termios.h> #ifndef TIOCGWINSZ #include <sys/ioctl.h> #endif static void pr_winsize(int fd) {     struct winsize size;     if (ioctl(fd, TIOCGWINSZ, (char *) &size) < 0)         err_sys("TIOCGWINSZ error");     printf("%d rows, %d columns\n", size.ws_row, size.ws_col); } static void sig_winch(int signo) {     printf("SIGWINCH received\n");     pr_winsize(STDIN_FILENO); } int main(void) {     if (isatty(STDIN_FILENO) == 0)         exit(1);     if (signal(SIGWINCH, sig_winch) == SIG_ERR)         err_sys("signal error");     pr_winsize(STDIN_FILENO);   /* print initial size */     for ( ; ; )                 /* and sleep forever */         pause(); } 

    team bbl



    Advanced Programming in the UNIX Environment
    Advanced Programming in the UNIX Environment, Second Edition (Addison-Wesley Professional Computing Series)
    ISBN: 0321525949
    EAN: 2147483647
    Year: 2005
    Pages: 370

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net