Online Labs

Pipes

A pipe is a method of connecting the standard output of one process to the standard input of another. Pipes are the eldest of the IPC tools, having been around since the earliest incarnations of the UNIX operating system. They provide a method of one-way communications (hence the term half-duplex) between processes.

This feature is widely used, even on the UNIX command line (in the shell).

When a process creates a pipe, the kernel sets up two file descriptors for use by the pipe. One descriptor is used to allow a path of input into the pipe (write), while the other is used to obtain data from the pipe (read). At this point, the pipe is of little practical use, as the creating process can only use the pipe to communicate with itself.

While a pipe initially connects a process to itself, data traveling through the pipe moves through the kernel. Under Linux, in particular, pipes are actually represented internally with a valid inode. Of course, this inode resides within the kernel itself, and not within the bounds of any physical file system. This particular point will open up some pretty handy I/O doors for us, as we will see a bit later on.

At this point, the creating process typically forks a child process. Since a child process will inherit any open file descriptors from the parent, we now have the basis for multiprocess communication (between parent and child). It is at this stage, that a critical decision must be made. In which direction do we desire data to travel? Does the child process send information to the parent, or vice-versa? The two processes mutually agree on this issue, and proceed to “close” the end of the pipe that they are not concerned with.

To access a pipe directly, the same system calls that are used for low-level file I/O can be used (recall that pipes are actually represented internally as a valid inode).

To send data to the pipe, we use the write() system call, and to retrieve data from the pipe, we use the read() system call. Remember, low-level file I/O system calls work with file descriptors! However, keep in mind that certain system calls, such as lseek(), do not work with descriptors to pipes.

To create a simple pipe with C, we make use of the pipe() system call. It takes a single argument, which is an array of two integers, and if successful, the array will contain two new file descriptors to be used for the pipeline.

System Call: pipe();   

Prototype; int pipe(int fd[2]);  

                                                                              

RETURNS: 0 on success                                                                                           -1 on error: errno = EMFILE (no free descriptors)                 

                                EMFILE (system file table is full)           

                                EFAULT (fd array is not valid)               

 

  NOTES: fd[0] is set up for reading, fd[1] is set up for writing

                The popen() function creates a pipe between the calling program  and  the  command  to  be  executed.  The arguments topopen() are pointers to null-terminated strings.   The  com-mand  argument  consists  of a shell command line.  The modeargument is an I/O mode, either r for reading or w for writing.  The  value  returned is a stream pointer such that one can write to the standard input of the command, if  the  I/Omode is w, by writing to the file stream  and one can read from the standard output of the command, if the I/O mode is r, by reading from the file stream.

                The pclose() function closes a stream opened by  popen() by closing the  pipe.  It  waits for the associated process to terminate and returns the termination status of the  process running  the command language interpreter. This is the value returned by waitpid(2).

 Simple Pipes or Lowlevel Pipes

 Program

 /* Program to demonstrate the creation and use of simple/low level pipe.

* This program creates a pipe that connects the child process with its parent process.

* Here the child process writes ‘REQUEST FROM CHILD PROCESS.’ on to the pipe  

    which is read by the parent process.

* The function ‘fork()’ is a system call used to create a child process.

* This module can be compiled using ‘cc simplepipe.c’ and executed using ‘./a.out’

 //inculsion

#include<stdio.h>

#include<sys/types.h>

 int main()

{

             //array to store the pipe pointers returned by the pipe() function.

 int pipe_pointer[2];

                        //variable to store the child process id.

 pid_t child;

 char message[50];

                        //creating a pipe

 pipe(pipe_pointer);

                        //creating a child process.

 child=fork();

  if(child==0)

 {

  printf(“\nThe child process is writing.\n”);

                        //closing the read pointer.

  close(pipe_pointer[0]);

                        //writing on to the pipe.

  write(pipe_pointer[1],”REQUEST FROM CHILD PROCESS.”,sizeof(“REQUEST FROM CHILD PROCESS.”));

 }

 else

 {

  printf(“\nThe parent process is reading.\n”);

                         //closing the write pointer.

  close(pipe_pointer[1]);

                        //reading from the pipe.

  read(pipe_pointer[0],message,sizeof(message));

   printf(“\nThe parent has read:\n\n** %s **\n”,message);

 }

  close(pipe_pointer[0]);

 close(pipe_pointer[1]);

}

 Output

18

 

 

 

 

 

 

 

Formatted Pipe

Output

/* Program to demonstrate the creation and use of formatted pipe.

*  This program creates a formatted pipe which is connected to the system process  

    denoted by the command ‘CMD’.

*  The pipe is established for reading and the read content is displayed.

*  This module can be compiled using ‘cc formattedpipe.c’ and executed ‘./a.out’.*/

                                     //inculsion part

#include<stdio.h>

#include<string.h>

 

#define CMD “cal”

 int main()

{

 FILE *ptr;

 char message[100];

 char cmd[20];

  strcpy(cmd,CMD);

                                    //creating a formatted pipe.

 ptr=popen(cmd,”r”);

  while( fgets(message,sizeof(message),ptr)!=NULL)

 {

  printf(“%s”,message);   

 }

                                    //closing the pipe.

 pclose(ptr);

}

 Output


26

 

 

 

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: