终端I/O之终端窗口的大小

大多数UNIX系统都提供了一种功能,可以对当前终端窗口的大小进行跟踪,在窗口大小发生变化时,使内核通知前台进程组。内核为每个终端和伪终端保存一个winsize结构:

Struct winsize {

    unsigned short    ws_row;    /* rows, in character */

    unsigned short ws_col;        /* columns, in characters */

    unsigned short ws_xpixel;    /* horizontal size, pixels (unused) */

    unsigned short ws_ypixel;    /* vertical size, pixels (unused) */

};

此结构的作用如下:

  1. 用ioctl函数的TIOCGWINSZ命令可以取此结构的当前值。
  2. 用ioctl函数的TIOCSWINSZ命令可以将此结构的新值存放到内核中。如果此新值与存放在内核中的当前值不同,则向前台进程组发送SIGWINCH信号。
  3. 除了存放此结构的当前值以及在此值改变时产生一个信号以外,内核对该结构不进行任何其他操作。对结构中的值进行解释完全是应用程序的工作。
  4. 提供这种功能的目的是,当窗口大小发生变化时通知应用程序(例如,vi编辑器)。应用程序接到此信号后,它可以取窗口大小的新值,然后重绘屏幕。

 

实例:打印当前窗口大小,然后休眠。每次窗口大小改变时,就捕捉到SIGWINCH信号,然后打印新的窗口大小。必须用一个信号终止此程序。

程序清单18-12 打印窗口大小

#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 ", size.ws_row, size.ws_col);

}

 

static void

sig_winch(int signo)

{

    printf("SIGWINCH received ");

    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();

}

原文地址:https://www.cnblogs.com/nufangrensheng/p/3577444.html