C Tutorial: Pipes
How to use a pipe
A pipe is a system call that creates a unidirectional communication link between two file descriptors. The pipe system call is called with a pointer to an array of two integers. Upon return, the first element of the array contains the file descriptor that corresponds to the output of the pipe (stuff to be read). The second element of the array contains the file descriptor that corresponds to the input of the pipe (the place where you write stuff). Whatever bytes are sent into the input of the pipe can be read from the other end of the pipe.
Example
This is a small program that gives an example of how a pipe works. The array of two file
descriptors is fd[2]
. Whatever is written to fd[1]
will be read
from fd[0]
.
Save this file by control-clicking or right clicking the download link and then saving it as pipe-simple.c.
Compile this program via:
If you don't have gcc, You may need to substitute the gcc command with cc or another name of your compiler.
Run the program:
Pipes between processes
This next example shows the true value of a pipe. We create a pipe between the "/bin/ls -al /" command and the "/usr/bin/tr a-z A-Z" command. This is the equivalent of running the shell command:
/bin/ls -al / | /usr/bin/tr a-z A-Z
The first command generates a long-format directory listing of the root (/
) directory and the
second command takes that listing and translates all lowercase characters to uppercase.
We start off by creating a pipe. Then we fork a child process.
The parent will use the pipe for command output. That means it needs to change its standard output
file descriptor (1) to the writing end of the pipe (pfd[1]
). It does this via the dup2
system call: dup2(pfd[1], 1)
. Then it executes the command in cmd1
.
The child will use the pipe for command input. It needs to change its standard input
file descriptor (0) to the reading end of the pipe (pfd[0]
). It also does this via the dup2
system call: dup2(pfd[0], 0)
. Then it executes the command in cmd2
.
Save this file by control-clicking or right clicking the download link and then saving it as pipe-exec.c.
Compile this program via:
If you don't have gcc, You may need to substitute the gcc command with cc or another name of your compiler.
Run the program:
Creating a pipe between two child processes
The above example put the parent process into a state where it gave up its standard output to the pipe and
the process itself was replaced by the exec of cmd1
. If we want to preserve the parent program and
its input and output streams but run the pipe between two child processes, we need to fork off two children.
The child that generates output will set its standard output to the writing end of the pipe and
the child that consumes that data will set its standard input to the reading end of the same pipe.
Once this is done the parent no longer needs the pipe and can close its file descriptors.
This is important! If the parent does not close the writing end of the pipe (pfd[1]
)
then the child that is reading from the pipe will never read an end of file and will never exit.
Save this file by control-clicking or right clicking the download link and then saving it as pipedemo.c.
Compile this program via:
If you don't have gcc, You may need to substitute the gcc command with cc or another name of your compiler.
Run the program: