进程替换就是把当前进程替换成我们需要执行的进程,一般是通过系统调用实现。
我们可以创建子进程,然后把子进程替换成我们需要的进程,执行其他程序的代码。
进程替换后:1、程序替换后,替换函数之后的代码不会被执行,因为进程已经被替换了。
2、替换函数只有失败返回值,没有成功返回值。
3、替换完成,不创建新的程序。
4、程序替换不会替换环境变量
程序替换常用的系统接口:
我们可以观察得到,这些函数前面都有exec,后面跟着的 p: 表示自动搜索路径;e: 表示自己维护环境变量;l:表示采用列表传参;v:表示采用数组传参;
示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t id = fork();
if(id == 0)
{
printf("exec begin\n");
//进程替换
execl("/usr/bin/ls", "ls", "-al", NULL);
printf("exec end\n");
exit(0);
}
int rid = waitpid(id, NULL, WUNTRACED);
if(rid > 0)
{
printf("wait success\n");
}
return 0;
}
并且我们代码中的 exec end 没有打出来,验证了进程替换后,后续代码不再执行。
以替换 "ls -al" 为例,剩余接口:
//l代表传参数列表,分成一个个字符串传
execl("/usr/bin/ls", "ls", "-al", NULL);
//p表示系统会去PATH环境变量中找
execlp("ls", "ls", "-al", NULL);
//v代表传数组,把命令分成字符串,放进字符串数组里,一起传
char* argv[] = {"ls", "-al", NULL};
execv("/usr/bin/ls", argv);
往进程加环境变量: putenv() .
e代表环境变量,程序替换不会替换环境变量,我们可以通过带e的接口设置新的环境变量。
这会覆盖原本的环境变量。
test.c 里面的代码:
#include <stdio.h>
int main(int argc, char* argv[], char* env[])
{
//打印环境变量
for(int i = 0; env[i]; ++i)
printf("env[%d] : %s\n",i, env[i]);
//打印参数个数
printf("argc = %d\n", argc);
//打印参数
for(int i = 0; argv[i]; ++i)
printf("argv[%d] = %s\n",i, argv[i]);
//随便打印一些
for(int i = 0; i < 10; ++i)
printf("I am test\n");
return 0;
}
用子进程来执行test.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
char* const env[] = {"haha=hehe", "PATH=/", NULL};
pid_t id = fork();
if(id == 0)
{
execle("./test", "test", "-a", "-b", "-c", NULL, env);
if(errno != 0)
printf("%s\n", strerror(errno));
printf("exec end\n");
exit(0);
}
int rid = waitpid(id, NULL, WUNTRACED);
if(rid > 0)
{
printf("wait success\n");
}
return 0;
}