- 浏览: 140226 次
文章分类
最新评论
多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的方法。在窗口大小发生变化时,内核就会通知前台进程组。内核为每个终端和伪终端都维护了一个如下的 winsize 结构。
此结构的规则如下:
1、用 ioctl 函数(见终端I/O函数 ioctl一节)的 TIOCGWINSZ 命令可以取此结构的当前值。
2、用 ioctl 的 TIOCSWINSZ 命令可以将此结构的新值存储到内核中。如果此新值与存储在内核中的当前值不同,则将向前台进程组发送 SIGWINCH 信号(默认会被忽略)。
3、除了存储此结构的当前值以及在此值改变时产生一个信号以外,内核对该结构不进行任何其他操作。对结构中的值进行解释是应用程序的工作。
提供这种功能的目的是,当窗口大小发生变化时应用程序能得到通知(如 vi 编辑器)。应用程序接收到此信号后,可以获取窗口大小的新值,然后重绘屏幕。
下面这个程序会打印当前窗口大小,然后休眠。之后每次窗口大小改变时,程序就捕捉 SIGWINCH 信号,然后打印新的窗口大小。
termcap 的意思是终端能力(terminal capability),它涉及文本文件 /etc/termcap 和一套读此文件的例程,主要是为了支持 vi 编辑器而开发的。termcap 文件包含了对各种终端的说明:终端支持哪些功能(如行数、列数、是否支持退格)、如何使终端执行某些操作(如清屏、移动光标到指定位置)等。把这些信息从编译过的程序中取出来并把它们放在易于编辑的文本文件中,这样就使得 vi 编辑器能在很多不同的终端上运行。最后,将支持 termcap 文件的例程从 vi 编辑器中抽取出来,放在一个单独的 curses 库中。为使这套库可供要进行屏幕处理的任何程序使用,还增加了很多功能。
不过 termcap 这种技术并不是很完善。因为当越来越多的终端被加到数据文件中时,为找到一个特定的终端,可能需要花费很长的时间扫描此数据文件。另外,该数据文件还用两个字符的名字来标识不同的终端属性。因此出现了 terminfo 以及与其相关的 curses 库。在 terminfo 中,终端说明基本上都是文本说明的编译版本,在运行时易于被快速定位。
但不论是 termcap 还是 terminfo,它们本身都只提供在各种终端上执行典型操作(如清屏、移动光标等)的方法,而不处理如更改终端模式、更改终端特殊字符、处理窗口大小等问题。不过 curses 库能提供某种具体细节方面的帮助。它提供了很多函数,用来设置原始模式、设置 cbreak 模式、打开和关闭回显等。注意,curses 库是为基于字符的哑终端设计的,它们如今大部分已被基于像素的图像终端所代替。
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) };
此结构的规则如下:
1、用 ioctl 函数(见终端I/O函数 ioctl一节)的 TIOCGWINSZ 命令可以取此结构的当前值。
2、用 ioctl 的 TIOCSWINSZ 命令可以将此结构的新值存储到内核中。如果此新值与存储在内核中的当前值不同,则将向前台进程组发送 SIGWINCH 信号(默认会被忽略)。
3、除了存储此结构的当前值以及在此值改变时产生一个信号以外,内核对该结构不进行任何其他操作。对结构中的值进行解释是应用程序的工作。
提供这种功能的目的是,当窗口大小发生变化时应用程序能得到通知(如 vi 编辑器)。应用程序接收到此信号后,可以获取窗口大小的新值,然后重绘屏幕。
下面这个程序会打印当前窗口大小,然后休眠。之后每次窗口大小改变时,程序就捕捉 SIGWINCH 信号,然后打印新的窗口大小。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #ifndef TIOCGWINSZ #include <sys/ioctl.h> #endif static void pr_winsize(int fd){ struct winsize size; if(ioctl(fd, TIOCGWINSZ, (char *)&size) < 0){ printf("TIOCGWINSZ error\n"); exit(1); } 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){ printf("signal error\n"); exit(1); } pr_winsize(STDIN_FILENO); // print initial size for(;;) // and sleep forever pause(); }
termcap 的意思是终端能力(terminal capability),它涉及文本文件 /etc/termcap 和一套读此文件的例程,主要是为了支持 vi 编辑器而开发的。termcap 文件包含了对各种终端的说明:终端支持哪些功能(如行数、列数、是否支持退格)、如何使终端执行某些操作(如清屏、移动光标到指定位置)等。把这些信息从编译过的程序中取出来并把它们放在易于编辑的文本文件中,这样就使得 vi 编辑器能在很多不同的终端上运行。最后,将支持 termcap 文件的例程从 vi 编辑器中抽取出来,放在一个单独的 curses 库中。为使这套库可供要进行屏幕处理的任何程序使用,还增加了很多功能。
不过 termcap 这种技术并不是很完善。因为当越来越多的终端被加到数据文件中时,为找到一个特定的终端,可能需要花费很长的时间扫描此数据文件。另外,该数据文件还用两个字符的名字来标识不同的终端属性。因此出现了 terminfo 以及与其相关的 curses 库。在 terminfo 中,终端说明基本上都是文本说明的编译版本,在运行时易于被快速定位。
但不论是 termcap 还是 terminfo,它们本身都只提供在各种终端上执行典型操作(如清屏、移动光标等)的方法,而不处理如更改终端模式、更改终端特殊字符、处理窗口大小等问题。不过 curses 库能提供某种具体细节方面的帮助。它提供了很多函数,用来设置原始模式、设置 cbreak 模式、打开和关闭回显等。注意,curses 库是为基于字符的哑终端设计的,它们如今大部分已被基于像素的图像终端所代替。
发表评论
-
打开伪终端设备
2018-07-09 20:50 1246在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1527伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端规范模式和非规范模式
2018-05-29 00:25 935终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
终端标识
2018-05-23 11:18 563尽管控制终端的名字在多数 UNIX 系统上都是 /de ... -
波特率和行控制函数
2018-05-22 07:53 933虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 706tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 806终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 430终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 574在XSI IPC通信之信 ... -
XSI IPC 通信之共享存储
2018-04-25 07:18 942在XSI IPC通信之消息队列和XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 612在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 488消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 477有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 409FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 380管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 875readv 和 writev 函数可用于在一次函数调用 ... -
POSIX 异步 I/O
2018-01-16 21:33 448POSIX 异步 I/O 接口为对不同类型的文件进行异 ... -
fcntl 记录锁
2018-01-06 23:48 570记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 431UNIX 系统中,守护进程遵循下列通用惯例。 ... -
守护进程编写规则与出错记录
2017-12-26 01:53 449在编写守护进程程 ...
相关推荐
通过`mvwin()`可以移动窗口,`resize_win()`调整大小,`subwin()`和`derwin()`创建子窗口。`wnoutrefresh()`和`wrefresh()`用于更新窗口到屏幕。 【视窗卷动】`wmove()`移动窗口内的光标,`wscroll()`用于滚动窗口...
`subwin()` 和 `derwin()` 用于从已有窗口创建子窗口,`mvwin()` 可以改变窗口的位置,`resize_term()` 和 `resize_window()` 用于调整终端或窗口的大小。 3. **颜色管理**:Curses 提供了颜色支持,`init_pair()` ...
18.12 终端的窗口大小 18.13 termcap,terminfo和curses 18.14 小结 习题 第19章 伪终端 19.1 引言 19.2 概述 19.3 打开伪终端设备 19.3.1 基于STREAMS的伪终端 19.3.2 基于BSD的伪终端...
11.12 终端的窗口大小 11.13 termcap, terminfo和 curses 11.14 小结 习题 第12章 高级I/O 12.1 引言 12.2 非阻塞I/O 12.3 记录锁 12.3.1 历史 12.3.2 fcntl记录锁 12.3.3 锁的隐含继承和释放 12.3.4 4.3+BSD的实现...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 11.13 termcap, terminfo和 curses 11.14 小结 习题 第12章 高级I/O 12.1 引言 12.2 非阻塞I/O 12.3 记录锁 12.3.1 历史 12.3.2 fcntl记录锁 12.3.3 锁的隐含继承和释放 12.3.4 4.3+BSD的实现...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.4 流 288 12.5 I/O多路转接 296 12.6 异步I/O ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...
11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...