fork()函数用于创建一个子进程,该子进程几乎复制了父进程的全部内容。我们能否让子进程执行一个新的程序呢?exec函数族就提供了一个在进程中执行另一个程序的方法。它可以根据指定的文件名或目录名找到可执行文件,并用他来取代当前进程的数据段、代码段和堆栈段。在执行完后,当前进程除了进程号外,其他内容都被替换。
头文件:#include <unistd.h>
函数原型:
int execl(const char*path, const char *arg, ...); //1. 查找方式:完整的文件目录路径;2. 参数传递方式:逐个列举(list)
int execv(const char*path, const char *const arg[]); //2. 参数传递方式:指针数组传递(vertor)
int execle(const char*path, const char *arg, ..., char *const envp[]); //3. 使用默认的环境变量(environment),在envp[]中指定当前进程使用的环境变量
int execve(const char*path, const char *const arg[], char *const envp[]);
int execlp(const char*file, const char *arg, ...); //1. 查找方式:文件名
int execvp(const char*file, const char *const arg[]);
exec函数名对应名称:
前四位:exec
第五位
l:参数传递为逐个列举方式
v:参数传递为构造指针数组的方式
第六位:
e:可传递新进程环境变量
p:可执行文件查找方式为文件名
函数返回值:-1:出错
如何使用文件名的方式查找可执行文件,同时使用参数列表的方式
这里使用的函数是execlp()
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main()
{
pid_t pid=fork();
if(pid==0)
{
if((ret=execlp("ps","ps","-ef",NULL))<0) //相当于调用了“ps -ef”命令
{
printf("execlp error\n");
}
}
使用完整的文件目录来查找对应的可执行文件。
这里使用的函数是execl()
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
if(fork()==0)
{
if(execl("/bin/ps","ps","-ef",NNULL)<0); //目录必须以“/”开头,否则将视其为文件名
{
printf("execl error\n");
}
}
}
利用execle()将环境变量添加到新建的子进程中
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
char *envp[]={"PATH=/tmp","USER=harry",NULL}; //命令行参数列表,必须以NULL结尾
if(fork()==0)
{
if(execle("/usr/bin/env","env",NULL,envp)<0) //env是查看当前进程环境变量的命令
{
printf("execle error\n");
}
}
}
使用execve()函数,通过构造指针数组的方式来传递参数
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
char *arg[]={"env",NULL};
char *envp[]={"PATH=/tmp","USER=harry",NULL};
if(fork())
{
if(execve("/usr/bin/env",arg,envp)<0)
{
printf("execve error\n");
}
}
}