termios 结构是在POSIX规范中定义的标准接口,它类似于系统V中的termio接口,通过设置termios类型的数据结构中的值和使用一小

组函数调用,你就可以对终端接口进行控制。

可以被调整来影响终端的值按照不同的模式被分为如下几组:

1.输入模式

2.输出模式

3.控制模式

4.本地模式

5.特殊控制模式

最小的termios结构的典型定义如下:

struct termios

{

tcflag_t c_iflag;

tcflag_t c_oflag;

tcflag_t c_cflag;

tcflag_t c_lflag;

cc_t           c_cc[NCCS];

};

结构成员的名称与上面列出的5种参数类型相对应。

你可以调用函数tcgetattr来初始化一个终端对应的termios结构,该函数的原型如下:

  1. #include<termios.h>
  2. int tcgetattr(int fd, struct termios *termios_p);

这个函数调用把当前终端接口变量的值写入termios_p参数指向的结构。如果这些值其后被修改了,你可以通过调用函数tcsetattr来重新配置

终端接口。

  1. #include<termios.h>
  2. int tcsetattr(int fd , int actions , const struct termios *termios_h);

参数actions控制修改方式,共有三种修改方式,如下所示。

1.TCSANOW:立刻对值进行修改

2.TCSADRAIN:等当前的输出完成后再对值进行修改。

3.TCSAFLUSH:等当前的输出完成之后,再对值进行修改,但丢弃还未从read调用返回的当前的可用的任何输入。

接下来我们将分别对五种模式进行介绍。

一 输入模式

输入模式控制输入数据在传递给程序之前的处理方式。你通过设置termios结构中的c_iflag成员的标志对它们进行控制。所有的标志都被定义为

宏,并可通过按位或的方式结合起来。

可用于c_iflag成员的宏如下所示:

BRKINT:当在输入行中检测到一个终止状态时,产生一个中断。

TGNBRK:忽略输入行中的终止状态。

TCRNL:将接受到的回车符转换为新行符。

TGNCR:忽略接受到的新行符。

INLCR:将接受到的新行符转换为回车符。

IGNPAR:忽略奇偶校检错误的字符。

INPCK:对接收到的字符执行奇偶校检。

PARMRK:对奇偶校检错误作出标记。

ISTRIP:将所有接收的字符裁减为7比特。

IXOFF:对输入启用软件流控。

IXON:对输出启用软件流控。

如果BRKINT和TGNBRK标志都未被设置,则输入行中的终止状态就被读取为NULL(0X00)字符。

三.输出模式

输出模式控制输出字符的处理方式,即由程序发出的字符在传递到串行口或屏幕之前如何处理.通过设置c_oflag成员的标识对输出模式进行控制.

OPSOT:打开输出处理功能

ONLCR:将输出中的换行符转换为回车符

OCRNL:将回车符转换为换行符

ONOCR:第0行不输出回车符

ONLRET:不输出回车符

NLDLY:换行符延时选择

CRDLY:回车符延时

TABDLY:制表符延时

...

输出模式用得也不多

四.控制模式

控制模式控制终端的硬件特性,通过c_cflag成员标识配置.

CLOCAL:忽略所有调制解调器的状态行

CREAD:启用字符接收器

CS5/6/7/8:发送或接收字符时使用5/6/7/8比特

CSTOPB:每个字符使用两停止位

HUPCL:关闭时挂断调制解调器

PARENB:启用奇偶校验码的生成和检测功能

PARODD:只使用奇检验而不用偶校验

一般也不用这种方式,通常直接修改终端配置文件来修改硬件特性要容易一些

五.本地模式

通过c_lflag成员控制终端的某些特性

ECHO:启用输入字符的本地回显功能

ECHONL:回显换行符

ICANON:启用标准输入处理

ISIG:启用信号

...

最常用的是ECHO和ICANON标志,前者抑制键入字符的回显(抑制??),后者如说明

六.特殊的控制字符

标准模式和非标准模式下,c_cc数组的下标有不同的值:

标准模式:

VEOF:EOF字符

VEOL:EOL字符

VERASE:ERASE字符

VINTR:INTR字符

VKILL:KILL字符

VQUIT:QUIT字符

VSTART:START字符

VSTOP:STOP字符

非标准模式:

VINTR:INTR字符

VMIN:MIN值

VQUIT:QUIT字符

VSUSP:SUSP字符

VTIME:TIME值

VSTART:START字符

VSTOP:STOP字符

1.字符

INTR:该字符使终端驱动程序向与终端相连的进程以送SIGINT信号

QUIT:该字符使终端驱动程序向与终端相连的进程发送SIGQUIT信号

EOF;该字符使终端驱动程序将输入行中的全部字符传递给正在读取输入的应用程序.如果输入行为空,read调用将返回0,就好像在文件尾调用read一样

...

2.TIME和MIN值

这两个值只用于非标准模式,两者结合共同控制对输入的读取方式,还能控制在一个程序试图与一个终端关联的文件描述符时将发生的情况

