Tuesday, November 11, 2014

Unix Prog: popen, pclose(1)

1. popen pclose
System Definition
 ubuntu@ip-172-31-23-227:~$ less /usr/include/stdio.h  
 ......  
 /* Create a new stream connected to a pipe running the given command.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern FILE *popen (const char *__command, const char *__modes) __wur;  
   
 /* Close a stream opened by popen and return the status of its child.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int pclose (FILE *__stream);  
 ......  

The function popen does a fork and exec to execute the cmdstring, and returns a standard I/O file pointer. If type is "r", the file pointer is connected to the standard output of cmdstring.


If the type is "w", the file pointer is connected to the standard input of cmd string.


The cmd string will be executed by bourne shell which is:
sh -c cmdstring

2. Example:
pipe.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<sys/wait.h>  
   
 #define PAGER "/bin/more" // environment variable or default  
   
 int main(int argc, char* argv[])  
 {  
  char line[20];  
  FILE *fpin, *fpout;  
   
  // Open the existing file for input  
  if((fpin = fopen(argv[1], "r")) == NULL) {  
   printf("can't open %s", argv[1]);  
   exit(1);  
  }  
   
  // Fork a new process, execute the pager, leave standard input on  
  // So parent process can write to fpout that could pipe to pager input  
  if((fpout = popen(PAGER, "w")) == NULL) {  
   printf("popen error!\n");  
   exit(2);  
  }  
   
  // Write the content to the fpout which is piped to standard input  
  while(fgets(line, 20, fpin) != NULL) {  
   if(fputs(line, fpout) == EOF) {  
    printf("fputs error to pipe");  
    exit(3);  
   }  
  }  
   
  if(ferror(fpin)) {  
   printf("fgets error!\n");  
   exit(4);  
  }  
   
  // Close the file stream  
  if(pclose(fpout) == -1) {  
   printf("pclose error!\n");  
   exit(5);  
  }  
   
  exit(0);  
 }  

shell:
popen will make the pipe much easier.
 ubuntu@ip-172-31-23-227:~$ ./pipe.out test  
 hello world!  

No comments:

Post a Comment