exec函数族
fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数去执行另一个程序,当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行,调用exec函数并不创建新进程,所以调用exec前后进程的id没有变化。
将当前进程的.text、.data替换为所要加载的程序的.text、.data,然后让进程从新的.text第一条指令开始执行,但进程id不变。
有6中exec开头的函数,统称exec函数族:
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[ ]);
execlp函数
加载一个进程,借助PATH环境变量。该函数通常用来调用系统程序,如ls,date,cp,cat命令等
int execlp(const char *file,const char *arg,…);
参数:
file:要加载的程序名,该函数需要配合PATH环境变量来使用,当环境变量中所有目录搜索后没有参数file则出错返回
arg:命令行参数
返回值:
成功:无返回;
失败:-1;
execl函数
加载一个进程,通过路径+程序名加载
int execl(const char *path,const char *arg,…);
参数:
path:路径+程序名
arg:命令行参数
返回值:
成功:无返回;
失败:-1;
对比execlp函数,如加载ls命令带有-l,-F参数
execlp(“ls”,“ls”,“-l“,”-F“,NULL);使用程序名在PATH中搜索
execl(“/bin/ls”,“ls”,“-l”,“-F”,NULL);使用参数1给出的绝对路径搜索
execvp函数
加载一个进程,使用自定义环境变量env
int execvp(const char *file,char *const argv[ ]);
参数:
file:要加载的程序名,配合环境变量使用
argv[ ]:命令行参数集合,相当于int main(int argc,char *argv[ ]);
返回值:
成功:无返回
失败:-1
execvp与execlp参数形式不同,原理相同
exec族一般规律
exec函数一旦调用成功即执行新的程序,不返回。只有在失败的时候才返回,返回-1。所以通常可以直接在exec函数调用后直接调用perror()和exit(),无需if判断。
l(list) 命令行参数列表
p(path) 搜索file时使用的环境变量
v(vector) 使用命令行参数数组
e(environment) 使用环境变量数组,不使用进程原有的环境变量,设置新加载程序运行的环境变量
事实上,只有execve是真正的系统调用,其他五个函数最终都调用execve,所以execve在man手册第2页,其他函数在man手册第3页,这些函数关系如下:


浙公网安备 33010602011771号