Detailed explanation of exec function family

Introduction to exec

View help via command:man 3 exec

Insert image description here

The function of the exec function family is to find the executable file based on the specified file name and use it to replace the content of the calling process. In other words, it is to execute an executable file inside the calling process .

Functions in the exec function family will not return after successful execution, because the entities of the calling process, including code segments, data segments, and stacks, have been replaced by new content, leaving only some superficial information such as process IDs. Only if the call fails, they will return -1 and continue execution from the calling point of the original program.

Insert image description here
Picture reference from: [Linux] Understanding and using process control (exec function family)

Process program replacement does not create a new process, it only loads the program's code and data to replace the original process.

exec family

int execl(const char *path, const char *arg, .../* (char *) NULL */);
int execlp(const char *file, const char *arg, ... /* (char *) NULL */);
int execle(const char *path, const char *arg, .../*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
int execve(const char *filename, char *const argv[], char *const envp[]);

return value

  • Functions in the exec function family will not return after successful execution.
  • The call failed and -1 was returned.

Followed by different parameters, representing different meanings

  • l(list): parameter address list, terminated by a null pointer

  • v(vector): The address of the pointer array that stores the address of each parameter

  • p(path): Search for executable files in the directory specified by the PATH environment variable. You can use env to view existing environment variables.

  • e (environment): The address of the pointer array that stores the string address of the environment variable

The first two are used more often

execl function

  • int execl(const char *path, const char arg, …/ (char *) NULL */);

    • path: the path or name of the file to be executed that needs to be specified

    • arg: is the list of parameters required to execute the executable file. The first parameter generally has no effect. For convenience, it usually writes the name of the program to be executed. Starting from the second parameter, it is the list of parameters required for program execution. The parameters need to end with NULL (Sentinel)

Note: There are 2 files in the initial folder hello.c, the content of which is to output a random statement.hello

program

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    
    
    // 创建一个子进程,在子进程中执行exec函数族中的函数
    pid_t pid = fork();
    if(pid > 0) {
    
    
        // 父进程
        printf("i am parent process, pid : %d\n",getpid());
        sleep(1);
    }else if(pid == 0) {
    
    
        execl("hello","hello",NULL);
        perror("execl");
        printf("i am child process, pid : %d\n", getpid());
    }
    for(int i = 0; i < 3; i++) {
    
    
        printf("i = %d, pid = %d\n", i, getpid());
    }
    return 0;
}

operation result

(base) user@ubuntu:~/Desktop/OS/NiuKe$ gcc -o test test.c -std=c99
(base) user@ubuntu:~/Desktop/OS/NiuKe$ ./test 
i am parent process, pid : 4426
Hello world
i = 0, pid = 4426
i = 1, pid = 4426
i = 2, pid = 4426

As you can see, the content of the child process (user area) is replaced, and the content in the hello executable file is printed.

execlp function

  • int execlp(const char *file, const char arg, … / (char *) NULL */);

    • It will search for the specified executable file in the environment variable. If it is found, it will be executed. If it is not found, the execution will not be successful.

    • file: only the name needs to be provided (the path does not need to be provided)

program

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main() {
    
    
    // 创建一个子进程,在子进程中执行exec函数族中的函数
    pid_t pid = fork();

    if(pid > 0) {
    
    
        // 父进程
        printf("i am parent process, pid : %d\n",getpid());
        sleep(1);
    }else if(pid == 0) {
    
    
        // 子进程
        execlp("ps", "ps", "aux", NULL);

        printf("i am child process, pid : %d\n", getpid());
    }
    for(int i = 0; i < 3; i++) {
    
    
        printf("i = %d, pid = %d\n", i, getpid());
    }
    return 0;
}

Output results

(base) user@ubuntu:~/Desktop/OS/NiuKe$ gcc -o test test.c -std=c99
(base) user@ubuntu:~/Desktop/OS/NiuKe$ ./test 
i am parent process, pid : 4437
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.2 160048  9248 ?        Ss   Jan15   0:03 /sbin/init auto noprompt
root          2  0.0  0.0      0     0 ?        S    Jan15   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        I<   Jan15   0:00 [rcu_gp]
root          4  0.0  0.0      0     0 ?        I<   Jan15   0:00 [rcu_par_gp]
root          6  0.0  0.0      0     0 ?        I<   Jan15   0:00 [kworker/0:0H-kb]
...
user       4438  0.0  0.0  41424  3568 pts/3    R+   00:51   0:00 ps aux
i = 0, pid = 4437
i = 1, pid = 4437
i = 2, pid = 4437

execv function

  • int execv(const char *path, char *const argv[]);

    • argv: Write all running parameters in the array

program

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

int main() {
    
    
    // 创建一个子进程,在子进程中执行exec函数族中的函数
    pid_t pid = fork();

    if(pid > 0) {
    
    
        // 父进程
        printf("i am parent process, pid : %d\n",getpid());
        sleep(1);
    }else if(pid == 0) {
    
    
        // 子进程
        char* argv[] = {
    
    "hello", NULL};
        execv("hello", argv);
        perror("execv");
        printf("i am child process, pid : %d\n", getpid());

    }

    for(int i = 0; i < 3; i++) {
    
    
        printf("i = %d, pid = %d\n", i, getpid());
    }
    return 0;
}

Output results

(base) user@ubuntu:~/Desktop/OS/NiuKe$ gcc -o test test.c -std=c99
(base) user@ubuntu:~/Desktop/OS/NiuKe$ ./test 
i am parent process, pid : 4453
Hello world
i = 0, pid = 4453
i = 1, pid = 4453
i = 2, pid = 4453

The remaining functions are similar in usage and will not be shown~

Guess you like

Origin blog.csdn.net/weixin_42888638/article/details/128705783