0
0
CHow-ToBeginner · 3 min read

How to Use Pipe in C: Syntax and Example

In C, you use the pipe() system call to create a unidirectional communication channel between processes. It creates two file descriptors: one for reading and one for writing. You can then use fork() to create a child process and communicate through the pipe.
📐

Syntax

The pipe() function creates a pipe and fills an array with two file descriptors. The first descriptor is for reading, and the second is for writing.

  • int pipefd[2]; declares an array to hold the descriptors.
  • pipe(pipefd); creates the pipe.
  • pipefd[0] is the read end.
  • pipefd[1] is the write end.
c
int pipefd[2];
int result = pipe(pipefd);
// pipefd[0] is read end
// pipefd[1] is write end
💻

Example

This example shows how a parent process sends a message to its child process using a pipe.

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

int main() {
    int pipefd[2];
    char buf[30];
    if (pipe(pipefd) == -1) {
        perror("pipe");
        return 1;
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        return 1;
    }

    if (pid == 0) { // child process
        close(pipefd[1]); // close write end
        read(pipefd[0], buf, sizeof(buf));
        printf("Child received: %s\n", buf);
        close(pipefd[0]);
    } else { // parent process
        close(pipefd[0]); // close read end
        char message[] = "Hello from parent";
        write(pipefd[1], message, strlen(message) + 1);
        close(pipefd[1]);
        wait(NULL); // wait for child
    }
    return 0;
}
Output
Child received: Hello from parent
⚠️

Common Pitfalls

  • Not closing unused pipe ends in parent or child can cause deadlocks.
  • Forgetting to add +1 to strlen() when writing strings causes missing null terminator.
  • Reading or writing more bytes than the pipe buffer can hold may block the process.
  • Not checking the return value of pipe() or fork() can lead to errors.
c
/* Wrong: Not closing unused ends */
pipe(pipefd);
pid = fork();
if (pid == 0) {
    // child reads but does not close write end
    read(pipefd[0], buf, sizeof(buf));
}
// Correct:
if (pid == 0) {
    close(pipefd[1]); // close write end in child
    read(pipefd[0], buf, sizeof(buf));
}
📊

Quick Reference

Remember these key points when using pipes in C:

  • pipe() creates two file descriptors: read and write ends.
  • Use fork() to create child processes that share the pipe.
  • Always close unused ends of the pipe in each process.
  • Use read() and write() to communicate.
  • Check return values for errors.

Key Takeaways

Use pipe() to create a communication channel with two file descriptors: read and write ends.
After fork(), close unused pipe ends in parent and child to avoid deadlocks.
Use read() and write() to send data through the pipe between processes.
Always check the return values of pipe() and fork() for errors.
Remember to include the null terminator when writing strings through the pipe.