/* * duped_pipe.c * This program will demonstrate how to dup a file * descriptor and open a pipe. * * to compile: cc -O -pipe duped_pipe.c -o duped_pipe * */ #include #include #include #include #include #define CHILD_FILE ("child_out") #define MODE (S_IRWXU | S_IRWXG | S_IROTH | S_IWOTH) #define MAX_BUFF (1024) #define CAT ("cat") int main(int argc, char **argv) { int fds[2], log, infile; char buff[MAX_BUFF]; size_t len; pid_t child; if( argc > 1 ) { infile = open(argv[1], O_RDONLY); if( infile < 0 ) { perror("Open failed!\n"); exit(0); } /* * Create our pipe */ if( pipe(fds) == 0 ) { /* open our childs log */ log = open(CHILD_FILE, (O_RDWR | O_CREAT), MODE); if( log > 0 ) { /* * Now that we have our pipe, input file, and our log * file we need to fork, then set the log file as the * childs STDOUT. Then set the read end of the pipe * as the childs STDIN. */ child = fork(); if( child == 0 ) { /* Child * ----- * Close the child's write end of the pipe because if * we leave it open the child will never recieve * the end-of-file marker on the read end of the pipe. */ close(fds[1]); /* * Now we have to close STDIN by calling dup2 with * STDIN as the newfd arg. That way dup2 will close * STDIN for us and then, set STDIN to our read * end of the pipe. */ if( dup2(fds[0], STDIN_FILENO) >= 0 ) { /* * Now we have to set the log file to * STDOUT. Agian calling dup2 with STDOUT * as the newfd arg will cause it to be closed * and STDOUT set to log file descriptor. */ if( dup2(log, STDOUT_FILENO) < 0) { perror("Cannot dup STDOUT! \n"); exit(0); } /* Now exec cat */ execlp(CAT, CAT, 0); /* never reached unless error */ perror("Error cannot exec !\n"); exit(0); } /* if( dup2 ) */ else { perror("Cannot dupe STDINT !\n"); exit(0); } } /* fork */ else { /* Parent * ------ * All the parent has to do is first close its * read end of the pipe, and then simply read and write * out the file to the child. */ close(fds[0]); do { len = read(infile, buff, MAX_BUFF); write(fds[1], buff, len); }while( len > 0); close(fds[1]); close(infile); } } /* if(log) */ }/* if(pipe) */ else { perror("Pipe failed !"); } } /* if( argc ) */ else { printf("Error, please specify a file like so\n"); printf(" $ %s \n", argv[0]); } /* FIN */ return(0); }