ls | less


In section 2.2, we see how pipe works for communication between parent and child processes. A familiar example of this kind of communication can be seen in all operating system shells.

pipe4.c implements shell command "ls | less" in C.

/* pipe4.c */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int agrc, char* agrv[])
{
  int pipefds[2];
    pid_t pid;
  if(pipe(pipefds) == -1){
    perror("pipe");
    exit(EXIT_FAILURE);
  }
  pid = fork();
  if(pid == -1){
    perror("fork");
    exit(EXIT_FAILURE);
  }
  if(pid == 0){
  //replace stdout with the write end of the pipe
    dup2(pipefds[1],STDOUT_FILENO);  
  //close read to pipe, in child    
    close(pipefds[0]);               
    execlp("ls","ls",NULL);
    exit(EXIT_SUCCESS);
  }else{
  //Replace stdin with the read end of the pipe
        dup2(pipefds[0],STDIN_FILENO);  
  //close write to pipe, in parent
        close(pipefds[1]);               
        execlp("less","less",NULL);
        exit(EXIT_SUCCESS);
    }   
}

The result of pipe4.c is the same with ls | less

Analysis: The parent uses the pipe for ls output. That means it needs to change its standard output file descriptor to the writing end of the pipe. It does this via dup2 system call and then executes ls. The child will use the pipe for less input. It changes its standard input file descriptor to the reading end of pipe by dup2(pfd[0], 0). Then child executes less and the result is send to standard output. Thus the output of ls flows into the pipe, and the input of less flows in from the pipe. This is how we connect the standard output of ls to the standard input of less.