在进程中启动程序
# 在进程中启动程序
# 进程的操作
传统Uinx模型中有两个创建和修改进程的操作。
fork:用来创建一个新的进程,此进程几乎是当前进程的一个完全拷贝
exec:可以在进程中用另外的程序来替换掉当前进程运行的程序
# exec函数族
exec函数实际是包含了六个函数的函数族
#include<unistd.h>
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[]);
1
2
3
4
5
6
7
2
3
4
5
6
7
# execve函数
#include<unistd.h>
int execve(const char* path, char* const argv[] , char* const envp[]);
1
2
2
path:可执行文件路径
argv[]:完整的参数列表,包含argv[0],必须以NULL结束
envp[]:环境变量,可省
# execve函数举例
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *argv[] = {"/", NULL};
if(execve("/bin/ls", argv, NULL) == -1)
{
perror("execve");
exit(EXIT_FAILURE);
}
puts("shouldn't get here");
exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ./execve
1.txt 2.txt 3.txt execve
1
2
2
# 结论
“shouldn‘t get here”根本没有执行。
这是因为执行到execve函数时,进程的代码部分已经用新程序替换了,不会留下调用进程的任何痕迹。
也就是说,exec函数族一旦执行成功,就不会返回它的调用者(失败返回-1,并设置errno)。
# 示例代码
利用fork建立一个子进程,在此子进程中执行显示当前目录下所有文件的命令,同时父进程中显示父进程的PID号。
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
pid_t child;
int status;
if((child = fork()) == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if(child == 0) {
puts("in child");
char *argv[] = {"ls -l", NULL};
if(execve("/bin/ls", argv, NULL) == -1) {
perror("execve");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
} else {
waitpid(child, &status, 0);
puts("\nin parent");
printf("\tparent pid = %d\n", getpid());
printf("\tparent ppid = %d\n", getppid());
}
exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
执行结果
$ ./forkwait
in child
1.txt 2.txt 3.txt execve forkwait
in parent
parent pid = 2576
parent ppid = 2138
1
2
3
4
5
6
7
2
3
4
5
6
7
编辑 (opens new window)
上次更新: 2023/02/18, 10:09:42
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05