Piping with popen

Last edit

Added: 15a16

> This example writes lines to the ''wc'' (word count) utility.

Added: 47a49,59

> To read the output of a program, use something like the following snippet:
> FILE *ls = popen("/bin/ls -l /","r");
> char str[300];
> int ret=0;
> memset((void *)str,0,sizeof(str));
> if(ls != NULL) {
> fflush(ls);
> ret+=fread((void *)&str[ret],sizeof(char),sizeof(str),ls);
> printf("%s\n",str);
> pclose(ls);
> }


Easy piping with popen()

Problem: I want to execute a command and write to its standard input. Or: I want to execute a command and read from its standard output.

Solution: Create a pipe with popen()

Syntax:

  FILE *popen ( char *command, char *type);

Here we are using the easy way with popen(). It forks off a process, executes the shell and runs the program specified by the parameter char *command. Then a pipe is created between your process and the one just created by popen(). The parameter char *type makes the pipe either a write or a read pipe. And just like a stream opened with fopen() you use scanf() and printf() to get your data through the pipe.

Note that with popen() you have the functionality of the shell at your disposal, like file expansion characters (wildcards) but also redirection.

Examples of popen() calls

 popen("ls /home","r");             /* read the current directory
                                       into your process */
 popen("sort > ./output","w");      /* sort some output generated by
                                       your process and write it to the
                                       file output */

Example of a program using popen()

This example writes lines to the wc (word count) utility.

  #include <stdio.h>
  
  #define MAXSTRS 5
  
  main()
  {
        int  cntr;
        FILE* fp_pipe;                             /* filepointer for the pipe */
        char* psz_pipe_input[MAXSTRS] =        /* some strings to use as input */
              {"one", "two", "three", "four", "five"};
  
        /* Create one way pipe line with call to popen() */
        /* The UNIX utility "wc -w" is a WordCounter... */
        fp_pipe = popen("wc -w", "w");
        if ( fp_pipe == NULL ) {
              printf("popen error!");
              exit(1);
        }
  
        /* This loop throws those strings in the pipe to wc*/
        for(cntr=0; cntr<MAXSTRS; cntr++) {
              fprintf(pipe_fp, strings[cntr]);
              fputc(' ', pipe_fp);
        }
  
        if (pclose(pipe_fp)==-1) {
              printf("pclose error!");
              exit(1);
        }
          
        return(0);
  }

To read the output of a program, use something like the following snippet:

    FILE *ls = popen("/bin/ls -l /","r");
    char str[300];
    int ret=0;
    memset((void *)str,0,sizeof(str));
    if(ls != NULL) {
        fflush(ls);
        ret+=fread((void *)&str[ret],sizeof(char),sizeof(str),ls);
        printf("%s\n",str);
        pclose(ls);
    }