2016-02-29
终端标识
在大多数unix系统中,控制终端的名字是/dev/tty
char *ctermid(char *ptr)
此函数可以用来决定控制台的名字
如果ptr是非空,则它被认为是一个指针,指向至少长度为L_ctermid字节的数组,进程的控制终端的名字存放在此数组中,若ptr是一个空指针,则该函数为数组分配空间,同样,进程的控制终端名存放在该数组中。
在这两种情况中,该数组的起始地址被作为函数的返回值。
int isatty(int filedes) 若为终端设备返回1否则返回0
char *ttyname(int filedes) 返回指向终端路径名的指针
ttyname函数需要搜索所有设备表项,寻找匹配项。其方法是读/dev目录,寻找具有相同设备号和i节点标号的的表项。
规范方式
规范方式很简单,发一个度请求,当一行已经输入后,终端驱动程序即返回。许多条件造成读返回。
- 所要求的字节数已读取到时即返回。无需读一个完成的行。如果读取了部分行,那么也不丢失任何信息,下一次读从前一次读的停止处开始。
- 当读到一个行界定符时,读返回。eg : NL、EOL、EOL2、EOF如果已经设置ICRNL但未设置IGNCR则CR字符的作用与NL字符一样,所以它也终止一行。在这五个行界定符中,其中只有一个EOF符在终端驱动程序对其进行处理后即被删除。其他四个字符则作为该行的最后一个字符返回调用者。
- 如果捕捉到信号而且该函数并不自动再启动,则读也停止。
调用完getpass函数的程序完成以后,为了安全起见,应清除存放过用户键入的文本口令的存储区。如果该程序会产生其他用户能读的core文件,或者如果某个其他进程能够设法读该进程的存储空间,则就能读到他的口令。
非规范方式
将termios结构中c_flag字段的ICANON标志关闭就使终端处于非规范方式。在非规范方式中,输入数据不装配成行,不处理以下特殊字符 ERASE KILL EOF NL EOL2 CR REPRINT STATUS WERASE
其读取策略是当已读了指定量的数据后,或者已经过了给定的时间后,即通知系统返回。这种技术使用了termios结构中c_cc数组的两个变量 MIN TIME。c_cc数组这两个元素的下标名为VMIN和VTIME
MIN说明一个read返回前的最小字节数。TIME说明等待数据到达的分秒数。
- MIN>0 TIME>0 TIME说明一个字节间的计时器,在接到第一个字节时它才启动。在改计时器超时前若已接到MIN个字节,则read返回MIN个字节。如果在接到MIN个字节之前,改计时器已经超时,则read返回已经接收到的字节。在这种情形下在接到第一个字节之前,调用者阻塞。如果在调用read时数据已经可用,则如同在read后,数据立即被接收一样。
- MIN>0 TIME==0 已经接到了MIN个字节时才返回。这可以造成read无限期阻塞。
- MIN==0 TIME==0 如果有数据可用,则read最多返回所要求的字节数。如果无数据可用,则read立即返回0
在所有这些情形中,MIN只是最小值,如果程序要求的数据多于MIN个字节,那么他可能接收到所需要的字节数。
终端窗口大小
程序可以对当前终端窗口大小进行跟踪,在窗口大小发生变化时,使内核通知前台进程组。内核为每个终端和伪终端保存一个winsize 结构
struct winsize {
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpicel;
unsigned short ws_ypixel;
}
此结构作用是
用ioctl的TIOCGEINSZ命令可以取西结构的当前值
用ioctl的TIOCSWINSZ命令可以将此结构的新值存放到内核中。如果此值与存放在内核中的当前值不同,则向前台进程组发送SIGWINCH信号
除了存放此结构的当前值以及在此值改变时产生一个信号以外,内核对该结构不进行其他操作。对结构中的值进行解释完全是应用程序的工作。
提供这种功能的目的是,当窗口大小发生变化时通知应用程序。应用程序接收到此信号后,可以取得窗口的大小的新值,然后重绘屏幕。
termcap terminfo 和 curses
termcap的意思是终端性能,它涉及到文本文件/etc/termcap和一套读此文件的例程。termcap的这种技术是在伯克利为了支持Vi编辑器而发展起来的。termcap文件包含了对各种终端的说明:终端支持哪些功能,如何使终端执行某些操作。把这些信息从需要编译的程序中取出来并把它们放在易于编辑的文本文件中,这样就使得Vi能在很多不同的终端上运行。
然后支持termcap文件的一套例程也从Vi编辑器中抽取出来,放在一个单独的curses库中,为使这套库可被要进行屏幕处理的任何程序使用,增加了很多功能。
termcap这种技术不是很完善。当越来越多的终端被加到该数据文件时,为了找到一个特定终端就需要使用较长时间扫描此文件。此数据文件也只用两个字符的名字来标识不同的终端属性。这些缺陷导致开发另一种新技术--terminfo及其相关的curses库。在terminfo中,终端说明基本上是文本说明的变异版本,在运行时易于快速定位。
不论是termcap还是terminfo都致力于本章所述及的问题:更改终端的方式、更改终端的特殊字符、处理窗口大小等等。他们所提供的是在各种终端上执行典型操作的方法。另一方面,在本章所述问题方面curses能提供更详细的帮助。 curses提供了很多函数,包括:设置原始方式、设置cbreak方式、打开和关闭回送等等。当时curses是为字符终端设计的,而当前的趋势是向以像素为基础的图形终端发展。