Fork, Exec, and Pipe in C | Learning Programming
Let’s start by creating a new pipe using pipe
int pipefd[2];
pipe(pipefd);
pipe takes 1 argument, an integer array with a size of 2. This creates a read and a write pipe 0 being read, and 1 being write.
Now we want to fork, so we have a child and a parent. The parent in this case is the real program, and the child is just temporarily there so we can call execlp. Speaking of which let’s do that
if(fork() == 0)
{
close(pipefd[0]); // close read dup2(pipefd[1], 1); // set stdout to write
//dup2(pipefd[1], 2); // set stderr to write close(pipefd[1]); // we are done modifying it so close it
execlp("ls", "ls", NULL); // call command
}
To start we close the reading part of the pipe because we won’t be using it in the child. Then we use dup2 which duplicates a file descriptor. We put pipefd[1], and 1 because we want our output to be output to the pipe. Then we close the write part of the pipe. Now we can finally call execlp. This takes a command as the first argument and then lists the command again and then all it’s arguments as the rest of the arguments, and it always ends with NULL so the function can tell we are done passing arguments to it! So if we wanted to use the -l flag on ls we would do this:
execlp("ls", "ls", "-l", NULL); // call command
If there are no arguments just use NULL as in the first example. Now let’s handle the parent’s side of things.
else
{
// parent
char *bigbuf = calloc(100000, sizeof(char)); // bigger buff
char *buffer= calloc(1000, sizeof(char)); // buffer close(pipefd[1]); // close write, don't need it while(read(pipefd[0], buffer, 1000) != 0)
{
strncpy(bigbuf, buffer, strlen(buffer));
}
printf("%s", bigbuf); close(pipefd[0]); // we are done with this pipe
}
First we create two buffers one that holds all the string information we are going to print at the end, we will call this string bigbuf. Second we create a buffer for each time we read a chunk of information from the child’s stdout which we will call buffer. We can close the write part of the pipe because it’s already setup because we did that in the child. Then we loop through using read to read all the information from the pipe file descriptors. We use pipefd[0] because it is the reading side of the pipe. We copy the characters from buffer to bigbuf, and then after the loop ends we just print bigbuf. Once that’s all done we can close the other part of the pipe and we are done! Here is a picture of the total source code:

Please not this code has an error execlp should look like this:
execlp("ls", "ls", "-l", NULL);