Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unix C pipe Question

Tags:

c

unix

pipe

I'm trying to understand the usage of pipe.

A parent process will pipe and if the parent forks, the child process will inherit the pipe. So now we hae a direct link to the child process and they can communicate?

I get lost when we start to close pipes and redirect pipes. Does anyone have a good explanation on closing pipes and redirecting pipes?

Thank you in-advance.

like image 554
RoR Avatar asked Dec 07 '22 01:12

RoR


2 Answers

Here's the deal.

  1. A pipe is a software abstraction, that has two ends, each one a fd. Whatever you write on at one end (write fd), you can read off the other end (read fd).
  2. The trick in using a pipe is that you switch the stdin of some process with the read fd of the pipe. Now, you can write to the write fd of the pipe, and when the other process reads what he thinks is his stdin, he actually reads the read fd of the pipe (and gets your data).
  3. For two way communication, you can get another pipe, and switch the stdout of the process with the write fd of the pipe. Now, whatever the process writes to its stdout, you can read off the read fd of the pipe.

Here is what it looks like:

P1=[WR FD]===========[RD FD]=[STDIN]=P2
P1=[RD FD]===========[WR FD]=[STDOUT]=P2

P1 and P2 are processes. And "===" depict the pipes.

Your question was specifically about closing and redirecting. That comes into play when you perform the switch I referred to earlier. Let's say you have obtained a pipe by using the pipe() system call.

int fd[2];
pipe(fd);

Now you create a child process, and in that process perform the switch, like so:

if (!fork()) // 0 return value indicates that you are in the child process
{
    dup2(fd[0], 0); // dup2 first closes 0 in the child process, then duplicates
                    // fd[0] as 0; keep in mind that 0 is stdin and fd[0] is the
                    // read end of the pipe

    exec(something); // start the new process, which when it reads stdin, will be
                     // reading the pipe instead
}
like image 196
Ziffusion Avatar answered Dec 11 '22 08:12

Ziffusion


See Pipeline.

Simple example

ls -l | less

In this example, ls is the Unix directory lister, and less is an interactive text pager with searching capabilities. The pipeline lets the user scroll up and down a directory listing that may not fit on the screen.

Creating pipelines programmatically

Pipelines can be created under program control. The Unix pipe() system call asks the operating system to construct a new anonymous pipe object. This results in two new, opened file descriptors in the process: the read-only end of the pipe, and the write-only end. The pipe ends appear to be normal, anonymous file descriptors, except that they have no ability to seek.

To avoid deadlock and exploit parallelism, the Unix process with one or more new pipes will then, generally, call fork() to create new processes. Each process will then close the end(s) of the pipe that it will not be using before producing or consuming any data.

alt text

like image 42
Eugene Yokota Avatar answered Dec 11 '22 09:12

Eugene Yokota