Fork, Exec, and Pipe in C | Learning Programming

Mark Bailey
2 min readNov 11, 2022

--

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);

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Mark Bailey
Mark Bailey

Responses (1)

Write a response