Saturday, August 4, 2018

Notes on UNIX Pipes

  • A pipe call creates two file descriptors - read and a write
  • $ ls -l|more if write from ls is too much to handle by more, the write waits till read drains it.
  • If there is nothing to read, the pipe read waits.
  • Pipe is a kernel resource and is basically just a buffer.
  • A write to a read-closed pipe or vice-versa would not work. We get a SIGPIPE.
  • lseek( ) does not work on unidirectional pipes.

How shell commands piping work?

  • A process has its own local file descriptor table. This table keeps track of files opned by the process and their FDs.
    Using dup() system call, we can create a new entry in the process FDT as following:
FD filename
10 /tmp/xx

After calling dup(), we get a new entry with a new FD.

FD Filename
10 /tmp/xx
11 /tmp/xx

Both the entries map to same slot in the global file table. It is equivalent to a file softlink. Now, we can close the fd 10 and use fd 11 to continue ops or keep both of them open.

dup() returns the lowest available FD in the process. To exploit this fact, we can close standard FDs (0,1,2) and the next call to dup() would return these FDs.

int fd[2];
int p = pipe(fd);
close(1); // frees up fd 0
dup(fd[1]);
// dup will return the lowest available FD, one for fd[1]. 
FD File name
10 /tmp/xx
1 /tmp/xx

Now any write that was supposed to go to FD 1, would go to file /tmp/xx

Written with StackEdit.

No comments:

Post a Comment