TERMIOS - Linux手册页

时间:2019-08-20 18:01:30  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-08-13

名称

termios,tcgetattr,tcsetattr,tcsendbreak,tcdrain,tcflush,tcflow,cfmakeraw,cfgetospeed,cfgetispeed,cfsetispeed,cfsetospeed,cfsetspeed-获取和设置终端属性,线路控制,获取和设置波特率

语法

#include <termios.h>
#include <unistd.h>

int tcgetattr(int fd, struct termios *termios_p);

int tcsetattr(int fd, int optional_actions,
              const struct termios *termios_p);

int tcsendbreak(int fd, int duration);

int tcdrain(int fd);

int tcflush(int fd, int queue_selector);

int tcflow(int fd, int action);

void cfmakeraw(struct termios *termios_p);

speed_t cfgetispeed(const struct termios *termios_p);

speed_t cfgetospeed(const struct termios *termios_p);

int cfsetispeed(struct termios *termios_p, speed_t speed);

int cfsetospeed(struct termios *termios_p, speed_t speed);

int cfsetspeed(struct termios *termios_p, speed_t speed);

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

cfsetspeed(),cfmakeraw():
从glibc 2.19开始:
_DEFAULT_SOURCE
Glibc 2.19及更早版本:
_BSD_SOURCE

说明

termios功能描述了提供的通用终端接口,用于控制异步通信端口。

The termios structure

这里描述的许多功能都有一个termios_p参数,该参数是指向termios结构的指针。此结构至少包含以下成员:

tcflag_t c_iflag;      /* input modes */
tcflag_t c_oflag;      /* output modes */
tcflag_t c_cflag;      /* control modes */
tcflag_t c_lflag;      /* local modes */
cc_t     c_cc[NCCS];   /* special characters */

下面介绍可以分配给这些字段的值。对于前四个位掩码字段,仅当定义了特定的功能测试宏(请参见feature_test_macros(7))时才公开可能设置的某些相关标志的定义,如方括号(" [ ]")。

在下面的描述中,"不在POSIX中"表示未在POSIX.1-2001中指定该值,而" XSI"意味着在POSIX.1-2001中指定了该值作为XSI扩展的一部分。

c_iflag标志常量:

IGNBRK
忽略输入的BREAK条件。
BRKINT
如果设置了IGNBRK,则会忽略BREAK。如果未设置,但设置了BRKINT,则BREAK会导致刷新输入和输出队列,并且如果该终端是前台进程组的控制终端,它将导致SIGINT发送到该前台进程组。如果既未设置IGNBRK也未设置BRKINT,则BREAK读取为空字节(aq \ 0aq),除非设置了PARMRK,在这种情况下,其读取为序列\ 377 \ 0 \ 0。
IGNPAR
忽略成帧错误和奇偶校验错误。
PARMRK
如果设置了此位,则在传递给程序时会标记具有奇偶校验或成帧错误的输入字节。仅当设置了INPCK且未设置IGNPAR时,该位才有意义。标记错误字节的方式是使用前面的两个字节\ 377和\ 0。因此,程序实际上从终端接收到一个错误字节的三个字节。如果有效字节的值为\ 377,并且未设置ISTRIP(请参见下文),则程序可能会将其与标记奇偶校验错误的前缀混淆。因此,在这种情况下,有效字节\ 377作为两个字节\ 377 \ 377传递给程序。
如果既未设置IGNPAR也未设置PARMRK,则读取具有奇偶校验错误或成帧错误的字符\ 0。
INPCK
启用输入奇偶校验。
ISTRIP
剥掉第八位。
INLCR
在输入上将NL转换为CR。
IGNCR
忽略输入的回车。
ICRNL
在输入中将回车转换为换行符(除非设置了IGNCR)​​。
IUCLC
(不适用于POSIX)在输入时将大写字符映射为小写。
IXON
在输出上启用XON / XOFF流控制。
IXANY
(XSI)键入任何字符将重新启动停止的输出。 (默认是仅允许使用START字符来重新开始输出。)
IXOFF
在输入上启用XON / XOFF流控制。
IMAXBEL
(不在POSIX中)当输入队列已满时响铃。 Linux不会实现此位,并且就像始终将其设置一样。
IUTF8(since Linux 2.6.4)
(不在POSIX中)输入为UTF8;这样可以在烹饪模式下正确执行字符擦除。

c_oflag标志常量:

