Linux schedules the operation of a process by maintaining five states. These five states are: Run, interruptible, non-interruptible, zombie, stop.
PID to identify different processes, each of the processes in Linux has a unique process number.
A PCB block is a process resource
1.fork function
Include <unistd.h>
pid_t fork (void)
return value 0: Child process child process ID (greater than 0)-1: Error
The child process that is obtained by using the fork function is a replica of the parent process. Using the fork function is expensive, and it replicates most of the code snippets, data segments, and stack segments in the parent process.
2. exec function Family
Include <unistd.h>
int execl (char *path, char *arg0,char *arg1,..., char *argn,null)
int execle (char *path, char *arg0,char *arg1,..., char *argn,null,char *envp[])
int EXECLP (char *file, char *arg0,char *arg1,..., NULL)
int Execv (char *path, Char *argv[])
int Execve (char *path, char *argv[],char *envp[])
int EXECVP (char *file, Char *argv[])
return Value:-1 error.
In the EXEC function family, when the suffix L, V, p, E is added to exec, the specified function will have some operational capability
suffix p, the function can use the path variable to find the subroutine file if you want to execute the command/bin/cat/etc/passwd/etc/group, just write the cat passwd group directly
Suffix L, you want to receive a comma-delimited list of parameters, with a NULL pointer as the end flag execl ("/bin/cat", "/etc/passed", "/etc/group", NULL);
Suffix V, you want to receive a pointer to a NULL-terminated array of strings char* argv[] = {"/bin/cat", "/etc/passed", "/etc/group", NULL}
EXECV ("/bin/cat", argv);
Suffix e, the function passes the specified parameter envp, allowing the environment to change the child process, with no suffix e, the child process uses the current program's environment. ENVP is also a null-terminated string array pointer
int main (int argc, char *argv[], char *envp[])
It may not be the same as the vast majority of textbooks, but in fact, this is really the complete form of the main function.
Parameter argc indicates the number of command-line arguments to run the program, the array argv holds all the command-line arguments, and the array envp stores all the environment variables.
int Execve (const char *path, char *const argv[], char *const envp[]);
Compare the full form of the main function to see the problem? Yes, the argv and envp in these two functions are exactly one by one corresponding relationships. Execve the 1th parameter path is the full path of the application being executed, and the 2nd parameter argv is the command-line argument passed to the executed application, and the 3rd parameter ENVP is the environment variable passed to the application being executed.
Take a look at these 6 functions can also find that the first 3 functions are beginning with execl, and the last 3 are execv beginning with, the difference is that EXECV begins with the function is "char*argv[]" in the form of the command line parameters are passed, The function that begins with EXECL takes the way that we are more accustomed to, putting the parameters in one column and ending with a null representation. The null effect here is the same as the null function in the argv array.
Of all 6 functions, only execle and Execve use char*envp[] to pass environment variables, and none of the other 4 functions have this parameter, which does not mean that they do not pass environment variables, and these 4 functions will pass the default environment variable to the executed application without any modification. Execle and EXECVE will replace the default ones with the specified environment variables.
There are 2 functions EXECLP and EXECVP that end with P, and it seems that they differ very little from execl and EXECV, and it is true that all 4 functions except EXECLP and EXECVP require that their 1th parameter path be a complete path, such as "/ Bin/ls "; The 1th parameter file of EXECLP and EXECVP can be as simple as a file name, such as" LS ", which can be automatically found in the directory where the environment variable path is made.
1 Introduction
is called the EXEC system call, in fact, in Linux, there is no EXEC () function form, exec refers to a set of functions, a total of 6, namely:
int execl (const char *path, const char *arg, ...);
int EXECLP (const char *file, const char *arg, ...);
int execle (const char *path, const char *arg, ..., Char *const envp[]);
int execv (const char *path, char *const argv[]);
int EXECVP (const char *file, char *const argv[]);
int Execve (const char *path, char *const argv[], char *const envp[]);
Only EXECVE is the real system call, and the others are packaged library functions on this basis.
The function of the EXEC function family is to find the executable file according to the specified file name and use it to replace the contents of the calling process, in other words, execute an executable file inside the calling process. The executable file here can be either a binary file or a script file that can be executed under any Linux.
Unlike the general case, the function of the EXEC function family does not return after successful execution, because the entity that invokes the process, including the code snippet, the data segment, and the stack have been replaced by the new content, leaving only some surface information, such as the process ID, to remain as it is, rather "Jinchantuoqiao" in the "36 gauge". It looks like an old shell, but it's already infused with a new soul. Only the calls fail, they return a-1, which is then executed from the point of invocation of the original program.
Now we should understand how Linux executes the new program, and whenever there is a process that thinks that it cannot contribute to the system or its support, he can take the last bit of heat and call any exec to regenerate himself with a new face, or, more generally, If a process wants to execute another program, it can fork out a new process and call any exec, which looks like a new process is generated by executing the application.
In fact the second case is so prevalent that Linux is optimized for it, and we already know that fork will copy all the contents of the calling process to the newly created child
Process, these copies of the action is very time consuming, and if we call exec immediately after the fork, the hard copy of the things will be immediately erased, which seems to be very cost-effective, so people designed a "copy-on-write (Copy-on-write)" Technology, So that the fork does not immediately copy the contents of the parent process, but to the real practical time to copy, so if the next statement is exec, it will not be useless, and improve efficiency.
2 slightly deeper
The above 6 functions seem to be complex, but in fact they are very similar in function and usage, with only a small difference. Before you learn them, let's take a look at the main function we're accustomed to.
The following form of the main function may be somewhat unexpected:
int main (int argc, char *argv[], char *envp[])
It may not be the same as the vast majority of textbooks, but in fact, this is really the complete form of the main function.
Parameter ARGC indicates the number of command-line arguments to run the program, the array argv holds all the command-line arguments, and the array envp stores all the environment variables. An environment variable refers to a set of values that persist from the time a user logs in, and many applications rely on it to determine some of the details of the system, and our most common environment variable is path, which indicates where to search for the application, such as
/bin;home is also a more common environment variable, which indicates our personal directory in the system. Environment variables are generally in the form of the string "xxx=xxx", XXX represents the variable name, XXX represents the value of the variable.
It is worth mentioning that both the argv array and the ENVP array hold pointers to strings, both of which represent the end of the array with a NULL element.
We can see what goes into argc, argv and envp by following this procedure:
- /* main.c */
- int main (int argc, char *argv[], char *envp[])
- {
- printf ("\n### ARGC ###\n%d\n", ARGC);
- printf ("\n### ARGV ###\n");
- while (*ARGV)
- printf ("%s\n", * (argv++));
- printf ("\n### ENVP ###\n");
- while (*ENVP)
- printf ("%s\n", * (envp++));
- return 0;
- }
Compile it:
$ cc Main.c-o Main
At run time, we deliberately add several command-line arguments that do not have any effect:
./main-xx 000
The results are as follows:
- # # # ARGC # #
- 3
- # # # ARGV # #
- ./main
- -xx
- 000
- # # # ENVP # #
- Shell=/bin/bash
- Term=xterm
- xdg_session_cookie=a22b29a83538f728e1eb55634e0d3ce5-1333068076.875472-2013090315
- User=root
- ls_colors=rs=0:di=01;34:ln=01;36:hl=44;37:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37 ; 41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*. lzh=01;31:*.lzma=01;31:*.zip=01;31:*.z=01;31:*. z=01;31:*.dz=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01; 31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35 :*. Bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35: *.PNG=01;35:*.SVG=01;35:*.SVGZ=01;35:*.MNG=01;35:*.PCX=01;35:*.MOV=01;35:*.MPG=01;35:*.MPEG=01;35:*.M2V=01;35: *.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*. asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf= 01;35:*.xwd=01;35:*.yuv=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00; 36:*.RA=00;36:*.WAV=00;36:*.AXA=00;36:*.OGA=00;36:*.SPX=00;36:*.XSPF=00;36:
- Mail=/var/mail/root
- Path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/arm/4.3.2/bin
- Pwd=/home/jerry/studylinux
- Lang=zh_cn. UTF-8
- speechd_port=6560
- Shlvl=1
- Home=/root
- Language=zh_cn:zh
- Logname=root
- lessopen=| /usr/bin/lesspipe %s
- display=:0.0
- Lessclose=/usr/bin/lesspipe %s %s
- Xauthority=/var/run/gdm/auth-for-jerry-qvfa5i/database
- Colorterm=gnome-terminal
- _=./main
- Oldpwd=/home/jerry
We see that the program will "./main" as the 1th command-line argument, so we have 3 command-line arguments altogether. This may be a bit different from what you are accustomed to saying, be careful not to make a mistake.
Now look back at the EXEC function family and focus on EXECVE first:
int Execve (const char *path, char *const argv[], char *const envp[]);
Compare the full form of the main function to see the problem? Yes, the argv and envp in these two functions are exactly one by one corresponding relationships. Execve the 1th parameter path is the full path of the application being executed, and the 2nd parameter argv is the command-line argument passed to the executed application, and the 3rd parameter ENVP is the environment variable passed to the application being executed.
Take a look at these 6 functions can also find that the first 3 functions are beginning with execl, and the last 3 are execv beginning with, the difference is that EXECV begins with the function is "char*argv[]" in the form of the command line parameters are passed, The function that begins with EXECL takes the way that we are more accustomed to, putting the parameters in one column and ending with a null representation. The null effect here is the same as the null function in the argv array.
Of all 6 functions, only execle and Execve use char*envp[] to pass environment variables, and none of the other 4 functions have this parameter, which does not mean that they do not pass environment variables, and these 4 functions will pass the default environment variable to the executed application without any modification. Execle and EXECVE will replace the default ones with the specified environment variables.
There are 2 functions EXECLP and EXECVP that end with P, and it seems that they differ very little from execl and EXECV, and it is true that all 4 functions except EXECLP and EXECVP require that their 1th parameter path be a complete path, such as "/ Bin/ls "; The 1th parameter file of EXECLP and EXECVP can be as simple as a file name, such as" LS ", which can be automatically found in the directory where the environment variable path is made.
3 combat
The knowledge is about to be introduced, and then we'll look at the actual application:
- /* EXEC.C */
- #include
- Main ()
- {
- Char *envp[]={"Path=/tmp",
- "User=lei",
- "Status=testing",
- NULL};
- Char *argv_execv[]={"echo", "excuted by Execv", NULL};
- Char *argv_execvp[]={"echo", "executed by EXECVP", NULL};
- Char *argv_execve[]={"env", NULL};
- if (fork () ==0)
- if (Execl ("/bin/echo", "echo", "executed by Execl", NULL)
- }
The program calls 2 Linux common system commands, ECHO and Env. echo prints out the command line arguments that follow, and Env is used to list all environment variables.
Because the order in which each sub-process executes is uncontrollable, it is possible to have a confusing output-the results of each child process being printed mixed together rather than strictly in the order listed in the program.
Compile and run:
- $ cc EXEC.C- o exec
- $ ./exec
- Executed by execl
- Path=/tmp
- User=lei
- Status=testing
- Executed by EXECLP
- Excuted by Execv
- Executed by EXECVP
- Path=/tmp
- User=lei
- Status=testing
As expected, the results of the execle output ran to the EXECLP front.
Everyone in the normal programming, if the use of the EXEC function family, must remember to add the wrong judgment statement. Because exec is prone to injury compared to other system calls, the location of files being executed, permissions, and many other factors can cause the call to fail. The most common errors are:
File or path not found, at this time errno is set to enoent;
Array argv and envp forget to end with NULL, at this point errno is set to Efault;
There is no run permission on the file to be executed, at which point the errno is set to Eacces.
This article from Csdn Blog, reproduced please indicate the source: http://blog.csdn.net/wubin1124/archive/2009/12/14/5002556.aspx
Linux Process Programming