作用:
我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。
exec函数族:
execl, execlp, execle, execv, execvp, execvpe
#include
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[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
/*
path:可执行文件的路径名字
file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。
arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
*/
返回值:
exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。
例:
有绝对路径
//文件demo.c
#include
#include
#include
int main(void)
{
printf("before execl\n");
if(execl("./bin/echoarg","echoarg","abc",NULL) == -1)
//文件路径./ ...执行文件echoarg,显示内容abc,空结尾。
//arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
{
printf("execl failed!\n");
perror("why");//失败的原因
}
printf("after execl\n");
return 0;
}
//文件echoarg.c
#include
int main(int argc,char *argv[])
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("argv[%d]: %s\n",i,argv[i]);
}
return 0;
}
运行结果:
before execl
argv[0]: echoarg
argv[1]: abc
运行 ls:
通过whereis ls找到 ls的路径,然后调用:if(execl("/bin/ls","ls",NULL,NULL) == -1)
运行 ls -l:
通过whereis ls找到 ls的路径,然后调用:if(execl("/bin/ls","ls","-l",NULL) == -1)
获取系统时间date:
通过whereis date找到 date的路径,然后调用:if(execl("/bin/date","date",NULL,NULL) == -1)
族函数带p的:execlp
(不加绝对路径)exaclp函数带p,所以能通过环境变量PATH查找到可执行文件ps
#include
#include
#include
int main(void)
{
printf("before execlp\n");
if(execlp("ps","ps","-l",NULL) == -1)
//通过环境变量PATH查找到可执行文件ps
{
printf("execl failed!\n");
}
printf("after execl\n");
return 0;
}
环境变量:
查询环境变量:echo $PATH
显示当前路径:pwd
修改环境变量:export PATH=$PATH:pwd显示的路径
族函数带v的:execvp
execv带绝对路径
#include
#include
#include
int main(void)
{
printf("before execlp\n");
char *argv[] = {"ps",NULL,NULL};
if(execvp("ps",argv) == -1)
{
printf("execl failed!\n");
}
printf("after execl\n");
return 0;
}
精彩博文: https://blog.csdn.net/u014530704/article/details/73848573
**
**
实现功能:当父进程检测到输入为一的时候,创建子进程把配置文件的字段修改掉。
//changeData文件
/*
修改配置文件config.txt
> SPEED = 3
> LENG = 3
> SCORE = 9
> LEVEL = 5
> 修改为:
> SPEED = 3
> LENG = 100
> SCORE = 9
> LEVEL = 5
*/
#include
#include
#include
#include
#include
#include
#include
int main(int argc,char **argv)
{
int fdSrc,fdDes;
char *readBuf = NULL;
if(argc != 2){
printf("pararm error\n");
exit(-1);
}
fdSrc = open(config.txt,O_RDWR);//打开文件
int size = lseek(fdSrc,0,SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf = (char *)malloc(sizeof(char)*size + 8);
int n_read = read(fdSrc,readBuf,1024);
char *p = strstr(readBuf,"LENG=");
if(p==NULL){
printf("not founf\n");
exit(-1);
}
p = p+strlen("LENG=");
*p = "100";
lseek(fdSrc,0,SEEK_SET);//移动光标
int n_write =write(fdSrc,readBuf,strlen(readBuf));
close(fdSrc);
return 0;
}
用exec族函数调用changeData文件
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
pid_t pid;
int data = 10;
while(1){
printf("please input a data:\n");
scanf("%d",&data);
if(data == 1){
int fdSrc;
pid = fork();
if(pid > 0){
wait(NULL);
}
if(pid == 0){
execl("./changeData","changeData","config.txt",NULL);
}
}
else{
printf("wait ,do nothing!\n");
}
}
return 0;
}