MIN = 0, TIME = 0时:read立即返回,如果有待处理的字符,它们就会被返回,如果没有,read调用返回0,且不读取任何字符

MIN = 0, TIME > 0时:有字符处理或经过TIME个0.1秒后返回

MIN > 0, TIME = 0时:read一直等待,直到有MIN个字符可以读取,返回值是字符的数量.到达文件尾时返回0

MIN > 0, TIME > 0时:read调用时,它会等待接收一个字符.在接收到第一个字符及其后续的每个字符后,启用一个字符间隔定时器.当有MIN个字符可读或两字符间的时间间隔超进TIME个0.1秒时,read返回

通过设置MIN和TIME值,我们可以逐个字符地对输入进行处理

3.通过shell访问终端模式

stty -a:这个命令用来查看当前终端的设置情况

stty sane:如果不小心设错了终端模式,可用这个命令恢复,另一种恢复办法是在设置之前保存当前stty设置,在需要时再读出

stty -g > save_stty:将当前设置保存到文件save_atty中

stty $(cat save_stty):读出save_atty文件,恢复原终端设置

第三种恢复的办法是重新打下一个终端模拟器.查看死掉的终端进程,kill掉它

4.在命令行模式下设置终端模式

比如想让shell脚本读取单个字符,就需要关闭标准模式,同时将MIN设为1,TIME设为0:

stty -icanon min1 time 0

另一个例子是关闭输入密码时的回显功能:

atty -echo

使用完这个命令后要执行atty echo,将回显功能再次恢复

5.终端速度

termios结构中没有关于终端速度的成员和标识,但我们可以通过一组函数来实现.注意输入和输出是分开的,应使用不同的函数

#include <termios.h>

speed_t cfgetispeed(const struct termios *);

speed_t cfgetospeed(const struct termios *);

int cfsetispeed(struct termios *, speed_t speed);

int cfseospeed(struct termios *, speed_t speed);

这些函数只作用于termios结构,因此需要先调用tcgetattr()获得termios结构,再调用以上函数之一设置终端速度,最后调用tcsetattr()使设置生效

上面的speed参数可设的值,其中比较重要的几个:

B0:挂起终端

B1200:1200波特

B2400:2400波特

B9600:9600波特

B19200:19200波特

B38400:38400波特

6.其他函数

这些函数直接作用于文件描述符,不需要读写termios结构:

#include <termios.h>

int tcdrain(int fd);让调用程序一直等待,直到所有排队的输出都发送完毕

int tcflow(int, int flowtype);暂停或重新开始输出

int tcflush(int fd, int in_out_selector);清空输入,输出或两者都清华空

使用termios结构的密码程序

  1. #include <termios.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #define PASSWORD_LEN 8
  5. int main()
  6. {
  7. struct termios initialrsettings, newrsettings;
  8. char password[PASSWORD_LEN + 1];
  9. tcgetattr(fileno(stdin), &initialrsettings);
  10. newrsettings = initialrsettings;
  11. newrsettings.c_lflag &= ~ECHO;
  12. printf("Enter password: ");
  13. if(tcsetattr(fileno(stdin), TCSAFLUSH, &newrsettings) != 0) {
  14. fprintf(stderr,"Could not set attributes\n");
  15. }
  16. else {
  17. fgets(password, PASSWORD_LEN, stdin);
  18. tcsetattr(fileno(stdin), TCSANOW, &initialrsettings);
  19. fprintf(stdout, "\nYou entered %s\n", password);
  20. }
  21. exit(0);
  22. }

读取每一个字符

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <termios.h>
  5. char *menu[] = {
  6. "a - add new record",
  7. "d - delete record",
  8. "q - quit",
  9. NULL,
  10. };
  11. int getchoice(char *greet, char *choices[], FILE *in, FILE *out);
  12. int main()
  13. {
  14. int choice = 0;
  15. FILE *input;
  16. FILE *output;
  17. struct termios initial_settings, new_settings;
  18. if (!isatty(fileno(stdout))) {
  19. fprintf(stderr,"You are not a terminal, OK.\n");
  20. }
  21. input = fopen("/dev/tty", "r");
  22. output = fopen("/dev/tty", "w");
  23. if(!input || !output) {
  24. fprintf(stderr, "Unable to open /dev/tty\n");
  25. exit(1);
  26. }
  27. tcgetattr(fileno(input),&initial_settings);
  28. new_settings = initial_settings;
  29. new_settings.c_lflag &= ~ICANON;
  30. new_settings.c_lflag &= ~ECHO;
  31. new_settings.c_cc[VMIN] = 1;
  32. new_settings.c_cc[VTIME] = 0;
  33. new_settings.c_lflag &= ~ISIG;
  34. if(tcsetattr(fileno(input), TCSANOW, &new_settings) != 0) {
  35. fprintf(stderr,"could not set attributes\n");
  36. }
  37. do {
  38. choice = getchoice("Please select an action", menu, input, output);
  39. printf("You have chosen: %c\n", choice);
  40. } while (choice != 'q');
  41. tcsetattr(fileno(input),TCSANOW,&initial_settings);
  42. exit(0);
  43. }
  44. int getchoice(char *greet, char *choices[], FILE *in, FILE *out)
  45. {
  46. int chosen = 0;
  47. int selected;
  48. char **option;
  49. do {
  50. fprintf(out, "Choice: %s\n",greet);
  51. option = choices;
  52. while(*option) {
  53. fprintf(out, "%s\n",*option);
  54. option++;
  55. }
  56. do {
  57. selected = fgetc(in);
  58. } while (selected == '\n' || selected == '\r');
  59. option = choices;
  60. while(*option) {
  61. if(selected == *option[0]) {
  62. chosen = 1;
  63. break;
  64. }
  65. option++;
  66. }
  67. if(!chosen) {
  68. fprintf(out, "Incorrect choice, select again\n");
  69. }
  70. } while(!chosen);
  71. return selected;
  72. }

