Chinaunix首页 | 论坛 | 博客
  • 博客访问: 752676
  • 博文数量: 130
  • 博客积分: 2951
  • 博客等级: 少校
  • 技术积分: 1875
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-04 18:32
文章分类

全部博文(130)

文章存档

2013年(1)

2012年(129)

分类: C/C++

2012-10-26 14:59:14

摘自《linux-unix编程实践》

  1. #include    <stdio.h>
  2. #include    <signal.h>
  3. #include    <termios.h>

  4. #define    LINELEN    512
  5. #define    oops(s) { perror(s); exit(1); }

  6. void do_more(FILE *);
  7. int see_more(FILE *);

  8. int main(int ac,char *av[])
  9. {
  10.     FILE    *fp;
  11.     int    rv = 0;

  12.     settings(0);
  13.     if ( ac == 1 )
  14.         do_more(stdin);
  15.     else
  16.         while ( --ac )
  17.             if ( (fp=fopen(*++av,"r")) != NULL ) {
  18.                 do_more(fp) ;
  19.                 fclose(fp);
  20.             }
  21.             else {
  22.                 perror(*av);
  23.                 rv = 1;
  24.                 break;
  25.             }
  26.     settings(1);
  27.     return rv;
  28. }

  29. /*
  30.  * * called for SIGINT and SIGQUIT
  31.  * * - Just reset terminal and get out
  32.  * */
  33. void handler(int s)
  34. {
  35.     settings(1);
  36.     exit(0);
  37. }

  38. /*
  39.  * * program settings are turned on and off here
  40.  * */
  41. settings(int how)
  42. {
  43.     void handler(int);
  44.     int    rv;

  45.     static struct termios    term_orig;

  46.     /* read settings */
  47.     if ( how == 0 )
  48.     {
  49.         struct termios        term_new;

  50.         rv = tcgetattr(0, &term_orig);    /* get settings */
  51.         if ( rv == -1 )
  52.             oops("getting settings");
  53.         term_new = term_orig;
  54.         term_new.c_lflag &= ~ICANON;    /* noncanonical    */
  55.         term_new.c_lflag &= ~ECHO;    /* no echo     */
  56.         term_new.c_cc[VMIN] = 1;    /* chr-by-chr    */

  57.         rv = tcsetattr(0, TCSANOW, &term_new);
  58.         if ( rv == -1 )
  59.             oops("changing settings");

  60.         signal(SIGINT,handler);
  61.         signal(SIGQUIT,handler);
  62.     }
  63.     else
  64.     {
  65.         tcsetattr(0, TCSANOW, &term_orig);
  66.     }
  67. }

  68. void do_more( FILE *fp )
  69. /*
  70.  * * read PAGELEN lines, then call see_more() for further instructions
  71.  * */
  72. {
  73.     char    line[LINELEN];
  74.     FILE    *fp_tty;
  75.     int    num_of_lines = 0;
  76.     int    see_more(FILE *), reply;
  77.     int    pagelen = screen_rows(1);

  78.     fp_tty = fopen( "/dev/tty", "r" );     /* NEW: cmd stream */
  79.     if ( fp_tty == NULL )             /* if open fails */
  80.         exit(1); /* no use in running */

  81.     while ( fgets( line, LINELEN, fp ) ){        /* more input    */
  82.         if ( num_of_lines == pagelen ) {    /* full screen?    */
  83.             reply = see_more(fp_tty); /* NEW: pass FILE * */
  84.             if ( reply == 0 )        /* n: done */
  85.                 break;
  86.             if ( reply == -1 )
  87.                 num_of_lines = 0;
  88.             else
  89.                 num_of_lines -= reply;    /* reset count    */
  90.         }
  91.         if ( fputs( line, stdout ) == EOF )    /* show line    */
  92.             exit(1);            /* or die    */
  93.         num_of_lines++;                /* count it    */
  94.     }
  95. }

  96. int see_more(FILE *cmd)                 /* NEW: accepts arg */
  97. /*
  98.  * *    print message, wait for response, return # of lines to advance
  99.  * *    q means no, space means yes, CR means one line
  100.  * *    Returns -1 for spacebar (ie. full screen)
  101.  * */
  102. {
  103.     int    c;

  104.     printf("\033[7m more? \033[m");        /* reverse on a vt100    */
  105.     while( (c=getc(cmd)) != EOF )        /* NEW: reads from tty */
  106.     {
  107.         printf("\r \r");        /* erase message    */
  108.         if ( c == 'q' )            /* q -> N        */
  109.             return 0;
  110.         if ( c == ' ' )            /* ' ' => next page    */
  111.             return -1;        /* -1 means full page    */
  112.         if ( c == '\n' )        /* Enter key => 1 line    */
  113.             return 1;        
  114.         printf("\033[7m more? \033[m");    /* put it back        */
  115.     }
  116.     return 0;
  117. }

  118. #include <sys/ioctl.h>

  119. /*
  120.  * * returns the number of rows associated with fd
  121.  * * or 24 if that number cannot be determined
  122.  * */
  123. int
  124. screen_rows(fd)
  125. {
  126.     struct winsize wbuf;

  127.     if ( ioctl(fd, TIOCGWINSZ, &wbuf) != -1 )
  128.         return wbuf.ws_row;
  129.     return 24;
  130. }

阅读(947) | 评论(0) | 转发(0) |
0

上一篇:C小程序 - printf 2

下一篇:NIM与SCS

给主人留下些什么吧!~~