《UNIX环境高级编程》笔记74--特殊输入字符

来源:互联网 发布:淘宝网qq飞车雷诺永久 编辑:程序博客网 时间:2024/06/06 07:38

POSIX.1定义了11个在输入是做特殊处理的字符。实现定义了另外一些特殊字符。下表摘要列出了这些特殊字符。


POSIX.1允许禁用这些字符。若将c_cc数组中的某项设置为_POSIX_VDISABLE的值,则禁用相应的特殊字符。可以使用

tcsetattr函数进行操作。

使用函数tcgetattr和tcsetattr可以获得或设置termios结构。

[cpp] view plain copy
  1. #include<termios.h>  
  2. int tcgetattr(int filedes, struct termios *termptr);  
  3. int tcsetattr(int filedes, int opt, const struct termios *termptr);  
  4. //这两个函数若成功则返回0,出错则返回-1.  
因为这两个函数只对终端设备进行操作,所以若filedes并不引用一个终端设备则出错返回-1,errno设置为ENOTTY。

opt参数使我们可以指定在什么时候新的终端属性才起作用。使用以下的常量:

TCSANOW  更改立即发生。

TCSADRAIN  发送了所有输出后更改才发生。若更改输出参数则应使用此选项。

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


实践:程序中禁用了终端信号。

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <termios.h>  
  3. #include <unistd.h>  
  4.   
  5. int main(void){  
  6.         struct termios term;  
  7.         long vdisable;  
  8.   
  9.         if(isatty(STDIN_FILENO) == 0){  
  10.                 printf("STDIN is not a terminal device.\n");  
  11.                 return -1;  
  12.         }  
  13.   
  14.         if((vdisable = fpathconf(STDIN_FILENO, _PC_VDISABLE)) < 0){  
  15.                 perror("fpathconf");  
  16.                 return -1;  
  17.         }  
  18.   
  19.         if(tcgetattr(STDIN_FILENO, &term) < 0){  
  20.                 perror("tcgetattr");  
  21.                 return -1;  
  22.         }  
  23.   
  24.         term.c_cc[VINTR] = vdisable;  
  25.   
  26.         if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &term) < 0){  
  27.                 perror("tcsetattr");  
  28.                 return -1;  
  29.         }  
  30.   
  31.         return 0;  
  32. }  

执行结果:

yan@vm:~/apue$ ping 192.168.18.249
PING 192.168.18.249 (192.168.18.249) 56(84) bytes of data.
64 bytes from 192.168.18.249: icmp_req=1 ttl=64 time=4.65 ms
64 bytes from 192.168.18.249: icmp_req=2 ttl=64 time=0.464 ms
64 bytes from 192.168.18.249: icmp_req=3 ttl=64 time=0.803 ms
^C
--- 192.168.18.249 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.464/1.973/4.653/1.900 ms
yan@vm:~/apue$ ./a.out
yan@vm:~/apue$ ping 192.168.18.249
PING 192.168.18.249 (192.168.18.249) 56(84) bytes of data.
64 bytes from 192.168.18.249: icmp_req=1 ttl=64 time=0.456 ms
64 bytes from 192.168.18.249: icmp_req=2 ttl=64 time=0.555 ms
^C^C^C64 bytes from 192.168.18.249: icmp_req=3 ttl=64 time=0.482 ms
^C^C^C64 bytes from 192.168.18.249: icmp_req=4 ttl=64 time=0.774 ms
^C^C^C^C64 bytes from 192.168.18.249: icmp_req=5 ttl=64 time=0.479 ms

可以看到在执行程序前可以使用ctrl+c取消程序,但是执行程序后,ctrl+c已经被禁用了。关闭终端后再次打开,恢复原来的设置,

ctrl+c再次能使用。因为重新打开终端后,termios中的值变成默认值。


tcsetattr设置的选项可以使用stty -a命令查看:

yan@yanwenjie-vm:~/apue$ stty -a
speed 9600 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke


yan@yan-vm:~/apue$ ./a.out


yan@yan-vm:~/apue$ stty -a
speed 9600 baud; rows 24; columns 80; line = 0;
intr = <undef>; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

上述中,intr = ^C; 变成了intr = <undef>; 

原创粉丝点击