linux 端口设置结构体 struc的更多相关文章

  1. Linux C语言结构体-学习笔记

    Linux C语言结构体简介 前面学习了c语言的基本语法特性,本节进行更深入的学习. 预处理程序. 编译指令: 预处理, 宏定义, 建立自己的数据类型:结构体,联合体,动态数据结构 c语言表达式工具 ...

  2. iOS 用KVC设置结构体

    iOS 用KVC设置结构体 在Fundation中KVC提供的键值路径只能访问对象,不能访问结构体.这很不面向对象. 执行下面的语句将会报错: [self setValue:@() forKeyPat ...

  3. go语言通过反射获取和设置结构体字段值的方法

    本文实例讲述了go语言通过反射获取和设置结构体字段值的方法.分享给大家供大家参考.具体实现方法如下: type MyStruct struct { N int } n := MyStruct{ 1 } ...

  4. Linux内核device结构体分析

    1.前言 Linux内核中的设备驱动模型,是建立在sysfs设备文件系统和kobject上的,由总线(bus).设备(device).驱动(driver)和类(class)所组成的关系结构,在底层,L ...

  5. Linux内核kobject结构体分析

    1.前言 Linux内核中有大量的驱动,而这些驱动往往具有类似的结构,根据面向对象的思想,可以将共同的部分提取为父类,而这个父类就是kobject,kobject结构体中包含了大量设备的必须信息,而三 ...

  6. Linux进程: task_struct结构体成员

    一:简介 为了管理进程,内核必须对每个进程所做的事情进行清除的描叙. 比如:内核必须知道进程优先级,他是正在CPU上运行还是因为某些事件被阻塞了,给它分配了什么样的地址空间,允许它访问哪个文件等等.这 ...

  7. Linux C中结构体初始化

          在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式.该方式是某些C教材(如谭二版.K&R二版)中没有介绍过的.这种方式称为指定初始化(designated in ...

  8. Linux下C结构体初始化[总结]

    1.前言 今天在公司看一同事写的代码,代码中用到了struct,初始化一个struct用的是乱序格式,如下代码所示: typedef struct _data_t { int a; int b; }d ...

  9. Linux下C结构体初始化

    1.前言 今天在公司看一同事写的代码,代码中用到了struct,初始化一个struct用的是乱序格式,如下代码所示: typedef struct _data_t { int a; int b; }d ...

随机推荐

  1. 【BZOJ2138】stone(线段树,Hall定理)

    [BZOJ2138]stone(线段树,Hall定理) 题面 BZOJ 题解 考虑一个暴力. 我们对于每堆石子和每个询问,显然是匹配的操作. 所以可以把石子拆成\(a_i\)个,询问点拆成\(K_i\ ...

  2. 测试开发面试的Linux面试题总结之一:vim使用方法

    现在做测试没有说不用到linux,大部分公司都会涉及到,作为测试经常使用linux最常见手段就是查看日志,帮助开发定位问题,这是目前最常见的测试当中使用linux方法,今天就讲一讲vim文本编辑器的使 ...

  3. 修改apache的注册表值提高系统权限

    In Windows environments when a service is registered with the system a new key is created in the reg ...

  4. The meterprter basic commonds

    Using Meterpeter commands Since the Meterpreter provides awhole new environment, we will cover some ...

  5. 【noip2018】【luogu5021】赛道修建

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,…,n1,2,…,n,有 n-1n−1 条适合于修建赛道的双向通 ...

  6. [POJ3613] Cow Relays

    link 题目大意 给你一个含有边权的无向图,问从$S$到$T$经过$N$条边的最小花费. 试题分析 我们可以很容易推导$dp$方程,$dp(k,i,j)$表示经过$k$条边从$i$到$j$的最小花费 ...

  7. echars画折线图的一种数据处理方式

    echars画折线图的一种数据处理方式 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...

  8. SpringMVC接收复杂集合对象(参数)代码示例

    原文: https://www.jb51.net/article/128233.htm SpringMVC接收复杂集合对象(参数)代码示例 更新时间:2017年11月15日 09:18:15   作者 ...

  9. HDU--2962

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 分析:最短路+二分. #include<iostream> #include< ...

  10. Codeforces 895.C Square Subsets

    C. Square Subsets time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...