Linux provides many ways for processes to communicate with each other. One of them is using pipes.
Like a pipe that carries water in which water enters from one end and exits from the other, in linux pipes data enters from one end and exits from the other.
Pipes are created using the system call pipe() and the system calls read() and write() are used to read and write from the pipe. The c library in linux provides wrappers around these system calls which make their use much easier.
The function popen() is a wrapper for pipe, which allows us to create a pipe and read or write from it using c fuctions like fprintf,fscanf etc
Arguments : 1. command that will be executed by the child process.
2. The type of communication by the parent, i.e. whether the parent is going to read from the pipe or write into the pipe.
Return : It returns a file descriptor that gets created as a result of th call to the pipe.
The open() system call creates a pipe and returns two file descriptors, one that can be used to read from the pipe and one that can be used to write into the pipe. This can be visualized as follows
The popen function which recives these two descriptors decides the next step based on whether the process requested for a read or write operation from the pipe. That is the whether the second arguement to the pipe was "r" or "w"
If the second argument was "r" that is the process is going to read from the pipe then the write file descriptor is changed to that of the standard output. Which means when the output of "command", which was passed as the first argument to open, instead of being printed on the standard output will now be sent into the pipe, which can be later read by using fscanf .
Thus the child is able to send data through the pipe to the parent process, achieveing the commnicatio between processes.
Here is a example that shows how to open a pipe in read mode
The above program opens the pipe in read mode, hence the process is going to read from the pipe, and write to the other end of the pipe which will be the standard output as exaplined above.
The command that the child process is going to execute is "echo hello world" which will be read by the parent process . The popen() returns a file descriptor which can be used to read from the pipe using the function fscanf() ,which reads from a file.
Thus we run a while loop till the end of file is reached and keep reading the contents of the file into a string, which is turn is printed on to the
standard output to see what was the string read from the pipe.
compile the code using the gcc compiler as shown below
The command "echo hello world" wrote "hello world" into the pipe, the same was read out using the file descriptor returned by popen.
If second argument was "w" that is the process is going to write into the pipe then the read file descriptor is changed to standard input.
Which means what ever we write into the pipe will act as an input to the command that was passed in the first argument to popen.
Thus the parent is able to send data to the child through the pipe, achieveing the commnicatio between processes.
Here is a example that shows how to open a pipe in write mode
The above program opens the pipe in write mode. The command that the child is executing is "wc -c" which counts the number of characters in the input file passed to it. As the pipe has been opened in write mode, that is the parent is going to write into the pipe, the child will read the data that the parent wrties. Hence what ever is printed into the file, using the file descriptor returned by popen() will be passed to "wc -w" as input which will count the number of characters and give the output on the standard output.
save the file as pipe_write.c. Compile it using gcc and execute is as follows.
There are 11 characters in the string "hello world" including the blank space, hence we see the output 11.