In Linux, there is no exec () function, exec refers to a set of functions, a total of 6, namely: #include <unistd.h> extern char **environ; 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[]); in T 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 role of the EXEC function family is
finds the executable file according to the specified file name and replaces the contents of the calling process with it
, in other words, executing an executable file inside the calling process。 The executable file here can be either a
Binary FilesOr it can be executed under any Linux
script File。 Relationship between function name and parameter: Take a closer look, these 6 functions are all starting with the Exec (representing the EXEC function group), the first 3 functions followed by the letter L, the last 3 followed by the letter V, I understand that L is the list (enumeration parameters), V is the vector (parameter vector table). The difference is that the function at the beginning of EXECV is to pass command-line arguments as "char *argv[" (vector), and the function at the beginning of the EXECL takes a list (list), lists the parameters one by one, and ends with a null representation. The null effect here is the same as the null function in the argv array. The letter P refers to the directory where the environment variable path is located to find the executable file to execute. The 2 functions EXECLP and EXECVP, which end in P, seem to differ very little from those of Execl and execv, and they differ from the first parameter name: 4 functions except EXECLP and EXECVP are required, Their 1th parameter path must be a complete path, such as "/bin/ls", while the 1th parameter of EXECLP and EXECVP file can be just a file name, such as "LS", these two functions can be automatically to the environment variable path specified in the directory to find. The letter E refers to the environment variable specified for the executable file. Of all 6 functions, only execle and Execve use char *envp[] to pass the environment variable, and none of the other 4 functions have this parameter, which does not mean that they do not pass the environment variable, and these 4 functions will pass the default environment variable to the executed application without any modification. Instead, execle and EXECVE use the specified environment variables to override the default ones. The return value differs from the general case in that the function of the EXEC function family executes
does not return after success, because the entity that invokes the process, including code snippets, data segments, and stacks, has been replaced with new content, and only some surface information, such as the process ID, remains intact.
when the call fails, it sets errno and returns 1, then executes from the original program's call point。 In contrast to other system calls, exec is prone to failure, the location of files being executed, permissions, and many other factors that can cause a call to fail. Therefore, when using the EXEC function family, be sure to add an error judgment statement. The most common error: file or path not found, errno is set to Enoent, array argv and envp forget to end with NULL, errno is set to Efault, there is no run permission to execute file, errno is set to eacces at this time. 2. Application if a process wants to execute another program, it can fork or vfork out a new process, and then call any of the exec functions. To do this, Linux also specializes in fork optimization:
usually fork will copy all the contents of the calling process into the newly generated sub-process, the actions of these copies are very time consuming, and if we call exec immediately after the fork is finished, the hard copy will be erased immediately, which looks very uneconomical, 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 to the child process, but to the actual use of the copy, so that if the next statement is exec, it will not be useless. In fact, "copy-on-write" or copy, the process of the MM structure, page tables are still copied ("Copy on Write" must also be supported by this information.) Otherwise, the kernel captures the CPU access exception, how to distinguish whether this is "copy-on-write" caused by, or the real ultra-vires visit it? )。 and vfork to do things, all the memory of the things are not copied,
The memory of the parent-child process is fully shared。 But then there are problems, although the user program can design many ways to avoid the conflict between parent-child processes. But the key point is that the parent-child process is shared with the stack, which is not controlled by the user. When a process makes an operation about a function call or return, the call stack of another process (which is actually the same stack) is also affected. Such a program is not going to work. So
Vfork There is a restriction that when a child process is generated, the parent process is suspended by the kernel in vfork until the child process has its own memory space (exec**) or exits (_exit). And
until then, the child process cannot return from the function that called Vfork(Also, you cannot modify variables on the stack, you cannot continue to invoke functions other than the _exit or exec series, otherwise the parent process's data may be overwritten). Despite a lot of restrictions, vfork immediately after the exec efficiency will be much higher than fork.
/* EXEC.C */
UNISTDH #include <.>
main void (void)
{
ENVP char*[]={"Path=/tmp", "User=lingdxuyan", "status=testing", NULL};
ARGV_EXECV char*[]={"echo", "excuted by Execv", NULL};
ARGV_EXECVP char*[]={"echo", "executed by EXECVP", NULL};
Argv_execve char*[]={"env", NULL};
Fork 0 if (() = =)
Execl 0 if (("/bin/echo", "echo", "executed by Execl", NULL) <)
Perror ("Err on Execl");
Fork 0 if (() = =)
EXECLP 0 if (("echo", "echo", "executed by EXECLP", NULL) <)
Perror ("Err on EXECLP");
Fork 0 if (() = =)
Execle ENVP 0 if (("/usr/bin/env", "env", NULL,) <)
Perror ("Err on Execle");
Fork 0 if (() = =)
EXECV ARGV_EXECV 0 if (("/bin/echo",) <)
Perror ("Err on Execv");
Fork 0 if (() = =)
EXECVP ARGV_EXECVP 0 if (("echo",) <)
Perror ("Err on EXECVP");
Fork 0 if (() = =)
Execve argv_execve envp 0 if (("/usr/bin/env",,) <)
Perror ("Err on Execve");
}
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. If you change the fork in the program to Vfork, the program executed by each exec executes sequentially.
Reproduced Linux Process Control--exec function family