more 自写 linux命令

满足
1.回车 下一行
2.空格 下一页
3.q 退出
4.下方有”–More–(百分比)"
截图如下:
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<sys/types.h>
#include<sys/ioctl.h>
#include<unistd.h>
#include<termios.h>

#define MOVEUP(x) printf("\033[%dA", (x))
#define MOVEDOWN(x) printf("\033[%dB", (x))

int PAGELINE;
int LENLINE;
int FILELINE = 0;

void do_more(FILE *fp);
void init(FILE *fp);

int main(int argc, char **argv) {
    FILE *fp;
	if (argc == 1) {
        do_more(stdin); 
    }
    else {
        while (--argc) {
            argv++;
            if ((fp = fopen(*argv, "r")) != NULL) {
                init(fp);
                fclose(fp);
            }
            else {
                exit(1);
            }

            if ((fp = fopen(*argv, "r")) != NULL) {
                do_more(fp);
                fclose(fp);
            }
            else {
                exit(1);
            }
        }
    }
    return 0;
}

void init(FILE *fp) {
	struct winsize size;
    ioctl(STDIN_FILENO,TIOCGWINSZ,&size);
    LENLINE = size.ws_col;
    PAGELINE = size.ws_row - 2;
    char line[LENLINE] = {0};
    while (fgets(line, LENLINE, fp) != NULL) {
        FILELINE++;
    }
}

void do_more(FILE *fp) {
    char line[LENLINE] = {0};
    char more_str[] = "\033[7m --More-- \033[m";
    int num_line = 0, reply, get_cmd(FILE *), cnt = 0;
    FILE *fp_tty_in, *fp_tty_out;  
    fp_tty_in = fopen("/dev/tty", "r");  
    fp_tty_out = fopen("/dev/tty", "w");  

    struct termios initial_settings, new_settings;  
    tcgetattr(fileno(fp_tty_in), &initial_settings);  
    new_settings = initial_settings;  
    new_settings.c_lflag &= ~ECHO;
    new_settings.c_lflag &= ~ICANON;
    new_settings.c_cc[VMIN] = 1;

    if(tcsetattr(fileno(fp_tty_in), TCSANOW, &new_settings) != 0) { 
        fprintf(stderr, "could not set attributes\n");  
    }  

    while (fgets(line, LENLINE, fp) != NULL) {
        if (num_line == PAGELINE) {
            MOVEDOWN(2);
            if (FILELINE == 0) FILELINE = 1;
            printf("%s(%.2f%%)\n", more_str, (float)(cnt * 100.0 / FILELINE));
            MOVEUP(1);
            reply = get_cmd(fp_tty_in);
            printf("                           \n");
            MOVEUP(1);
            if (reply == 0) break;
            num_line -= reply;
        }
        printf("%s", line);
        /*
        if( fputs(line, fp_tty_out) == EOF) {
            tcsetattr(fileno(fp_tty_in), TCSANOW, &initial_settings);
            exit(1);  
        } 
        */
		num_line++;
        cnt++;
    }
	tcsetattr(fileno(fp_tty_in), TCSANOW, &initial_settings);
}

int get_cmd(FILE *cmd) {
    int c, ret = -1;
    while ((c = fgetc(cmd)) != EOF) {
        if (c == 'q') ret = 0;
        if (c == ' ') ret = PAGELINE;
        if (c == '\n') ret = 1;
        sleep(1);
        return ret;
    }
    return ret;
}
发布了209 篇原创文章 · 获赞 72 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_43870649/article/details/105031086