Linux下自己编写的more命令

    /* 
      重定向方面存在缺憾(重定向后每调试完成) 
       stdin时非重定向可用read和write屏蔽部分部分 
     
    */  
      
    #include <stdlib.h>  
    #include <stdio.h>  
    #include <unistd.h>   
    #include <string.h>  
    #include <sys/types.h>//lstat  
    #include <sys/stat.h> //lstat  
    #include<termios.h>  
      
    #define PAGELEN 24  
    #define LINELEN 1024  
    //#define BUFFSIZE 8192  
      
    void settermattr();    //设置终端属性  
    void do_more(FILE *);  
    int see_more(FILE *);  
      
    int filesize;   //文件的大小  
    int readsize;   //已经显示的内容长度  
      
    struct termios ts,ots;     //终端属性  
      
    int main(int argc,char *argv[])  
    {  
        FILE *fp;  
        struct stat buf;  
        settermattr();    
      
        if(argc==1)   //eg: mymore < mymore.c    ->argc=1   未计算filesize,filesize为0  
        {   do_more(stdin);   }  
        else{  
            while(--argc)  
            {  
                if(lstat(*++argv,&buf)<0)  
                 {    
                    fprintf(stderr,"ERROR: lstat error\n");  
                  }  
                else{  
                                filesize+=buf.st_size;     //输入重定向后,标准输入< 后的参数不可获得  
                                if((fp = fopen(*argv,"r"))!=NULL)  
                    {   
                    fprintf(stdout,"............................\n");  
                    fprintf(stdout,"....%20s....\n",*argv);  
                    fprintf(stdout,"............................\n");  
                    do_more(fp);  
                    fclose(fp);  
                    }  
                    else{  
                    fprintf(stderr,"ERROR: cannot open file: %s\n",*argv);  
                    exit(1);  
                        }  
                     }    
            }  
              }  
        tcsetattr(STDIN_FILENO,TCSANOW,&ots);//将修改后的终端属性复原,TCSANOW表示修改立即生效  
        return 0;  
    }  
      
    void do_more(FILE * fp)  
    {  
      
        char    line[LINELEN];  
        int     num_of_lines = 0;  
        int see_more(FILE *);  
        int replay;  
    //  int n;  
    //  char    buf[BUFFSIZE];  
        FILE    *fp_tty;  
      
        fp_tty = fopen( "/dev/tty", "r" );     /* NEW: cmd stream   */  
        if ( fp_tty == NULL )              /* if open fails     */  
        {     
            fprintf(stderr,"ERROR:  open /dev/tty fails\n");  
            exit(1);  
        }  
      
    /*      
     *     当用重定向符定向标准输入时,不能分页显示,一下全部显示出来。故屏掉 
     * 
        if( fp ==stdin) //将标准输入写到标准输出,read write 包含在unistd.h头文件中 
        { 
            while ( (n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)   //read返回读得的字节数,用作要写的字节数,当达到末尾时,read返回0,发生错误返回-1 
            if (write(STDOUT_FILENO, buf, n) != n) 
            {   fprintf(stderr,"ERROR: write error!\n"); 
                exit(1); 
            } 
     
            if(n<0){ 
                fprintf(stderr,"ERROR: read error!\n"); 
                exit(1); 
            } 
        }else 
              { 
    * 
    * 
    *    
    */  
           while(fgets(line,LINELEN,fp))  
           {        
            readsize+=strlen(line);   
               if(num_of_lines == PAGELEN)  
               {  
                   replay = see_more(fp_tty);  /* NEW: pass FILE *  */  
                   if(replay==0)  
                   {   tcsetattr(STDIN_FILENO,TCSANOW,&ots); //TCSANOW表示修改立即生效  
                       break;  
                   }  
                   num_of_lines-=replay;  
               }  
               if(fputs(line,stdout)==EOF)  
                          {  
                   tcsetattr(STDIN_FILENO,TCSANOW,&ots); //TCSANOW表示修改立即生效  
                   break;  
                }  
               num_of_lines++;  
               }  
      
        //}  
    }  
      
    int see_more(FILE *cmd)                /* NEW: accepts arg  */  
    /* 
     *  print message, wait for response, return # of lines to advance 
     *  q means no, space means yes, CR means one line 
     */  
    {  
        int c;  
      
        printf("\033[7m--more--(%2.0f%%)\033[m",(double)readsize/filesize*100);  
        //printf("\033[7m--more--(%d/%d)\033[m",readsize,filesize);  
        while( (c=getc(cmd)) != EOF )       /* NEW: reads from tty  */  
        {  
            if ( c == 'q' )         /* q -> N        */  
            {  
                  
                            printf("\033[2K\n");  
                return 0;  
            }  
            if ( c == ' ' )         /* ' ' => next page  */  
                    {  
                 printf("\033[2K");     /*清除上行提示信息*/  
                return PAGELEN;     /* how many to show */  
            }  
            if ( c == '\n' )        /* Enter key => 1 line   */  
            {  
                  
                            printf("\033[2K");  
                return 1;         
                    }  
        }  
        return 0;  
    }  
      
      
      
    void settermattr(){  
        tcgetattr(STDIN_FILENO,&ts);    //获取终端属性   
        ots=ts;         //备份终端属性  
        ts.c_lflag &= (~ECHO);    //阻止回显  
        ts.c_lflag &= (~ICANON);    //设置终端为非标准模式  
        ts.c_cc[VMIN]=1;        //这两行当需要从终端获取字符时立即返回,不需要按回车键  
        ts.c_cc[VTIME]=0;  
        tcsetattr(STDIN_FILENO,TCSAFLUSH,&ts);    //设置终端的新属性。TCSAFLUSH表示输出队列空了以后才生效,生效之前的输出队列被flush  
    }  

你可能感兴趣的:(c,linux,more)