/* * pager.c -- modified from APUE textbook */ #include #include #include #include #include #define MAXLINE 256 #define DEF_PAGER "/bin/less" /* default pager program */ void err_quit(char *msg) { fprintf(stderr, "%s\n", msg); exit(-1); } int main(int argc, char *argv[]) { int i; int n; int fd[2]; pid_t pid; char *pager, *argv0; char line[MAXLINE]; FILE *fp; if (argc != 2) err_quit("usage: "); if ((fp = fopen(argv[1], "r")) == NULL) err_quit("can't open input file."); if (pipe(fd) < 0) err_quit("pipe error"); if ((pid = fork()) < 0) { err_quit("fork error"); } else if (pid > 0) { /* parent */ close(fd[0]); /* close read end */ /* parent copies argv[1] to pipe */ while (fgets(line, MAXLINE, fp) != NULL) { n = strlen(line); if (write(fd[1], line, n) != n) err_quit("write error to pipe"); } if (ferror(fp)) err_quit("fgets error"); close(fd[1]); /* close write end of pipe for reader */ if (waitpid(pid, NULL, 0) < 0) err_quit("waitpid error"); for ( i = 0; i < 3; i++ ) { fprintf(stdout, "Parent can continue here ...\n"); fflush(stdout); sleep(1); } exit(0); } else { /* child */ close(fd[1]); /* close write end */ if (fd[0] != STDIN_FILENO) { if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) err_quit("dup2 error to stdin"); close(fd[0]); /* don't need this after dup2 */ } /* get arguments for execl() */ if ((pager = getenv("PAGER")) == NULL) pager = DEF_PAGER; if ((argv0 = strrchr(pager, '/')) != NULL) argv0++; /* step past rightmost slash */ else argv0 = pager; /* no slash in pager */ if (execl(pager, argv0, (char *)0) < 0) err_quit("execl error for pager"); } exit(0); }