pipe() — Create an unnamed pipe

Standards

Standards / Extensions C or C++ Dependencies

POSIX.1
XPG4
XPG4.2
Single UNIX Specification, Version 3

both  

Format

#define _POSIX_SOURCE
#include <unistd.h>

int pipe(int fdinfo[2]);

General description

Creates a pipe, an I/O channel that a process can use to communicate with another process (in the same process or another process), or in some cases with itself. Data is written into one end of the pipe and read from the other. fdinfo[2] points to a memory area where pipe() can store two file descriptors. pipe() stores a file descriptor for the input end of the pipe in fdinfo[1], and stores a file descriptor for the output end of the pipe in fdinfo[0]. Thus, processes can read from fdinfo[0] and write to fdinfo[1]. Data written to fdinfo[1] is read from fdinfo[0] on a first-in-first-out (FIFO) basis.

When pipe() creates a pipe, the O_NONBLOCK and FD_CLOEXEC flags are turned off on both ends of the pipe. You can turn these flags on with fcntl(). See fcntl() — Control open file descriptors for details.

If pipe() successfully creates a pipe, it updates the access, change, and modification times for the pipe.

It is unspecified whether fdinfo[0] is also open for writing and whether fdinfo[1] is also open for reading. z/OS® UNIX pipes are not STREAMS-based.

Returned value

If successful, pipe() returns 0.

If unsuccessful, pipe() returns -1 and sets errno to one of the following values:
Error Code
Description
EMFILE
Opening the pipe would exceed the limit on the number of file descriptors the process can have open. This limit is given by OPEN_MAX, defined in the limits.h header file.
ENFILE
Opening the pipe would exceed the number of files that the system can have open simultaneously.
ENOMEM
Opening the pipe requires more space than is available.

Example

CELEBP04
⁄* CELEBP04

   This example creates an I⁄O channel.
   The output shows the data written into one end and read from
   the other.

 *⁄
#define _POSIX_SOURCE
#include <unistd.h>
#include <stdio.h>

void reverse(char *s) {
  char *first, *last, temp;

  first = s;
  last = s+strlen(s)-1;
  while (first != last) {
    temp = *first;
    *(first++) = *last;
    *(last--) = temp;
  }
}

main() {
  char original[]="This is the original string";
  char buf[80];
  int  p1[2], p2[2];

  if (pipe(p1) != 0)
    perror("first pipe() failed");
  else if (pipe(p2) != 0)
    perror("second pipe() failed");
  else if (fork() == 0) {
    close(p1[1]);
    close(p2[0]);
    if (read(p1[0], buf, sizeof(buf)) == -1)
      perror("read() error in parent");
    else {
      reverse(buf);
      if (write(p2[1], buf, strlen(buf)+1) == -1)
        perror("write() error in child");
    }
    exit(0);
  }
  else {
    close(p1[0]);
    close(p2[1]);
    printf("parent is writing '%s' to pipe 1\n", original);
    if (write(p1[1], original, strlen(original)+1) == -1)
      perror("write() error in parent");
    else if (read(p2[0], buf, sizeof(buf)) == -1)
      perror("read() error in parent");
    else printf("parent read '%s' from pipe 2\n", buf);
  }
}
Output:
parent is writing 'This is the original string' to pipe 1
parent read 'gnirts lanigiro eht si sihT' from pipe 2

Related information