OPOST
启用实现定义的输出处理。
OLCUC
(不适用于POSIX)在输出时将小写字符映射为大写。
ONLCR
(XSI)在输出上将NL映射到CR-NL。
OCRNL
在输出上将CR映射到NL。
ONOCR
不要在第0列输出CR。
ONLRET
不输出CR。
OFILL
发送填充字符有一个延迟,而不是使用定时延迟。
OFDEL
填充字符为ASCII DEL(0177)。如果未设置,则填充字符为ASCII NUL(aq \ 0aq)。 (未在Linux上实现。)
NLDLY
换行延迟掩码。值是NL0和NL1。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]
CRDLY
回车延误掩码。值为CR0CR1,CR2或CR3。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]
TABDLY
水平制表符延迟掩码。值是TAB0TAB1TAB2TAB3(或XTABS,但请参见" BUGS"部分)。 TAB3的值(即XTABS)将制表符扩展为空格(制表符每八列停止一次)。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]
BSDLY
退格延迟掩码。值为BS0或BS1。 (从未实现。)[需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]
VTDLY
垂直制表符延迟掩码。值为VT0或VT1。
FFDLY
进纸延迟掩码。值为FF0或FF1。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

c_cflag标志常量:

CBAUD
(不在POSIX中)波特率速度掩码(4 + 1位)。 [需要_BSD_SOURCE或_SVID_SOURCE]
CBAUDEX
(不适用于POSIX)CBAUD中包含额外的波特率掩码(1位)。 [需要_BSD_SOURCE或_SVID_SOURCE]
(POSIX表示,波特率速度存储在termios结构中,而没有指定精确的位置,并提供cfgetispeed()和cfsetispeed()进行获取。某些系统使用cBc在C_cflag中选择的位,其他系统使用单独的字段,例如,sg_ispeed和sg_ospeed。)
CSIZE
字符大小掩码。值为CS5CS6,CS7或CS8。
CSTOPB
设置两个停止位,而不是一个。
CREAD
启用接收器。
PARENB
对输出启用奇偶校验生成,对输入启用奇偶校验。
PARODD
如果设置,则输入和输出的奇偶校验为奇数;否则为0。否则,将使用奇偶校验。
HUPCL
最后一个过程关闭设备(挂断)后,降低调制解调器控制线。
CLOCAL
忽略调制解调器控制线。
LOBLK
(不适用于POSIX)阻止非当前Shell层的输出。供shl(外壳层)使用。 (未在Linux上实现。)
CIBAUD
(不适用于POSIX)输入速度的掩码。 CIBAUD位的值与CBAUD位的值相同,向左移IBSHIFT位。 [需要_BSD_SOURCE或_SVID_SOURCE](在Linux上未实现。)
CMSPAR
(不适用于POSIX)使用" stick"(标记/空格)奇偶校验(在某些串行设备上受支持):如果设置了PARODD,则奇偶校验位始终为1;否则为0。如果未设置PARODD,则奇偶校验位始终为0。[需要_BSD_SOURCE或_SVID_SOURCE]
CRTSCTS
(不在POSIX中)启用RTS / CTS(硬件)流控制。 [需要_BSD_SOURCE或_SVID_SOURCE]

c_lflag标志常量:

ISIG
收到任何字符INTR,QUIT,SUSP或DSUSP时,都会产生相应的信号。
ICANON
启用规范模式(如下所述)。
XCASE
(在POSIX中不是;在Linux下不受支持)如果还设置了ICANON,则terminal只能是大写字母。输入将转换为小写字母,但\之前的字符除外。在输出时,大写字符以\开头,小写字符转换为大写。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]
ECHO
回声输入字符。
ECHOE
如果还设置了ICANON,则ERASE字符将擦除前面的输入字符,而WERASE将擦除前面的单词。
ECHOK
如果还设置了ICANON,则KILL字符将擦除当前行。
ECHONL
如果还设置了ICANON,即使未设置ECHO,也应回显NL字符。
ECHOCTL
(不适用于POSIX)如果还设置了ECHO,则将TAB,NL,START和STOP以外的终端特殊字符回显为haX,其中X是ASCII码比特殊字符大0x40的字符。例如,字符0x08(BS)回显为haH。 [需要_BSD_SOURCE或_SVID_SOURCE]
ECHOPRT
(不在POSIX中)如果还设置了ICANON和ECHO,则在擦除字符时将其打印出来。 [需要_BSD_SOURCE或_SVID_SOURCE]
ECHOKE
(不在POSIX中)如果还设置了ICANON,则按照ECHOE和ECHOPRT的指定,通过擦除行上的每个字符来回显KILL。 [需要_BSD_SOURCE或_SVID_SOURCE]
DEFECHO
(不适用于POSIX)仅在读取进程时回显。 (未在Linux上实现。)
FLUSHO
(不在POSIX中;在Linux下不受支持)正在刷新输出。通过输入DISCARD字符可切换此标志。 [需要_BSD_SOURCE或_SVID_SOURCE]
NOFLSH
生成INT,QUIT和SUSP字符的信号时,请禁用刷新输入和输出队列。
TOSTOP
将SIGTTOU信号发送到尝试写入其控制终端的后台进程的进程组。
PENDIN
(在POSIX中不是;在Linux下不受支持)在读取下一个字符时,将重新打印输入队列中的所有字符。 (bash(1)以这种方式处理提前输入。)[需要_BSD_SOURCE或_SVID_SOURCE]
IEXTEN
启用实现定义的输入处理。必须启用此标志以及ICANON,才能解析特殊字符EOL2,LNEXT,REPRINT,WERASE,并使IUCLC标志有效。

