热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linux获取终端输入进程,Linux终端输入输出(termios)函数

termios系列函数-tcgetattr,tcsetattr,tcsendbreak,tcdrain,tcflush,tcflow,cfmakeraw,cfgetospeed,c

termios系列函数-tcgetattr, tcsetattr, tcsendbreak, tcdrain, tcflush, tcflow, cfmakeraw, cfgetospeed, cfgetispeed, cfsetispeed, cfsetospeed, cfsetspeed等,用以获取/设置终端设备的属性/控制/速度。1. 函数声明

函数声明

#include #include /*获取文件描述符fd对应设备状态置入termios_p所指向结构体中*/

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

/*设置文件描述符对应设备状态*/

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

/*向fd发送0比特*/

int tcsendbreak(int fd, int duration);

/*挂起直到所有写入fd的输出全部发送完毕*/

int tcdrain(int fd);

/*丢弃所有准备写入但还未发送给fd的数据或从fd已接收但还还未被读取的数据*/

/*丢弃对象取决于queue_selector*/

int tcflush(int fd, int queue_selector);

/*挂起fd发送操作或接收操作,挂起对象取决于action*/

int tcflow(int fd, int action);

/*设备终端属性*/

void cfmakeraw(struct termios *termios_p);

/*返回termios_p所指向结构体中的输入波特率*/

speed_t cfgetispeed(const struct termios *termios_p);

/*返回termios_p所指向结构体中的输出波特率*/

speed_t cfgetospeed(const struct termios *termios_p);

/*设置termios_p所指向结构体中的输入波特率*/

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

/*设置termios_p所指向结构体中的输出波特率*/

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

/*4.4BSD扩展,设置输入输出波特率*/

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

glibc功能测试宏定义:

cfsetspeed(), cfmakeraw(): _BSD_SOURCE2. termios结构体

大多数termios函数都会用到termios结构。termios结构体定义如下:

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150typedefunsignedcharcc_t;

typedefunsignedintspeed_t;

typedefunsignedinttcflag_t;

structtermios

{

tcflag_t c_iflag;       /* input mode flags */

tcflag_t c_oflag;       /* output mode flags */

tcflag_t c_cflag;       /* control mode flags */

tcflag_t c_lflag;       /* local mode flags */

cc_t c_line;            /* line discipline */

cc_t c_cc[NCCS];        /* control characters */

speed_t c_ispeed;       /* input speed */

speed_t c_ospeed;       /* output speed */

#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1

#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1

};

c_iflag标志常量

IGNBRK忽略输入BREAK条件

BRKINT如果设置了IGNBRK,BREAK将会被忽略;如果仅仅设置了BRKINT,BREAK将会丢弃输入和输出队列中的数据(flush),并且如果终端为前台进程组的控制终端,则BREAK将会产生一个SIGINT信号发送到这个前台进程组。如果IGNBRK和BRKINT均未设置,BREAK将会被当作读入了null字节('\0'),除非设置了PARMRK标志被设置,在这种情况下,BREAK将会被当作读入了\377\0\0序列。

IGNPAR忽略帧错误和奇偶校验错误

PARMRK如果未设置IGNPAR标志,在带有奇偶校验错误或帧错误的字符前使用\377\0来标志;如果IGNPAR和PARMRK均未设置,则将奇偶校验错误的字符当作\0

INPCK允许输入奇偶校验

ISTRIP剥离第8个bit

INLCR将输入中的NL转换成CR

IGNCR忽略输入中的回车

ICRNL将输入中的CR转换为NL

IUCLC(非POSIX)将输入中的大写字符转换为小写

IXON允许输出端的XON/XOFF流控

IXANY(XSI)任意击键将会重启已停止的输出(默认情况仅允许使用START字符来重启输出)

IXOFF允许输入端XON/XOFF流控

IMAXBEL (非POSIX)输入队列满时响铃。Linux未实现此标志位,总是以此标志位被设置的情况动作

