无名管道例程:more分页显示程序

一、例程功能描述和代码思路

① 功能描述

将要浏览显示的文件内存 通过 管道 传输到 分页程序(more)中直接分页显示。

② 代码思路

第一步:通过main传参 传递 要浏览的文件路径
第二步:fopen打开该文件
第三步:创建无名管道
第四步:创建子进程
第五步:
        父进程 循环 读取 文件中的数据,并且写到 管道中
        子进程 使继承父进程的标准输入称为管道的读端
        使用exec调用more程序去管道读端获取文本数据并且显示
        注意虽然子进程调用exec,该子进程进程完全由新程序代换,替换原有进程的正文,但是之前的udp2的操作不受到影响。

③ 实例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>

#define     DEF_PAGER "/bin/more"   /*默认的系统分页程序*/
#define     MAXLINE   20

struct demo_inf
{
    FILE * fp;
    int  fd[2];
    char file_line_data[MAXLINE];
    int pid;
    char *pager;
    char * argv_process_name;
    
}DI;

void Pagination_Program(const char * obj_read_file);
void Pagination_Program(const char * obj_read_file)
{
    DI.fp = fopen(obj_read_file,"r");
    if(DI.fp == NULL)
    {
        perror("fopen ... ");
        exit(-1);
    }

    if(pipe(DI.fd) < 0)
    {
        perror("pipe ... ");
        exit(-1);
    }

    if((DI.pid = fork()) < 0)
    {
        perror("fork ... ");
        exit(-1);
    }
    else if(DI.pid > 0)
    {
        /*父进程*/
        memset(DI.file_line_data,0,MAXLINE);
        while( fgets(DI.file_line_data,MAXLINE,DI.fp) != NULL)
        {
            
            if(write(DI.fd[1],DI.file_line_data,strlen(DI.file_line_data)) == -1)
            {
                perror("write ... ");
                exit(-1);
            }
            memset(DI.file_line_data,0,MAXLINE);
        }

        if(ferror(DI.fp))
        {
            perror("ferror ... ");
            exit(-1);
        }

        if(feof(DI.fp))
        {
            if(waitpid(DI.pid,NULL,0) < 0)
            {
                perror("waitpid ... ");
                exit(-1);
            }
            exit(0);
        }
    }
    else
    {
        /*子进程*/
        if(DI.fd[0] != STDIN_FILENO)
        {
            if(dup2(DI.fd[0],STDIN_FILENO) != STDIN_FILENO)
            {
                perror("udp2 ... ");
                exit(-1);
            }
        }

        if((DI.pager = getenv("PAGER")) == NULL) // 获取分页系统MORE的环境变量路径
        {
            //perror("getenv error use default path");
            DI.pager = DEF_PAGER;
        }

        //环境变量中截取more程序名字
        if((DI.argv_process_name = strrchr(DI.pager,'/')) != NULL)
        {
            DI.argv_process_name++;
        }
        else
        {
            DI.argv_process_name = DI.pager; // 如果路径中没有/只能不需要切割
        }

        //调用exec启动more

        if(execl(DI.pager,DI.argv_process_name,NULL) < 0)
        {
            perror("execl ... ");
            exit(-1);
        }



    }

    exit(0);
}



int main(int agrc, char ** argv)
{
    if(agrc != 2)
    {
        printf("输入是没有指定文件!\n");
    
        return -1;
    }


    Pagination_Program(argv[1]);

    exit(0);
}

运行结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值