The primitive for creating a pipe is the pipe
function. This
creates both the reading and writing ends of the pipe. It is not very
useful for a single process to use a pipe to talk to itself. In typical
use, a process creates a pipe just before it forks one or more child
processes (see Creating a Process). The pipe is then used for
communication either between the parent or child processes, or between
two sibling processes.
The pipe
function is declared in the header file
unistd.h.
The
pipe
function creates a pipe and puts the file descriptors for the reading and writing ends of the pipe (respectively) into filedes[0]
and filedes[1]
.An easy way to remember that the input end comes first is that file descriptor
0
is standard input, and file descriptor1
is standard output.If successful,
pipe
returns a value of0
. On failure,-1
is returned. The followingerrno
error conditions are defined for this function:
EMFILE
- The process has too many files open.
ENFILE
- There are too many open files in the entire system. See Error Codes, for more information about
ENFILE
. This error never occurs in the GNU system.
Here is an example of a simple program that creates a pipe. This program
uses the fork
function (see Creating a Process) to create
a child process. The parent process writes data to the pipe, which is
read by the child process.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/* Read characters from the pipe and echo them to stdout
. */
void
read_from_pipe (int file)
{
FILE *stream;
int c;
stream = fdopen (file, "r");
while ((c = fgetc (stream)) != EOF)
putchar (c);
fclose (stream);
}
/* Write some random text to the pipe. */
void
write_to_pipe (int file)
{
FILE *stream;
stream = fdopen (file, "w");
fprintf (stream, "hello, world!\n");
fprintf (stream, "goodbye, world!\n");
fclose (stream);
}
int
main (void)
{
pid_t pid;
int mypipe[2];
/* Create the pipe. */
if (pipe (mypipe))
{
fprintf (stderr, "Pipe failed.\n");
return EXIT_FAILURE;
}
/* Create the child process. */
pid = fork ();
if (pid == (pid_t) 0)
{
/* This is the child process.
Close other end first. */
close (mypipe[1]);
read_from_pipe (mypipe[0]);
return EXIT_SUCCESS;
}
else if (pid < (pid_t) 0)
{
/* The fork failed. */
fprintf (stderr, "Fork failed.\n");
return EXIT_FAILURE;
}
else
{
/* This is the parent process.
Close other end first. */
close (mypipe[0]);
write_to_pipe (mypipe[1]);
return EXIT_SUCCESS;
}
}