IUTF8(从Linux 2.6.4开始支持,非POSIX)输入为UTF8编码

c_oflag标志常量定义(POSIX.1):

OPOST允许实现定义的输出处理

OLCUC(非POSIX)将输出中的小写字母映射为大写

ONLCR(XSI)将输出中的NL映射为CR-NL

OCRNL将输出中的CR映射为NL

ONOCR不在第零列输出CR

ONLRET不输出CR

OFILL发送填充字符实现延迟,而不是使用时间上的延迟

OFDEL(非POSIX)填充字符为ASCII DEL(0177)。如果未设置,填充字符为ASCII NUL('\0')。(Linux中未实现)

NLDLY新行延迟掩码。值为NL0和NL1。(需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE)

CRDLY回车(CR)延迟掩码。值为CR0,CR1,CR2,或CR3。(需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE)

TABDLY水平制表符延迟掩码。值为TAB0,TAB1,TAB2,TAB3(或XTABS)。值TAB3/XTABS表示将制表符扩展为空格(每8列为一个制表符停止位)。(需要_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或_XOPEN_SOURCE)

CBAUDEX(非POSIX)附加波特速率掩码(1比特),包含在CBAUD中。(需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE)

CSIZE字符尺寸掩码。值为CS5,CS6,CS7,或CS8

CSTOPB设置两个停止位(bits),而不是一位

CREAD允许接收器

PARENB允许输出端生产奇偶校验位,输入端进行校验

PARODD如设置,则输入输出端奇偶校验为奇校验;未设置则为偶校验

HUPCL上一次操作关闭设备后将调制解调器控制线设为低电平(挂起)

CLOCAL忽略调制解调器控制线

LOBLK(非POSIX)阻塞非当前shell层输出。(Linux未实现)

CIBAUD(非POSIX)输入速率掩码。

CMSPAR(非POSIX)使用"stick"奇偶校验:如果设置了PARODD,将奇偶检验位总是置为1;如果未设置PARODD,奇偶校验位总是置为0.

CRTSCTS允许RTS/CTS(硬件)流控。(需要_BSD_SOURCE或_SVID_SOURCE)

c_lflag标志常量:

ISIG当接收到INTR/QUIT/SUSP/DSUSP字符,生成一个相应的信号

ICANON允许canonical模式

XCASE(非POSIX,Linux不支持)如果设置了ICANON,终端仅为大写字符模式。输入字符被转换为小写,除非以'\'开始;输出端,大写字符以'\'开始,小写字符被转换为大写

ECHO回显所输入的字符

ECHOE如果同时设置了ICANON标志,ERASE字符删除前一个所输入的字符,WERASE删除前一个输入的单词

ECHOK如果同时设置有ICANON标志,KILL字符删除当前行

ECHONL如果同时设置有ICANON标志,回显NL字符即使ECHO未设置

ECHOCTL(非POSIX)如果同时设置有ECHO标志,除TAB/NL/START/STOP外的ASCII控制字符将会被回显成'^X',其中X为控制符数值加0x40

ECHOPRT(非POSIX)如果同时设置有ICANON和IECHO,字符以已删除方式打印

ECHOKE(非POSIX)如果设置有ICANON,KILL以删除所在行所有字符方式显示

DEFECHO(非POSIX)仅当有进程读取时回显字符(Linux未实现)

FLUSHO(非POSIX,LINUX不支持)输出被丢弃。

NOFLSH当生成SIGINT/SIGQUIT/SIGSUSP信号时禁止丢弃(flush)输入输出队列

TOSTOP当后台进程试图写入自己的控制终端时,发送SIGTTOU信号给进程组

PENDIN(非POSIX,Linux不支持)

IEXTEN允许实现所定义的输入处理。

c_cc数组定义了一些特殊控制字符:

VINTR003,ETX,Ctrl-C,0177,DEL,rubout,中断字符。发送SIGINT信号。

VQUIT034,FS,Ctrl-\,退出字符。发送SIGQUIT信号。

VERASE0177,DEL,rubout,010,BS,Ctrl-H,#, 删除字符。删除上一个未删除的字符,但不删除前面的EOF或者行开始字符。

VKILL025,NAK,Ctrl-U,Cgtrl-X,@,Kill字符。删除自上一个EOF或行开始字符之后的所有输入字符。

VEOF004,EOT,Ctrl-D,文件结尾(End-of-file)。EOF将会让挂起的tty缓冲区内容发送给处于等待中的用户程序,而不用等待行结束标识(End-of-line)。

VMIN非canonical模式读操作的最少字符数

VEOL(0,NUL)额外的行结束符(End-of-line)

VTIME非canonical模式读操作超时(单位为1/10秒)

VEOL2(非POSIX;0,NUL)另一个行结束标识

VSWTCH(非POSIX;Linux不支持;0,NUL)切换字符

VSTART021,DC1,Ctrl-Q,开始字符。重启被STOP字符停止的输出

VSTOP023,DC3,Ctrl-S,停止字符。停止输出直到START

VSUSP032,SUB,Ctrl-Z,挂起字符。发送SIGSTP信号

VDSUSP(非POSIX;Linux不支持)031,EM,Ctrl-Y,延迟挂起字符:当用户程序读取字符时发送SIGTSTP信号

VLNEXT(非POSIX)026,SYN,Ctrl-V,标识下一个字符为字面意思而非可能的特殊控制含义

VWERASE(非POSIX)027,ETC,Ctrl-W,单词删除

VREPRINT(非POSIX)022,DC2,Ctrl-R,再次打印未读取字符

VDISCARD(非POSIX;Linux不支持)017,SI,Ctrl-O,开关切换:开始/停止丢弃挂起的输出

VSTATUS(非POSIX;Linux不支持)024,DC4,Ctrl-T,状态请求3. 获取/更改终端设置

tcgetattr(),tcsetattr()分别用于获取/更改终端设置

tcgetattr()获取fd所指定终端的设置并存放入termios结构指针termios_p指向的地址空间;后台进程所获取的终端设置也可能随后被前台进程更改

tcsetattr()设置指定终端的属性。可选动作项指定终端属性何时更改:TCSANOW立即更改

TCSADRAIN当写入fd的所有输出发送完毕后更改

TCSAFLUSH所有写入fd的输出发送完毕,并且所有已接收但未读入的输入被丢弃后更改设置4. Canonical和non-canonical模式

c_lflag字段中的ICANON标志决定终端是否工作在canonical模式。缺省情况下,终端为canonical模式

canonical模式

输入工作在行模式。收到行定界符(NL,EOL,EOL2;或行首的EOF)后,输入行可供读取。read操作所读取的行内容包含行定界符。

允许行编辑(ERASE,KILL;如设置了IEXTEN标志,WERASE,REPRINT,LNEXT)。

non-canonical模式下,无需用户输入行定界符,输入立即可读取。

c_cc[VTIME]和c_cc[VMIN]对read操作的影响:

MIN==0;TIME==0:如有数据可用,read立即返回min(请求数量,可用字符数量)个字符;如无数据可用,read返回0

MIN>0;TIME==0:read阻塞,直到至少有min(请求数量,MIN)个字符可用,read返回两值中较小的一个

MIN==0;TIME>0:TIME指定读取超时(单位为1/10秒)。当调用read时设定定时器。当至少有一个字符可用或超时后,read返回。如果在超时前无可用字符,read返回0

MIN>0;TIME>0:TIME指定读取超时,收到输入的第一个字符后重启定时器。read在读取到MIN和所请求数量两者中较少的字符,或超时后,返回。至少会读取到一个字符。5. Raw模式

cfmakeraw()设置终端工作在"raw"模式下:输入以字符方式提供,禁止回显,所有特殊字符被禁止。

