Some History of the Named Pipe, Part 1

Let’s start with the more ancient history and work over a few steps towards what pipes look like today. Pipes started out as inter-process communication mechanisms that provide a one-way flow of data.

The standard Unix pipe is created by the pipe system call int pipe (int*). The pointer parameter is really an array to which the pipe system call will write a pair of file descriptors for reading and writing from the pipe. Thus, you’re more likely to see the pipe system call written these days as int pipe(int[2]).

These pipes are anonymous pipes as their only representation is a file descriptor, which is a non-significant integer value that’s not portable between processes. The pipe will already be opened upon creation so the interesting operations to do with it are to read, write, or close the pipe.

This might lead to the question of how a pipe actually gets used for inter-process communication if the pipe has no name and there’s no way to open it from another process. The only way a file descriptor gets copied around is when a process is forked to create a child process. After calling fork(), both the parent and child process initially have the same file descriptors, effectively replicating the endpoints of the pipe elsewhere. One of the processes can then use the read file descriptor while the other process uses the write file descriptor. For example, you might build bidirectional communication between a client and server with the following approach:

1.
Create two pipes
2.
Call fork()
3.
Child closes the read side of one of the pipes and the write side of the other pipe
4.
Parent closes the opposite side of each pipes
5.
The two processes can then exchange one-way messages using the sides of the pipe that are still open

These anonymous pipes are the fundamental building block of the pipeline for commands. The basic composition for running commands is to sequentially pipe data from one command to another. The command processor takes care of the step of creating the pipes and wiring them up to be the input and output of various commands in the pipeline.

Anonymous pipes are all well and good but it’s a big hindrance that they only work between two related processes. This spurred the creation of another inter-process communication mechanism that we’ll talk about next time.