终端I/O应用很广泛,用于终端、计算机之间的直接连线、调制解调器以及打印机等等。终端I/O有两种不同的工作模式:

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

  (2)非规范模式输入处理:输入字符并不组成行。

  终端设备是由一般位于内核的终端驱动程序控制的,每个终端设备有一个输入队列和一个输出队列。如下图:

可以检测和更改的终端设备特性都包含在termios结构中。该结构定义在<termios.h>
struct termios{
tcflag_t   c_iflag;    输入标志
tcflag_t   c_oflag;     输出标志
tcflag_t   c_cflag;       控制标志
tcflag_t   c_lflag;       本地标志
cc_t     c_cc[NCCS];    控制字符
}
终端I/O函数

写个程序,更改特殊字符,禁用中断字符和更改文件结束符。程序如下:

1 #include <stdio.h>2 #include <stdlib.h>3 #include <termios.h>4 #include <errno.h>5 #include <unistd.h>6 7 int main()8 {9     struct termios term;
10     long   vdisable;
11     //判断标准输入是否是终端设备
12     if(isatty(STDIN_FILENO) == 0)
13     {
14         printf("Standard input is not a terminal device.\n");
15         exit(-1);
16     }
17     if((vdisable = fpathconf(STDIN_FILENO,_PC_VDISABLE))<0)
18     {
19         perror("fpathconf eeror or _POSIX_VDISABLE not in effect");
20         exit(-1);
21     }
22     //获取termios结构
23     if(tcgetattr(STDIN_FILENO,&term) < 0)
24     {
25         perror("tcgetattr error");
26         exit(-1);
27     }
28
29     term.c_cc[VINTR] = vdisable;
30     term.c_cc[VEOF] = 2;
31     //设置termios结构
32     if(tcsetattr(STDIN_FILENO,TCSAFLUSH,&term) < 0)
33     {
34         perror("tcsetattr error");
35         exit(-1);
36     }
37     return 0;
38 }

获取和设置终端属性函数:

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

调用以上函数屏蔽标志取或设置一个值,程序如下:

 1 #include <stdio.h>2 #include <stdlib.h>3 #include <termios.h>4 #include <errno.h>5 #include <unistd.h>6 7 int main()8 {9     struct termios term;
10     //获取termios结构
11     if(tcgetattr(STDIN_FILENO,&term) < 0)
12     {
13         perror("tcgetattr error");
14         exit(-1);
15     }
16     switch(term.c_cflag & CSIZE)
17     {
18     case CS5:
19         printf("5 bits/byte\n");
20         break;
21     case CS6:
22         printf("6 bits/byte\n");
23         break;
24     case CS7:
25         printf("7 bits/byte\n");
26         break;
27     case CS8:
28         printf("8 bits/byte\n");
29         break;
30     default:
31         printf("Unknown bityes/byte\n");
32     }
33     term.c_cflag &= ~CSIZE;   //字符长度清0
34     term.c_cflag |= CS5;          //设置为8 bites/byte
35     if(tcsetattr(STDIN_FILENO,TCSANOW,&term) < 0)
36     {
37         perror("tcsetattr error");
38         exit(-1);
39     }
40     return 0;
41 }

stty命令:在终端中输入stty -a命令显示终端的所有选项,执行命令结果如下:

终端标识:在大多数UNIXi系统中,控制终端的名字是/dev/tty。

char *ctermid(char *s);  //获取终端控制名字

int isatty(int fd); //判断fd是否为终端设备

char *ttyname(int fd);  // 获取终端设备的路径名

写个程序输出控制终端的标识符信息,程序如下:

