Pipeline-based popen and pclose Functions

Source: Internet
Author: User

The standard I/O function library provides the popen function, which starts another process to execute a shell command line.

Here we call the process that calls popen as the parent process, and the process started by popen as the child process.

The popen function also creates an MPS queue for parent-child process communication. The parent process either reads information from the MPs queue or writes information to the MPs queue. Whether the read or write operation is performed depends on the parameters passed when the parent process calls popen. The definitions of popen and pclose are given below:

 

01 #include <stdio.h>
02 /*
03 Function: popen () calls fork () to generate a sub-process, and then calls/bin/sh-C from the sub-process to execute the command of the parameter command.
04         You can use "R" to indicate reading, and "W" to indicate writing.
05         According to this type value, popen () establishes a pipeline to connect to the standard output device or standard input device of the child process, and then returns a file pointer.
06         Then the process can use this file pointer to read the output device of the sub-process or write it to the standard input device of the sub-process.
07 Returned value: if the operation succeeds, the file pointer is returned. Otherwise, null is returned. The error cause is stored in errno.
08 */
09 FILE * popen( const char * command,const char * type);
10  
11 /*
12 Function: pclose () is used to close the pipeline and file pointer created by popen. The parameter stream is the object pointer returned by the previous popen ().
13 Return Value: If the return result is successful, the return result is-1, and the cause is stored in errno.
14 */
15 int pclose(FILE * stream);

 

The following example shows how to use popen:

If we want to obtain the number of files in the current directory, we can use:

1 ls wc -l

We can write in the program as follows:

01 /* Obtain the number of files in the current directory */
02 #include <stdio.h>
03 #include <stdlib.h>
04 #include <errno.h>
05 #include <sys/wait.h>
06  
07 #define MAXLINE 1024
08  
09 int main()
10 {
11     char result_buf[MAXLINE], command[MAXLINE];
12     int rc = 0; // Receives the return value of a command.
13     FILE *fp;
14  
15     /* Write the command to be executed to Buf */
16     snprintf(command, sizeof(command), "ls ./ | wc -l");
17  
18     /* Execute the preset command and read the standard output of the command */
19     fp = popen(command, "r");
20     if(NULL == fp)
21     {
22         perror("Popen execution failed! ");
23         exit(1);
24     }
25     while(fgets(result_buf, sizeof(result_buf), fp) != NULL)
26     {
27         /* Remove the line break returned by the command for better output below */
28         if(‘\n‘ == result_buf[strlen(result_buf)-1])
29         {
30             result_buf[strlen(result_buf)-1] = ‘\0‘;
31         }
32         printf("Command [% s] Output [% s] \ r \ n", command, result_buf);
33     }
34  
35     /* Wait for the command to be executed and close the pipeline and file pointer */
36     rc = pclose(fp);
37     if(-1 == rc)
38     {
39         perror("Failed to close file Pointer");
40         exit(1);
41     }
42     else
43     {
44         printf("Command [% s] subprocess end status [% d] command return value [% d] \ r \ n", command, rc, WEXITSTATUS(rc));
45     }
46  
47     return 0;
48 }
Compile and execute:

$ GCC popen. c

$./A. Out

Command [ls./| WC-L] to output [2]

Command [ls./| WC-L] sub-process end status [0] command return value [0]

The above popen only captures the standard output of the command. If the command fails to be executed, the sub-process prints the error information to the standard output, and the parent process cannot obtain the error information. For example, if the command is "ls nofile.txt", then the shell will output "ls: nofile.txt: no such file or directory ". This output is on the standard error output. It cannot be obtained through the above program.

Note: If you set the command in the above program to "ls nofile.txt", compile and execute the program and you will see the following results:

$ GCC popen. c

$./A. Out

Ls: nofile.txt: no such file or directory

Command [ls nofile.txt] subprocess end status [256] command return value [1]

Note that the first line of output is not the output of the parent process, but the standard error output of the child process.

Sometimes the error information of a child process is very useful. How can a parent process obtain the error information of a child process?

Here we can redirect the error output of the child process to the standard output (2> & 1) so that the parent process can capture the error information of the child process. For example, if the command is "ls nofile.txt 2> & 1", the output is as follows:

Command [ls nofile.txt 2> & 1] to output [ls: nofile.txt: no such file or directory]

Command [ls nofile.txt 2> & 1] sub-process end status [256] command return value [1]

Appendix: Macro involved in determining the termination status of a sub-process. Set the Process Termination status to status.

Wifexited (Status) is not 0 if the sub-process ends normally.

Wexitstatus (Status) gets the end code returned by the sub-process exit (). Generally, wifexited is used to determine whether the macro can be used until it ends normally.

Wifsignaled (Status) If the sub-process ends because of a signal, the macro value is true.

Wtermsig (Status) gets the signal code of the sub-process terminated due to the signal. Generally, this macro is used only after wifsignaled is used for determination.

Wifstopped (Status) If the sub-process is paused, the macro value is true. This is generally the case only when wuntraced is used.

Wstopsig (Status) gets the signal code that causes the sub-process to pause. This macro is generally used only after wifstopped is used for determination.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.