c_cc数组定义终端特殊字符。符号索引(初始值)和含义是:

VDISCARD
(不适用于POSIX; Linux不支持; 017,SI,Ctrl-O)切换:开始/停止丢弃待处理的输出。设置IEXTEN后识别,然后不作为输入传递。
VDSUSP
(不适用于POSIX; Linux不支持; 031,EM,Ctrl-Y)延迟的挂起字符(DSUSP):当用户程序读取该字符时发送SIGTSTP信号。在设置IEXTEN和ISIG且系统支持作业控制,然后不作为输入传递时识别。
VEOF
(004,EOT,Ctrl-D)文件结尾字符(EOF)。更准确地说:此字符使待处理的tty缓冲区被发送到等待的用户程序,而无需等待行尾。如果它是该行的第一个字符,则用户程序中的read(2)返回0,表示文件结束。设置ICANON后识别,然后不作为输入传递。
VEOL
(0,NUL)附加的行尾字符(EOL)。设置ICANON时可识别。
VEOL2
(不在POSIX中; 0,NUL)另一个行尾字符(EOL2)。设置ICANON时可识别。
VERASE
(0177,DEL,外表或010,BS,Ctrl-H或#)擦除字符(ERASE)。这会擦除以前尚未擦除的字符,但不会擦除过去的EOF或行首。设置ICANON后识别,然后不作为输入传递。
VINTR
(003,ETX,Ctrl-C或0177,DEL,rubout)中断字符(INTR)。发送SIGINT信号。设置ISIG后识别,然后不作为输入传递。
VKILL
(025,NAK,Ctrl-U或Ctrl-X或@),杀死角色(KILL)。自上次EOF或行首以来,这将擦除输入。设置ICANON后识别,然后不作为输入传递。
VLNEXT
(不适用于POSIX; 026,SYN,Ctrl-V)立即数下一个(LNEXT)。引用下一个输入字符,使它失去可能的特殊含义。设置IEXTEN后识别,然后不作为输入传递。
VMIN
非规范读取的最小字符数(MIN)。
VQUIT
(034,FS,Ctrl- \)退出字符(QUIT)。发送SIGQUIT信号。设置ISIG后识别,然后不作为输入传递。
VREPRINT
(不在POSIX中; 022,DC2,Ctrl-R)重新打印未读字符(REPRINT)。设置ICANON和IEXTEN,然后不作为输入传递时识别。
VSTART
(021,D​​C1,Ctrl-Q)起始字符(START)。重新启动由Stop​​字符停止的输出。设置IXON后识别,然后不作为输入传递。
VSTATUS
(不适用于POSIX; Linux不支持;状态请求:024,DC4,Ctrl-T)。状态字符(STATUS)。在终端上显示状态信息,包括前台进程的状态及其已消耗的CPU时间。还将SIGINFO信号(Linux不支持)发送到前台进程组。
VSTOP
(023,DC3,Ctrl-S)停止字符(STOP)。停止输出,直到键入开始字符。设置IXON后识别,然后不作为输入传递。
VSUSP
(032,SUB,Ctrl-Z)挂起字符(SUSP)。发送SIGTSTP信号。设置ISIG后识别,然后不作为输入传递。
VSWTCH
(不在POSIX中;在Linux下不受支持; 0,NUL)切换字符(SWTCH)。在System V中用于在Shell层中切换Shell,这是Shell作业控制的前身。
VTIME
非规范读取(TIME)的超时时间(以分秒为单位)。
VWERASE
(不适用于POSIX; 027,ETB,Ctrl-W)字擦除(清除)。设置ICANON和IEXTEN,然后不作为输入传递时识别。

通过将相应的c_cc元素的值设置为_POSIX_VDISABLE,可以禁用单个终端特殊字符。

除了VTIME,VMIN分别具有与VEOL,VEOF相同的值外,以上符号下标值均不同。在非规范模式下,特殊字符含义由超时含义代替。有关VMIN和VTIME的说明,请参见下面的非规范模式说明。

Retrieving and changing terminal settings

tcgetattr()获取与fd引用的对象关联的参数,并将其存储在termios_p引用的termios结构中。该功能可以从后台进程中调用;但是,终端属性可能随后会被前台进程更改。

tcsetattr()从termios_p引用的termios结构中设置与终端关联的参数(除非需要不可用的基础硬件的支持)。 optional_actions指定更改何时生效:

TCSANOW
更改立即发生。
TCSADRAIN
在传输完所有写入fd的输出之后,将发生更改。更改影响输出的参数时,应使用此选项。
TCSAFLUSH
更改发生在写入fd引用的对象的所有输出都已传输之后,并且在进行更改之前,已接收但未读取的所有输入将被丢弃。

Canonical and noncanonical mode

c_lflag中ICANON佳能标志的设置确定终端是在规范模式下(ICANON设置)还是在非规范模式下(ICANON未设置)运行。默认情况下,设置ICANON。

在规范模式下:

*
逐行提供输入。输入一个行定界符(NL,EOL,EOL2或行首的EOF)时,输入行可用。除EOF以外,行定界符包含在read(2)返回的缓冲区中。
*
启用了行编辑(ERASE,KILL;如果设置了IEXTEN标志:WERASE,REPRINT,LNEXT)。 read(2)最多返回一行输入;如果read(2)请求的字节少于当前输入行中可用的字节,则仅读取请求的字节数,其余字符可用于将来的read(2)。
*
最大行长为4096个字符(包括终止的换行符);长度超过4096个字符的行将被截断。在4095个字符之后,将继续进行输入处理(例如ISIG和ECHO *处理),但在4095个字符之后(直至(但不包括)任何终止换行符)的所有输入数据都将被丢弃。这样可以确保终端可以始终接收更多输入,直到可以读取至少一行。

在非规范模式下,输入立即可用(无需用户输入行定界符),不执行任何输入处理,并且禁用行编辑。读缓冲区仅接受4095个字符;如果将输入模式切换为规范,则为换行符提供了必要的空间。 MIN(c_cc [VMIN])和TIME(c_cc [VTIME])的设置确定read(2)完成的情况;有四种不同的情况:

MIN == 0, TIME == 0 (polling read)
如果有可用数据,read(2)将立即返回,而可用字节数或请求的字节数较少。如果没有可用数据,则read(2)返回0。
MIN > 0, TIME == 0 (blocking read)
read(2)阻塞,直到MIN个字节可用为止,并返回最多所请求的字节数。
MIN == 0, TIME > 0 (read with timeout)
TIME以十分之一秒为单位指定计时器的限制。调用read(2)时启动计时器。当至少一个字节的数据可用或计时器到期时,read(2)返回。如果计时器到期而没有任何可用输入,则read(2)返回0。如果在调用read(2)时数据已经可用,则该调用的行为就好像在调用之后立即接收到数据一样。
MIN > 0, TIME > 0 (read with interbyte timeout)
TIME specifies the limit for a timer in tenths of a second. Once an initial byte of input becomes available, the timer is restarted after each further byte is received. read(2)

returns when any of the following conditions is met:

*
收到了MIN个字节。
*
字节间计时器到期。
*
已接收到read(2)请求的字节数。 (POSIX未指定此终止条件,在某些其他实现中,在这种情况下,read(2)不会返回。)
由于仅在初始字节可用后才启动计时器,因此将至少读取一个字节。如果在调用read(2)时数据已经可用,则该调用的行为就像在调用之后立即接收到数据一样。

POSIX不指定O_NONBLOCK文件状态标志的设置是否优先于MIN和TIME设置。如果设置了O_NONBLOCK,则无论MIN或TIME的设置如何,非规范模式下的read(2)都可能立即返回。此外,如果没有可用数据,则POSIX允许在非规范模式下的read(2)返回0或-1,并将errno设置为EAGAIN。

Raw mode

cfmakeraw()将终端设置为类似于旧版本7终端驱动程序的"原始"模式:逐字符可用输入,禁用回显,并且禁用终端输入和输出字符的所有特殊处理。终端属性设置如下:

termios_p->c_iflag &= ti(IGNBRK | BRKINT | PARMRK | ISTRIP
                | INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= tiOPOST;
termios_p->c_lflag &= ti(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ti(CSIZE | PARENB);
termios_p->c_cflag |= CS8;

Line control

如果终端使用异步串行数据传输,则tcsendbreak()会在特定持续时间内传输连续的零值比特流。如果持续时间为零,则它将零值位传输至少0.25秒且不超过0.5秒。如果持续时间不为零,则它将在某些实现定义的时间长度内发送零值位。

如果终端未使用异步串行数据传输,则tcsendbreak()将返回而不采取任何措施。

tcdrain()等待,直到写入fd引用的对象的所有输出都已传输。

根据queue_selector的值,tcflush()丢弃写入fd所引用但未发送的对象的数据或已接收但未读取的数据:

TCIFLUSH
刷新已接收但未读取的数据。
TCOFLUSH
刷新已写入但未传输的数据。
TCIOFLUSH
刷新已接收但未读取的数据,以及已写入但未传输的数据。

tcflow()挂起fd引用的对象上的数据传输或接收,具体取决于action的值:

TCOOFF
暂停输出。
TCOON
重新启动暂停的输出。
TCIOFF
发送一个STOP字符,该字符将阻止终端设备向系统发送数据。
TCION
发送一个START字符,这将启动终端设备向系统发送数据。

终端文件打开时的默认设置是既不暂停其输入也不暂停其输出。

Line speed

提供了波特率功能,用于在termios结构中获取和设置输入和输出波特率的值。在成功调用tcsetattr()之前,新值不会生效。

将速度设置为B0指示调制解调器"挂断"。对应于B38400的实际比特率可以使用setserial(8)进行更改。

输入和输出波特率存储在termios结构中。

cfgetospeed()返回存储在termios_p指向的termios结构中的输出波特率。

cfsetospeed()将存储在termios_p所指向的termios结构中的输出波特率设置为speed,该波特率必须是以下常量之一:

        B0
        B50
        B75
        B110
        B134
        B150
        B200
        B300
        B600
        B1200
        B1800
        B2400
        B4800
        B9600
        B19200
        B38400
        B57600
        B115200
        B230400

零波特率B0用于终止连接。如果指定了B0,则调制解调器控制线将不再有效。通常,这将断开线路。 CBAUDEX是POSIX.1(57600及更高版本)中定义的速度以外的速度的掩盖。因此,B57600和CBAUDEX不为零。

cfgetispeed()返回存储在termios结构中的输入波特率。

cfsetispeed()将存储在termios结构中的输入波特率设置为speed,必须将其指定为cfsetospeed()上面列出的Bnnn常数之一。如果输入波特率设置为零,则输入波特率将等于输出波特率。

cfsetspeed()是4.4BSD扩展。它采用与cfsetispeed()相同的参数,并设置输入和输出速度。

返回值

cfgetispeed()返回存储在termios结构中的输入波特率。

cfgetospeed()返回存储在termios结构中的输出波特率。

所有其他函数返回:

0
成功。
-1
如果失败,则设置errno来指示错误。

请注意,如果可以成功执行任何请求的更改,则tcsetattr()返回成功。因此,在进行多项更改时,可能有必要在此调用之后再调用tcgetattr()以检查是否已成功执行所有更改。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
tcgetattr(),tcsetattr(),tcdrain(),tcflush(),tcflow(),tcsendbreak(),cfmakeraw(),cfgetispeed(),cfgetospeed(),cfsetispeed(),cfsetospeed(),cfsetspeed()Thread safetyMT-Safe

遵循规范

在POSIX.1-2001中指定了tcgetattr(),tcsetattr(),tcsendbreak(),tcdrain(),tcflush(),tcflow(),cfgetispeed(),cfgetospeed(),cfsetispeed()和cfsetospeed()。

cfmakeraw()和cfsetspeed()是非标准的,但在BSD上可用。

备注

UNIX V7和更高版本的系统都有一个波特率列表,其中B14,...,B9600这十四个值之后是两个常量EXTA,EXTB(" External A"和" External B")。许多系统以更高的波特率扩展了列表。

tcsendbreak()的非零持续时间的影响会有所不同。 SunOS指定了一个持续时间* N秒的间隔,其中N至少为0.25,并且不大于0.5。 Linux,AIX,DU,Tru64发送间隔时间为毫秒的中断。 FreeBSD和NetBSD以及HP-UX和MacOS忽略持续时间的值。在Solaris和UnixWare下,持续时间为非零的tcsendbreak()的行为类似于tcdrain()。

BUGS

在Linux 4.16之前的Alpha架构(和2.28之前的glibc)上,XTABS值不同于TAB3,因此它被终端驱动程序的N_TTY行规程代码忽略(因为它不是TABDLY掩码的一部分) )。

另外参见

reset(1),setterm(1),stty(1),tput(1),tset(1),tty(1),ioctl_console(2),ioctl_tty(2),setserial(8)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/