raw模式下,终端属性如下:

termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP

| INLCR | IGNCR | ICRNL | IXON);

termios_p->c_oflag &= ~OPOST;

termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);

termios_p->c_cflag &= ~(CSIZE | PARENB);

termios_p->c_cflag |= CS8;6. 线控

控制与终端的连接

tcsendbreak如果终端工作在异步串行数据发送模式,在指定时长内发送0比特流。如果时长为0,发送0比特流至少0.25s,但不多于0.5s。如果终端未工作在异步串行数据发送模式,tcsendbreak立刻返回不作任何操作。

tcdrain()等待直到所有输出至fd的数据均被发送

tcflush()丢弃已写入fd但还未发送的数据,或丢弃已接收但还未读取的数据。丢弃对象取决于queue_selector:TCIFLUSH丢弃已接收但还未读取的数据

TCOFLUSH丢弃已写入但还未发送的数据

TCIOFLUSH丢弃以上两种

tcflow()挂起fd的发送或接收操作。挂起对象取决于action:TCOOFF挂起输出

TCOON重启挂起的输出

TCIOFF发送STOP字符,停止终端设备向系统发送数据

TCION发送START字符,启动设备向系统发送数据7. 线速

控制输入/输出波特率

设置波特率为B0会使调制解调器挂起(Hang up)。B38400对应的实际速率可能会受到setserial(8)的影响。

cfgetospeed()返回输出波特率

cfsetospeed()设置输出波特率为B0/B50/B75/B110/B134/B150/B200/B300/B600/B1200/B1800/B2400/B4800/B9600/B38400/B57600/B115200/B230400

*B0用于终止连接

cfgetispeed()返回输入波特率

cfsetispeed()设置输入波特率

cfsetspeed()4.4BSD扩展,同时将输入输入波特率设置为同一值8. 返回值

标识函数调用结果

cfgetispeed()/cfgetospeed()返回输入/输出波特率

对其他函数,返回值为0表示成功;-1表示失败,errno给出错误

*对于tcsetattr(),只要任一要更改的属性设置成功,则会返回成功。9. 例

获取标准输入终端(STDIN)的属性并更改标准输入终端为raw模式(也可以使用更简便的调用-cfmakeraw()完成),接收键盘输入、显示键值,直到接收到Ctrl-b输入。

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150#include

#include

#include

#include

#include

#include

#define BUF_LENGTH 255

intmain(void)

{

intret = 0;

charbuf[BUF_LENGTH]={0};

inti = 0;

structtermios newtmios={0};

structtermios oldtmios={0};

ret = tcgetattr(STDIN_FILENO, &oldtmios);

if( ret )

{

printf("tcgetattr() error, errno = 0x%X\n", errno);

return-1;

}

memcpy(&newtmios, &oldtmios, sizeof(structtermios));

newtmios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP

| INLCR | IGNCR | ICRNL | IXON);

newtmios.c_oflag &= ~OPOST;

newtmios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);

newtmios.c_cflag &= ~(CSIZE | PARENB);

newtmios.c_cflag |= CS8;

ret = tcsetattr(STDIN_FILENO, TCSANOW, &newtmios);

if( ret )

{

printf("tcsetattr() error, errno = 0x%X\n", errno);

return-2;

}

printf("Press any key(Ctrl-b to quit) :\n ");

tcdrain(STDIN_FILENO);

while( 1 )

{

ret = read(STDIN_FILENO, buf, BUF_LENGTH);

if( ret )

{

printf("\rread %d chars, you pressed ", ret);

for(i=0; i" 0x%02X ", buf[i]);

printf("\r\n");

if( (1==ret) && (0x02 == buf[0]) )

{

break;

}

}

}

ret = tcsetattr(STDIN_FILENO, TCSANOW, &oldtmios);

returnret;

}



推荐阅读
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
author-avatar
九九九丶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有