Original: http://blog.csdn.NET/nvd11/article/details/8856278
What if we wanted to invoke 1 shell scripts or execute 1 Bash shell commands when we were writing 1 C programs?
In fact, in <stdlib.h> this header contains 1 functions called the shell command or script system (); It is convenient to directly pass the shell command as a parameter to the system function. There is one such introduction to System: When system execution is automatically enabled fork () creates a new 1 process, the efficiency is not directly using the fork () and the EXEC function is high.
So this article is actually about the use of fork () and Exec functions, and how to use them instead of the system functions.
1. The fork () function 1.1 the fork () function
Generally speaking, we write 1 ordinary C programs, run the program until the end of the program, the system will only assign 1 PID to the program, it is said that the system will only have a process about the program.
But the function of fork () execution is different.
Fork the English word in English is "fork" meaning, fork () This function is also very consistent with this meaning. Its role is to replicate the current process (including the process in memory stack data) for 1 new mirrors. The new image is then executed at the same time as the old process. Equivalent to 1 processes, the fork () function is divided into two processes at the same time executed. And the two processes are mutually exclusive.
fork
The feature of the function is summed up as "call once, return two times"
1.2 Distinguish between main programs and subroutines.
In practical applications, it is not very important to simply let the program fork, we add a subroutine, most likely to let the child process execute a piece of code alone. Implement different functions than the main process.
To implement the functionality described above, you are actually letting the child process and the main process execute different code.
So fork () actually has a return value, and the return value in the two process is different, in the main process the fork () function will return the PID of the child process, and in the child process will return 0! So we can use the IF statement to execute different code, depending on the return value of the fork () to determine which process the process is in.
intfork_test () {intChildpid; intret; if(ret =fork () = =-1) {printf ("Fork failed\n"); } }Else if(ret = =0){ //Child Processprintf"This is the child process\n"); } Else{printf ("This is the parent process\n"); }}
1.3 Use the Wait () function to execute a subroutine such as the main program after completion (exit).
From the above example, the execution order of the main program and the subroutine is random, but in reality, we usually want the child process to execute before continuing with the main process.
The wait () function provides this functionality by adding the wait () function to the main process part of the IF condition, allowing the main process to hold the fork () function, wait for the child process to exit and then execute, usually in conjunction with the exit () function of the child process.
2. exec Function Group
It is important to note that exec is not a 1 function, but it is a general term for a set of functions, which includes the following 6 functions:
#include <unistd.h>intEXECL (Const Char*path,Const Char*arg, ...); intEXECLP (Const Char*file,Const Char*arg, ...); intExecle (Const Char*path,Const Char*arg, ...,Char*Constenvp[]); intExecvConst Char*path,Char*Constargv[]); intEXECVP (Const Char*file,Char*Constargv[]); intExecve (Const Char*path,Char*ConstArgv[],Char*ConstEnvp[]);
You can see that these 6 function names are different, and they are used to accept different parameters.
In fact, their functions are almost the same, because to accept different parameters so to distinguish them with different names, after all, C language does not function overloaded functions.
But in fact they are named in a regular pattern:
Exec[l or V][p][e]
The parameters in the EXEC function can be divided into 3 parts, the execution of the file section, the Command Parameters section, and the Environment variables section.
For example, I want to execute 1 commands ls-l/home/gateman
The execution file section is "/usr/bin/ls"
The command entry part is "LS", "-L", "/home/gateman", NULL to see is the beginning of the LS with 1 every space must be divided into 2 parts, and null-terminated AH.
The environment variable section, which is an array, the final element must be NULL such as char * env[] = {"Path=/home/gateman", "User=lei", "status=testing", NULL};
Okay, here's the naming convention:
e Follow-up, the parameter must have the environment variable part, the environment change 0 part parameter becomes the environment variable during exec function execution, less use
l Subsequent, the command parameter section must be separated by "," and the last 1 command arguments must be null
v subsequent, the command argument section must be a pointer to the head of 1 null-terminated array of string pointers. For example, char * pstr is a pointer to a string, char * pstr[] is an array, pointing to each string individually.
P subsequent, the executable file part can be without the path, the EXEC function will find in the $path
Another 1 note is that the EXEC function supersedes the process that executes it, that is, once the EXEC function executes successfully, it does not return, and the process ends. But if the EXEC function fails, it returns the failed information, and the process continues to execute the following code!
Normally exec will be placed in the sub-process portion of the fork () function to replace the child process execution, and the subroutine disappears after execution succeeds, but the exit () function must be used to exit the child process if execution fails!
Here are the various examples:
2.1 Execv function
intChildpid; inti; if(fork () = =0){ //Child Process Char* execv_str[] = {"Echo","executed by Execv", NULL}; if(Execv ("/usr/bin/echo", EXECV_STR) <0) {perror ("error on exec"); Exit (0); } }Else{ //Parent ProcessWait (&childpid); printf ("execv done\n\n"); }
Note the definition and assignment of a string pointer array
2.2 EXECVP function
if(fork () = =0){ //Child Process Char* execvp_str[] = {"Echo","executed by EXECVP",">>","~/abc.txt", NULL}; if(EXECVP ("Echo", EXECVP_STR) <0) {perror ("error on exec"); Exit (0); } }Else{ //Parent ProcessWait (&childpid); printf ("EXECVP done\n\n"); }
2.3 Execve function
if(fork () = =0){ //Child Process Char* execve_str[] = {"Env", NULL}; Char* env[] = {"path=/tmp","User=lei","status=testing", NULL}; if(Execve ("/usr/bin/env", execve_str,env) <0) {perror ("error on exec"); Exit (0); } }Else{ //Parent ProcessWait (&childpid); printf ("Execve done\n\n"); }
2.4 Execl function
if(fork () = =0){ //Child Process if(Execl ("/usr/bin/echo","Echo","executed by Execl", NULL) <0) {perror ("error on exec"); Exit (0); } }Else{ //Parent ProcessWait (&childpid); printf ("execv done\n\n"); }
2.5 EXECLP function
if(fork () = =0){ //Child Process if(EXECLP ("Echo","Echo","executed by EXECLP", NULL) <0) {perror ("error on exec"); Exit (0); } }Else{ //Parent ProcessWait (&childpid); printf ("EXECLP done\n\n"); }
2.6 Execle function
if(fork () = =0){ //Child Process Char* env[] = {"Path=/home/gateman","User=lei","status=testing", NULL}; if(Execle ("/usr/bin/env","Env", null,env) <0) {perror ("error on exec"); Exit (0); } }Else{ //Parent ProcessWait (&childpid); printf ("execle done\n\n"); }
Linux C Fork Exec Introduction usage