### 15.2 Pipe to a Subprocess ¶

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.

Function: `FILE *` popen `(const char *command, const char *mode)` ¶

  Preliminary: | MT-Safe | AS-Unsafe heap corrupt | AC-Unsafe corrupt lock fd mem | See POSIX Safety Concepts.

  The `popen` function is closely related to the `system` 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.

Function: `int` pclose `(FILE *stream)` ¶

  Preliminary: | MT-Safe | AS-Unsafe heap plugin corrupt lock | AC-Unsafe corrupt lock fd mem | See POSIX Safety Concepts.

  The `pclose` function is used to close a stream created by `popen`. It waits for the child process to terminate and returns its status value, as for the `system` 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;
    }