Unix环境编程-终端

1.什么是Linux的终端I/O,它分为几种类型。

       终端是一种字符型设备,有多种类型,通常使用tty来简称各种类型的终端设备。终端特殊设备文件一般有以下几种: 串行端口终端(/dev/ttySn ,伪终端(/dev/pty/),控制终端(/dev/tty ,控制台终端(/dev/ttyn, /dev/console).

1. 串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev/ttyS1)等,设备号分别是(4,0)、(4,1)等,分别对应于DOS系统下的COM1COM2等。

2. 伪终端(Pseudo Terminal)是成对的逻辑终端设备,例如/dev/ptyp3/dev/ttyp3(在设备文件系统中分别是/dev/pty/m3/dev/pty/s3,它们与实际物理设备并不直接相关。对于ttyp3s3),任何设计成使用一个串行端口设备的程序都可以使用该逻辑设备。但对于使用ptyp3的程序,则需要专门设计来使用ptyp3m3)逻辑设备。 如果使用telnet远程登录,则telnet会开始连接到设备ptyp2m2)上(一个伪终端端口上)。此时一个getty程序就应该运行在对应的ttyp2s2)端口上。当telnet从远端获取了一个字符时,该字符就会通过m2s2传递给getty程序,而getty程序就会通过s2m2telnet程序往网络上返回”login:”字符串信息。登录程序与telnet程序就通过“伪终端”进行通信,通过使用适当的软件,就可以把两个甚至多个伪终端设备连接到同一个物理串行端口上。因为只存在16ttypttyp0ttypf)的设备文件,就使用了象qrs等字符来代替p。例如,ttys8ptys8就是一个伪终端设备对。目录/dev/pts是一个类型为devpts的文件系统,并且可以在被加载文件系统列表中看到。虽然/dev/pts象是设备文件系统中的一项,但它其实是一种不同的文件系统。

3. 如果当前进程有控制终端(Controlling Terminal)的话,那么/dev/tty就是当前进程的控制终端的设备特殊文件。可以使用命令”ps ax”来查看进程与哪个控制终端相连使用命令”tty”可以查看它具体对应哪个实际终端设备。/dev/tty有些类似于到实际所使用终端设备的一个联接。

4.  Linux系统中,计算机显示器通常被称为控制台终端(Console,它仿真了类型为Linux的一种终端(TERM=Linux),并且有一些设备特殊文件与之相关联:tty0tty1tty2等。当你在控制台上登录时,使用的是tty1。使用Alt+[F1F6]组合键时,我们就可以切换到tty2tty3等上面去。tty1 tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,系统所产生的信息会发送到该终端上。只有系统或超级用户root可以向/dev/tty0进行写操作 .

 

2.终端I/O有两种不同的工作方式:

(1) 规范方式输入处理。在这种方式中,终端输入以行为单位进行处理。对于每个读要求驱动程序最多返回一行。

(2) 非规范放式输入处理。输入字符不以行为单位进行装配。

 

 

3.终端标志

Unix/Linux终端设备特性都包含在termios结构中。该结构在头文件<termios.h>中定义。

struct termios{

       tcflag_t c_iflag; /*输入标志*/

       tcflag_t c_oflag;/*输出标志*/

       tcflag_t c_cflag;/*控制标志*/

       tcfag_t c_lflag;/*本地标志*/

       cc_t c_cc[NCCS];/*控制字符*/

};

 

下面对他们分别进行介绍。

字段

标志

说明

c_iflag

BRKINT

接到BREAK时产生SIGINT

 

ICRNL

将输入的CR转换为NL

 

IGNBRK

忽略BREAK条件

 

IGNCR

忽略CR

 

IGNPAR

忽略奇偶错字符

 

IMAXBEL

在输入队列空时振铃

 

INLCR

将输入的NL转换为CR

 

INPCK

打开输入奇偶效验

 

ISTRIP

剥除输入字符的第8

 

IUCLC

将输入的大写字符转换成小写字符

 

IXANY

使任一字符都重起动动输出

 

IXOFF

使起动/停止输入控制流起作用

 

IXON

使起动/停止输出控制流起作用

 

PARMRK

标记奇偶错

 

c_oflag

BSDLY

退格延迟屏蔽

 

CRDLY

CR延迟屏蔽

 

FFDLY

换页延迟屏蔽

 

NLDLY

NL延迟屏蔽

 

OCRNL

将输出的CR转换为NL

 

OFDEL

填充符为DEL,否则为NUL

 

OFILL

对于延迟使用填充符

 

OLCUC

将输出的小写字符转换为大写字符

 

ONLCR

NL转换为CR-NL

 

ONLRET

NL执行CR功能

 

ONOCR

0列不输出CR

 

ONOEOT

在输出中删除EOT字符

 

OPOST

执行输出处理

 

OXTABS

将制表符扩充为表格

 

TABDLY

水平制表符延迟屏蔽

 

VTDLY

垂直制表延迟屏蔽

字段

标志

说明

c_cflag

CCTS_OFLOW

输出的CTS流控制

 

CIGNORE

忽略控制标志

 

CLOAL

忽略调制解调器状态行

 

CREAD

启用接收装置

 

CRTS_IFLOW

输入的RTS流控制

 

CSIZE

字符大小屏蔽

 

CSTOPB

送两个停止位,否则为1

 

HUPCL

最后关闭时断开

 

MDMBUF

经载波的控制输出

 

PARENB

进行奇偶校

 

PARODD

奇校,否则为偶校

 

c_lflag

ALTWERASE

使用替换WERASW算法

 

ECHO

进行回送

 

ECHOCTL

回送控制字符为^char

 

ECHOE

可见符擦除符

 

ECHOK

回送kill

 

ECHOKE

kill的可见擦除

 

ECHONL

回送NL

 

ECHOPRT

硬拷贝的可见擦除方式

 

FLUSHO

刷清输出

 

ICANON

规范输出

 

IEXTEN

使扩充的输入字符处理起作用

 

ISIG

使终端产生的信号起作用

 

NOFLSH

在中断或退出键后不刷清

 

NOKERNINFO

STATUS不使内核输出

 

PENDIN

重新打印

 

TOSTOP

对于后台输出发送SIGTTOU

 

XCASH

规范大/小写表示

 

4.终端选择标志

       所有列出的选择标志都用一或多位表示,而屏蔽标志则定义多位。屏蔽标志有一个定义名,每个值也有一个名字。例如,为了设置字符长度,首先用字符长度屏蔽标志CSIZE将表示字符长度的位清0,然后设置下列值之一:CS5CS6CS7CS8。具体语法看程序11_1.c

 

5.特殊字符

 

 
 

六.终端I/O函数

tcgetattr                       取属性(termios结构)

tcsetattr                        设置属性(termios结构)

cfgetispeed                   得到输入速度

cfgetospeed                  得到输出速度

cfsetispeed                   设置输入速度

cfsetospeed                  设置输出速度

tcdrain                         等待所有输出都被传输

tcflow                          挂起传输或接收

tcflush                         刷清未决输入和输出

tcsendbread                  BREAK字符

tcgetpgrp                      得到前台进程id

tcsetpgrp                      设置前台进程id

 

1

名称:

tcgetattr/tcsetattr

功能:

获得和设置终端属性

头文件:

#include <termios.h>

函数原形:

int tcgetattr(int filedes,struct termios *termptr);

int tcsetattr(int filedes,int opt,const struct termios *termptr);

参数:

filedes     终端I/O所对应的文件的文件描述符

termptr    终端属性

opt        作用时间

返回值:

若成功返回0,若出错则返回-1

      

 

 

 

 

 

 

 

 

 

使用这两个函数可以获得或设置termios。这样也就可以检测和修改各种终端选择标志和特殊字符,以使终端按我们所希望的方式进行操作。

       这两个函数都有一个指向termios结构的指针作为其参数,它们返回当前终端的属性,或者设置该终端的属性。因为这两函数只对终端进行操作,所以若filedes并不引用一个终端设备则出错返回,errno设置为ENOTTY.

       tcsetattr的参数opt使我们可以指定在什么时候新的终端属性才起作用,opt可以指定下列属性中的一个。

TCSANOW           更改立即发生

TCSADRAIN         发送了所有输出后更改才发生

TCSAFLUSH         发送了所有输出后更改才发生,更进一步,在更改发生时未读的所有输入数据都被清空。

       tcsetattr函数的返回值易于产生混淆。如果它执行了任意一种所要求的动作,即使未能执行所有要求的动作,它也返回0(表示成功)。如果该函数返回0,则我们有责任检查该函数是否执行了所有要求的动作。这就意味着,在调用tcsetattr设置所希望的属性后,需调用tcgetattr,然后将实际终端属性与所希望的属性相比较,以检测两者是否有区别。

 

/*11_1.c*/

#include <stdio.h>

#include <stdlib.h>

#include <termios.h>

#inlcude <unistd.h>

 

int main()

{

struct termios term; /*定义终端属性*/

int size;

 

if(tcgetattr(STDIN_FILENO,&term)<0) /* STDIN_FILENO 就对应于标准输入. 实际上是文件描述符1 */

    printf(“tcgerattr error”);

 

size=term.c_cflag&CSIZE; /*字符大小*/

if(size==CS5)

    printf(“5 bits/byte\n”);

else if(size==CS6)

    printf(“6 bits/byte\n”);

else if(size==CS7)

    printf(“7 bits/byte\n”);

else if(size==CS8)

    printf(“8 bits/byte\n”);

else

    printf(“unknown bits/byte\n”);

 

term.c_cflag &=~CSIZE; /*把字符长度位清0*/

term.c_cflag | =CS6; /*设置6bits/byte的长度位*/

 

if(tcsetattr(STDIN_FILENO,TCSANOW,&term)<0)

    printf(“tcsetattr error\n”);

exit(0);

}

       程序运行后在屏幕上输出:8 bits/byte(你的系统有可能不是这个数),当程序再次运行时会打印 8 bits/byte。这就是我们用屏蔽标志设置的一个值。

 

 

posted @ 2009-06-18 16:46  辛勤耕耘  阅读(520)  评论(0)    收藏  举报