1 #include <stdio.h>2 #include <stdlib.h>3 #include <termios.h>4 #include <unistd.h>5 #include <string.h>6 static char ctermid_name[L_ctermid];7 char* my_ctermid(char *str)8 {9     if(str == NULL)
10         str = ctermid_name;
11     return (strcpy(str,"/dev/tty"));
12 }
13 int main()
14 {
15     char tername[50];
16     char *name;
17     ctermid(tername);
18     printf("terminate name is: %s\n",tername);
19     my_ctermid(tername);
20     printf("my terminate name is: %s\n",tername);
21     printf("Test isatty() function.\n");
22     printf("fd 0 is: %s\n",isatty(0)? "tty" : "not a tty");
23     printf("fd 1 is: %s\n",isatty(1)? "tty" : "not a tty");
24     printf("fd 2 is: %s\n",isatty(2)? "tty" : "not a tty");
25     printf("Test ttyname() function.\n");
26     if(isatty(0))
27     {
28         name = ttyname(0);
29         if(name == NULL)
30             name ="undefined";
31     }
32     else
33         name = "not a tty";
34     printf("fd 0 :%s\n",name);
35     if(isatty(1))
36     {
37         name = ttyname(1);
38         if(name == NULL)
39             name ="undefined";
40     }
41     else
42         name = "not a tty";
43     printf("fd 1 :%s\n",name);
44     if(isatty(2))
45     {
46         name = ttyname(2);
47         if(name == NULL)
48             name ="undefined";
49     }
50     else
51         name = "not a tty";
52     printf("fd 2 :%s\n",name);
53     exit(0);
54 }

程序执行结果如下:

终端的窗口大小:内核为每个终端和伪终端保存了一个窗口大小结构winszie,用ioctl函数的TIOCGWINSZ命令可以获取此结构的当前值。

struct winsize {

  unsigned short ws_row;

  unsigned short ws_col;

  unsigned short ws_xpixel; /* unused */

  unsigned short ws_ypixel; /* unused */

};

写个程序打印终端窗口大小,程序如下:

 1 #include <stdio.h>2 #include <stdlib.h>3 #include <termios.h>4 #include <unistd.h>5 #include <string.h>6 #include <sys/ioctl.h>7 #include <signal.h>8 #include <errno.h>9
10 static void pr_winsize(int fd)
11 {
12     struct  winsize size;
13     if(ioctl(fd,TIOCGWINSZ,(char *)&size) < 0)
14     {
15         perror("ioctl() error");
16         exit(-1);
17     }
18     printf("%d rows,%d columns\n",size.ws_row,size.ws_col);
19 }
20 static void sig_winch(int signo)
21 {
22     printf("SIGWINCH received\n");
23     pr_winsize(STDIN_FILENO);
24 }
25 int main()
26 {
27     if(isatty(STDIN_FILENO) == 0)
28     {
29         printf("STDIN_FILENO is not terminate device.\n");
30         exit(1);
31     }
32     if(signal(SIGWINCH,sig_winch) == SIG_ERR)
33     {
34         perror("signal() error");
35         exit(-1);
36     }
37     pr_winsize(STDIN_FILENO);
38     for( ; ;)
39      pause();
40 }

程序执行结果如下:

总结:本章介绍了终端,涉及到很多系统底层的知识,很多参数。看的时候只是了解了一些基本的终端操作,还要很多地方不懂,关键是不知道终端用在什么地方,以后用到了需要回头好好学习一下。

转载于:https://www.cnblogs.com/alantu2018/p/8466200.html

Unix环境高级编程(十九)终端I/O相关推荐

  1. Unix环境高级编程(十五)高级I/O

    1.非阻塞I/O 对低速设备的I/O操作可能会使进程永久阻塞,这类系统调用主要有如下情况: (1)如果数据并不存在,则读文件可能会使调用者永远阻塞(例如读管道.终端设备和网络设备). (2)如果数据不 ...

  2. Unix环境高级编程(十)信号续

    1.signal函数 Unix系统的信号机制最简单的接口是signal函数,函数原型如下: #include <signal.h> typedef void (*sighandler_t) ...

  3. Unix环境高级编程 笔记

    Unix环境高级编程(第二版)学习笔记 这是一次较长时间的整理,然而跳跃了一些章节和很多知识点,仍然是很不完善很不全面的. 前言 操作系统某些问题 严格意义上,可将操作系统定义为一种软件,它控制计算机 ...

  4. 5w字总结 Unix系统编程学习笔记(面试向)(Unix环境高级编程/Unix环境程序设计)

    文章目录 一.计算 C语言的数据表示与处理 计算 C语言的基本运算操作 内存表和符号表 类型转换 函数类型的分析 指令 复合指令 句法 函数 函数激活(Activation Record) 函数激活定 ...

  5. unix环境高级编程 pdf_UNIX系统编程宝典,每一本都值得程序员珍藏

    这几本UNIX系统编程宝典,重印无数次,几代程序员都视如珍宝的几本书,小编在出版圈里快十年了,见证了这本书图灵版.异步社区版的出版.营销,对这套书倾注了一定的感情.今天继续分享给你们,好书总会有人还不 ...

  6. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  7. 《Unix环境高级编程》学习笔记:从点到面

    以前在课堂上学习过<Unix初级教程(第四版)>,对于Unix有了一点了解.由于以后使用的需要,要对它进行比较深入的学习,为此需要阅读不少的书籍,这本<Unix环境高级编程>便 ...

  8. 《UNIX环境高级编程(第3版)》——2.6 选项

    本节书摘来自异步社区<UNIX环境高级编程(第3版)>一书中的第2章,第2.6节,作者:[美]W. Richard Stevens , Stephen A.Rago著,更多章节内容可以访问 ...

  9. 【UNIX环境高级编程】

    [UNIX环境高级编程] 环境搭建 1.下载源码 wget http://apuebook.com/src.3e.tar.gz 2.解压 tar -zxvf src.3e.tar.gz 3.安装lib ...

  10. 《UNIX环境高级编程(第3版)》

    <UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison ...

最新文章

  1. (邓爱萍)类对象-this关键字
  2. 第五天2017/04/06(上午:文件的“读写操作”)
  3. opencv:读取、保存操作函数
  4. matlab怎么显示bfm模型的纹理模型,BFM模型介绍及可视化实现(C++)
  5. sql server生成不重复的时间字符串
  6. tensorflow summary demo with linear-model
  7. 关于dell电脑没有声音
  8. qam映射c程序_DVB-C系统中QAM调制与解调仿真
  9. 零基础小白入行3D建模,首先!你要了解什么叫建模!
  10. 青龙面板滴滴果园自动签到
  11. AD中使用Net Label时,编译时为什么总是Floating。出现的原因。
  12. 经典的10句人生箴言
  13. redis服务之主从复制、哨兵模式、群集模式
  14. linux基础(五)----linux命令系统学习----系统管理命令
  15. UPUPOO返回码格式!!!
  16. cox(Quaro)对设计的崭新定义,改变我的人生
  17. 记录微信小程序web-view页面分享出去之后没有返回首页按钮,微信小程序WebView页面分享出去后没有返回首页按钮,全局使用的自定义导航【解决办法】
  18. mac-怎么查询mac苹果电脑的保修期
  19. linux 杀毒软件查杀结果,Linux杀毒软件(ClamAV)
  20. Gorilla源码分析之gorilla/mux源码分析

热门文章

  1. C4D结合AE制作酷炫MG光影动画心得
  2. 程序员究竟还需要读书么?
  3. CSUST-2018区域赛选拔个人赛-1019 看直播(二分+DP)
  4. Python学习杂记_1_PyCharm使用的一些收获
  5. docker python3环境搭建
  6. 怎样解决python dataframe loc,iloc循环处理速度很慢的问题
  7. 获取cookies的简单代码(总结待续)
  8. 《Linux内核设计与实现》读书笔记 第一章 Linux内核简介
  9. jQuery调用WebService详解
  10. hdu 1394Minimum Inversion Number