CodeBlanks Logo Icon CodeBlanks

Pipe

Learn unidirectional data flow between processes with pipe.

What is a pipe?

A pipe is an anonymous channel providing unidirectional data flow between related processes. The pipe(int fds[2]) call returns two file descriptors: fds[0] for reading and fds[1] for writing.

The typical pattern is: first create the channel with pipe, then produce a child with fork. The parent uses the write end, the child the read end; they close the ends they do not use with close. Data then flows with write and read. Pipes are buffered; write blocks until a reader is attached.

Sharing a pipe with fork

The fork call gives the child a copy of the parent's descriptor table. So both processes hold both pipe ends. To keep the channel unidirectional, the parent closes the read end, the child closes the write end.

The parent writes with write(fds[1], "merhaba", 7), the child reads with read(fds[0], buf, 7). read blocks until data arrives, so output ordering is guaranteed. When done, both sides close the remaining end; the parent reaps the child with wait.

Practice Send a message through a pipe

Set up the channel with int fds[2]; pipe(fds);. Fork a child with pid_t pid = fork();. In the child: close(fds[1]);, char buf[16]; memset(buf, 0, sizeof(buf));, read(fds[0], buf, 7);, printf("%s\n", buf);, close(fds[0]); _exit(0);. In the parent: close(fds[0]);, write(fds[1], "merhaba", 7);, close(fds[1]);, wait(NULL);.

Starter code

main.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

// Set up channel with pipe
// Fork a child to read
// Parent writes and waits

int main(void) {
    return 0;
}

Sample solution

main.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

int main(void) {
    int fds[2];
    pipe(fds);
    pid_t pid = fork();
    if (pid == 0) {
        close(fds[1]);
        char buf[16];
        memset(buf, 0, sizeof(buf));
        read(fds[0], buf, 7);
        printf("%s\n", buf);
        close(fds[0]);
        _exit(0);
    }
    close(fds[0]);
    write(fds[1], "merhaba", 7);
    close(fds[1]);
    wait(NULL);
    return 0;
}

Expected output

merhaba

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 After pipe(fds), what is fds[0] used for?

  • Error code
  • Write end
  • Read end Correct answer
  • Process id

Explanation: fds[0] is the read end, fds[1] is the write end.

2 pipe call

Question
int fds[2]; pipe(____);
Answer
int fds[2]; pipe(fds);

Explanation: pipe takes the address of fds and fills both ends.

3 Match pipe parts

Term Meaning
pipe Creates channel
fork Splits process
fds[0] Read end
fds[1] Write end

All lessons in Advanced