将文件复制到分页程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#define DEF_PAGER "/bin/more"
#define MAXLINE 512
int main(int argc, char *argv[])
{
int n;
int fd[2];
pid_t pid;
char *pager,*argv0;
char line[MAXLINE];
FILE *fp;
if(argc != 2)
printf("Usage: a.out <pathname>");
if((fp=fopen(argv[1],"r"))==NULL)
printf("can't open %s", argv[1]);
if(pipe(fd)<0)
fprintf(stderr,"pipe error:%d\n", errno);
if((pid=fork())<0)
{
fprintf(stderr,"fork error:%d\n", errno);
}
else if(pid>0)
{
close(fd[0]);
while(fgets(line, MAXLINE, fp)!=NULL)
{
n = strlen(line);
if(write(fd[1],line,n) != n)
fprintf(stderr, "write error:%d\n", errno);
}
if(ferror(fp))
fprintf(stderr, "fgets error:%d\n", errno);
close(fd[1]);
if(waitpid(pid, NULL, 0)<0)
fprintf(stderr, "waitpid error:%d\n", errno);
exit(0);
}
else
{
close(fd[1]);
if(fd[0]!=STDIN_FILENO)
{
if(dup2(fd[0],STDIN_FILENO)!=STDIN_FILENO)
printf("dup2 error to stdin");
close(fd[0]);
}
if((pager=getenv("PAGER"))==NULL)
pager=DEF_PAGER;
if((argv0 = strrchr(pager, '/'))!=NULL)
argv0++;
else
argv0 = pager;
if(execl(pager, argv0,(char *)0)<0)
printf("execl error ");
}
exit(0);
}
1,为了避免先将所有数据写到一个临时文件中,然后再调用系统中有关程序显示该文件,我们希望将输出通过管道直接送到分页程序
2,在调用fork之前先创建一个管道,fork之后父进程关闭其读端,子进程关闭其写端。子进程然后调用dup2,使其标准输入成为管道的读端
3,execl第一个参数为程序名,这里用strrchr函数从绝对路径里得到程序名