Created
January 19, 2009 18:53
-
-
Save zaach/49106 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************** | |
* Pipe Example * | |
* * | |
* ls | wc > output * | |
* * | |
* Date: 09/20/07 * | |
* [email protected] * | |
***************************/ | |
#include <sys/wait.h> | |
#include <assert.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#define STDOUT 1 | |
#define STDIN 0 | |
int main(void) | |
{ | |
/*pid holds the process identification of the child*/ | |
pid_t pid[2]; | |
/*pfd = pipe file descriptor array | |
*status = used for waitpid */ | |
int pfd[2],status; //pfd = pipelineFileDescriptor is an array with 2 elements. | |
/* ask operating system for pipe, and place read end of pipe in pfd[0] and write end into pfd[1]*/ | |
pipe(pfd); //pfd[1] (the ls) becomes the opening of the pipe and pfd[0] (the wc) becomes the outside of the pipe | |
/*1st fork for "ls"*/ | |
pid[0] = fork(); | |
/*check if the pid returned from fork is 0 (for the child), or > 0 (for the parent)*/ | |
if(pid[0] == 0) | |
{ | |
/*We are in the child process*/ | |
/*first we need to close the read end of the pipe ("ls" isn't reading from anywhere)*/ | |
close(pfd[0]); | |
/*next we need to redirect the STDOUT of "ls" to go to the pipe instead of going to the screen (default)*/ | |
dup2(pfd[1], STDOUT); //dup2 is like mapping signals, here we are mapping stdout to pfd[1] (the ls) | |
/*now we must release the pipe, it is already bound with STDOUT --> why? Because child will | |
*soon be overwritten when execlp is called!*/ | |
close(pfd[1]);//must close after you do the dup2() | |
/*Before calling exec* make sure to have closed both ends of pfd (i.e. close(fd[0]),close(fd[1])), and file descriptors*/ | |
execlp("ls","ls",NULL); | |
} | |
else | |
{ | |
/*We are in the parent process*/ | |
/*Now, we should wait for all the data to be written to the pipe*/ | |
waitpid(pid[0], &status, WUNTRACED | WCONTINUED); //wait(NULL) is also okay here | |
/*Need to fork again for "wc"*/ | |
pid[1] = fork(); | |
/*check if the pid returned from fork is 0 (for the child), or > 0 (for the parent)*/ | |
if(pid[1] == 0) | |
{ | |
/*we're now in our 2nd child process for "wc"*/ | |
close(pfd[1]); | |
/*next we need to redirect the STDIN of "wc" to come from the pipe instead of the keyboard (default)*/ | |
dup2(pfd[0], STDIN); //mapping STDIN to pfd[0] | |
/*now we must release the pipe, it is already bound with STDIN --> why? Because child will | |
*soon be overwritten when execlp is called!*/ | |
close(pfd[0]); | |
/*Now lets redirect the output of "wc" to a file called "outfile"*/ | |
int fildes = open("outfile", O_WRONLY|O_CREAT, 0666); | |
/*Again, redirect STDOUT, but this time to the file descriptor*/ | |
dup2(fildes,STDOUT); /* copy fildes to 1 */ | |
/*And again, before calling execlp, release this resource*/ | |
close(fildes); /* conserve file descriptors by closing excess one */ | |
/*Before calling exec* make sure to have closed both ends of pfd (i.e. close(fd[0]),close(fd[1])), and another file descriptors*/ | |
execlp("wc","wc","-l",NULL); | |
} | |
else | |
{ | |
/*Also, the parent needs to release the pipe, otherwise you'll face troubles!*/ | |
close(pfd[0]); | |
close(pfd[1]); | |
/*Now wait until the second process has finished*/ | |
waitpid(pid[1], &status, WUNTRACED | WCONTINUED); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment