APUE - 终端 I/O
综述
终端 I/O 有两种不同的工作模式:
- 规范模式输入处理。在这种模式中,终端输入以行为单位进行处理。对于每个读要求,终端驱动程序最多返回一行。
- 非规范模式输入处理。输入字符并不组成行。
如果不作特殊处理,则默认模式是规范模式。
所有我们可以检测和更改的终端设备特性都包含在 termios 结构中。该结构定义在头文件
struct termios {
tcflag_t c_iflag; /* input flags */
tcflag_t c_oflag; /* output flags */
tcflag_t c_cflag; /* control flags */
tcflag_t c_lflag; /* local flags */
cc_t c_cc[NCCS]; /* control characters */
};
获得和设置终端属性
使用函数 tcgetattr 和 tcsetattr 可以获得或设置 termios 结构。这样也就可以检测和修改各种终端选择标志和特殊字符,以使终端按我们所希望的方式进行操作。
#include <termios.h>
int tcgetattr(int filedes, struct termios *termptr);
int tcsetattr(int filedes, int opt, const struct termios *termptr);
波特率函数
波特率是一个以往采用的术语,现在它指的是“位/秒”。虽然大多数终端设备对输入和输出使用同一波特率,但是只要硬件许可,可以将它们设置为两个不同值。
#include <termios.h>
speed_t cfgetispeed(const struct termios *termptr);
speed_t cfgetospeed(const struct termios *termptr);
int cfsetispeed(struct termios *termptr, speed_t speed);
int cfsetospeed(struct termios *termptr, speed_t speed);
行控制函数
下列 4 个函数提供了终端设备的行控制能力。
#include <termios.h>
int tcdrain(int filedes);
int tcflow(int filedes, int action);
int tcflush(int filedes, int queue);
int tcsendbreak(int filedes, int duration);
终端标识
在大多数 UNIX 系统中,控制终端的名字是 /dev/tty。POSIX.1 提供了一个运行时函数,可被用来确定控制终端的名字。
#include <stdio.h>
char *ctermid(char *ptr);
另外两个与终端标识有关的函数是 isatty 和 ttyname。前者在文件描述符引用一个终端设备时返回真,而后者返回在文件描述符上打开的终端设备的路径名。
#include <unistd.h>
int isatty(int filedes);
char *ttyname(int filedes);
终端的窗口大小
大多数 UNIX 系统都提供了一种功能,可以对当前终端窗口的大小进行跟踪,在窗口大小发生变化时,使内核通知前台进程组。内核为每个终端和伪终端保存一个 winsize 结构:
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) */
};