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页,这些函数关系如下:

 

 

posted @ 2021-02-15 15:15  さくらむすび  阅读(195)  评论(0)    收藏  举报