Next: FIFO Special Files, Previous: Creating a Pipe, Up: Pipes and FIFOs
A common use of pipes is to send data to or receive data from a program
being run as a subprocess. One way of doing this is by using a combination of
pipe
(to create the pipe), fork
(to create the subprocess),
dup2
(to force the subprocess to use the pipe as its standard input
or output channel), and exec
(to execute the new program). Or,
you can use popen
and pclose
.
The advantage of using popen
and pclose
is that the
interface is much simpler and easier to use. But it doesn't offer as
much flexibility as using the low-level functions directly.
The
popen
function is closely related to thesystem
function; see Running a Command. It executes the shell command command as a subprocess. However, instead of waiting for the command to complete, it creates a pipe to the subprocess and returns a stream that corresponds to that pipe.If you specify a mode argument of
"r"
, you can read from the stream to retrieve data from the standard output channel of the subprocess. The subprocess inherits its standard input channel from the parent process.Similarly, if you specify a mode argument of
"w"
, you can write to the stream to send data to the standard input channel of the subprocess. The subprocess inherits its standard output channel from the parent process.In the event of an error
popen
returns a null pointer. This might happen if the pipe or stream cannot be created, if the subprocess cannot be forked, or if the program cannot be executed.
The
pclose
function is used to close a stream created bypopen
. It waits for the child process to terminate and returns its status value, as for thesystem
function.
Here is an example showing how to use popen
and pclose
to
filter output through another program, in this case the paging program
more
.
#include <stdio.h> #include <stdlib.h> void write_data (FILE * stream) { int i; for (i = 0; i < 100; i++) fprintf (stream, "%d\n", i); if (ferror (stream)) { fprintf (stderr, "Output to stream failed.\n"); exit (EXIT_FAILURE); } } int main (void) { FILE *output; output = popen ("more", "w"); if (!output) { fprintf (stderr, "incorrect parameters or too many files.\n"); return EXIT_FAILURE; } write_data (output); if (pclose (output) != 0) { fprintf (stderr, "Could not run more or other error.\n"); } return EXIT_SUCCESS; }