设为首页 加入收藏

TOP

C小程序 - 终端一些特性的控制
2012-11-01 09:15:30 】 浏览:728
Tags:程序   终端 一些 特性 控制
  #include    <stdio.h>
  
  #include    <termios.h>
  
  #include    <fcntl.h>
  
  #include    <string.h>
  
  #define    ASK        “Do you want again ”
  
  #define TIMEOUT 6 /* time per try */
  
  #define    BEEP putchar(‘\a’) /* alert user */
  
  main()
  
  {
  
  int    response;
  
  tty_mode(0);                /* save current mode    */
  
  set_input_mode(TIMEOUT);
  
  response = get_response(ASK);        /* get some answer    */
  
  tty_mode(1);                /* restore orig mode    */
  
  putchar(‘\n’);
  
  return response;
  
  }
  
  get_response( char *question )
  
  /*
  
  * purpose: ask a question and wait for a y/n answer or maxtries
  
  * method: use getchar and complain about non-y/n input
  
  * returns: 0=>yes, 1=>no, 2=>timeout
  
  */
  
  {
  
  int    input;
  
  //后面采用了清空~ISIG标志位,所以这里就不用信号函数了
  
  //    signal(SIGINT, SIG_IGN);        /* ignore kbd signals    */
  
  //    signal(SIGQUIT, SIG_IGN);
  
  printf(“%s (y/n)?”, question);            /* ask        */
  
  fflush(stdout);                    /* force output    */
  
  while ( 1 ){
  
  input = tolower(getchar()); /* get next chr */
  
  if ( input == 'y' )
  
  return 0;
  
  if ( input == 'n' )
  
  return 1;
  
  if ( input == EOF )            /* timeout    */
  
  return 2;            /* sayso    */
  
  BEEP;
  
  }
  
  }
  
  set_input_mode(int timeout)
  
  /*
  
  * purpose: put file descriptor 0 into chr-by-chr mode and noecho mode
  
  * AND set VTIME to 5*timeout
  
  * See manpage for termios to learn how values of VMIN and
  
  * VTIME work
  
  * method: use bits in termios
  
  */
  
  {
  
  struct    termios    ttystate;
  
  tcgetattr( 0, &ttystate);        /* read curr. setting    */
  
  ttystate.c_lflag     &= ~ICANON;    /* 设置无缓冲,即输入一个字符就读一个字符,不会等到按回车再处理        */
  
  ttystate.c_lflag     &= ~ECHO;    /* 设置不回显,即按下某个键,屏幕不会显示    */
  
  ttystate.c_cc[VMIN]     = 1;        /* 最少读取的字符数    */
  
  ttystate.c_cc[VTIME]     = 5*timeout;    /* 设置终端超时时间,这里是3秒,5*6=30毫秒,即3秒*/
  
  ttystate.c_lflag     &= ~ISIG;    /* 不产生输入信号,即Ctrl+C这样的信号被屏蔽    */
  
  tcsetattr( 0 , TCSANOW, &ttystate);    /* install settings    */
  
  }
  
  /* how == 0 => save current mode, how == 1 => restore mode */
  
  /* this version handles termios and fcntl flags */
  
  tty_mode(int how)
  
  {
  
  static struct termios original_mode;
  
  static int original_flags;
  
  if ( how == 0 )
  
  tcgetattr(0, &original_mode);
  
  else
  
  tcsetattr(0, TCSANOW, &original_mode);
  
  }
  
  但是上面这个程序,却在超时后不会自动返回,主要是因为VMIN的设置有问题。
  
  参看下面的解释:
  
  情形A:MIN > 0, TIME > 0.TIME说明一个字节间的计时器,在接到第一个字节时才起动它。在该计时器超时之前,若已接到MIN个字节,则read返回MIN个字节。如果在接到MIN个字节之前,该计时器已超时,则read返回已接收到的字节(因为只有在接到第一个字节时才起动,所以在计时器超时时,至少返回1个字节)。在这种情形中,在接到第一个字节之前,调用者阻塞。如果在调用read时数据已经可用,则这如同在read后,数据立即被接收到一样。
  
  情形B:MIN > 0 , TIME = = 0.已经接到了MIN个字节时,read才返回。这可以造成read无限期的阻塞。
  
  情形C:MIN = = 0,TIME > 0.TIME指定了一个调用read时起动的读计时器。(与情形A相比较,两者是不同的)。在接到1个字节或者该计时器超时时,read即返回。如果是计时器超时,则read返回0.
  
  情形D :MIN = = 0,TIME = = 0.如果有数据可用,则read最多返回所要求的字节数。如果无数据可用,则read立即返回0.
  
  所以,在上述程序中把
  
  ttystate.c_cc[VMIN]     = 1;        /* 最少读取的字符数    */
  
  改为
  
  ttystate.c_cc[VMIN]     = 0;        /* 最少读取的字符数    */
  
  Then it works.
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C中的static修饰的镜头变量含义 下一篇C小程序 - 处理传入参..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目