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.
int
pipe (int filedes[2]
)
¶Preliminary: | MT-Safe | AS-Safe | AC-Safe fd | See POSIX Safety Concepts.
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 descriptor 1
is
standard output.
If successful, pipe
returns a value of 0
. On failure,
-1
is returned. The following errno
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 on
GNU/Hurd systems.
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; } }