exec函数

     fork、vfork和clone三个函数要是Linux用来创建新的进程(线程)而设计的,exec()系列函数则是用来用指定的程序替换当前进程的所有内容。所以exec()系列函数经常在前三个函数使用之后调用,来创建一个全新的程序运行环境。Linux用init进程启动其他进程的过程一般都是这样的。  

      exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,主要是在fork()之后,它会诱导fork后的子进程另起炉灶,但是PID不变,自己开创一片新天地,清空原来的堆栈区、代码区和数据区,让新的可执行程序完全替代现有的资源。换句话说,就是在调用进程内部执行一个可执行文件,这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。与一般情况不同,exec函数族的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样,颇有些神似"三十六计"中的"金蝉脱壳"。看上去还是旧的躯壳,却已经注入了新的灵魂。只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。

6个exec函数族:

(1)int execl(const char *path, const char *arg, ......);  
(2)int execle(const char *path, const char *arg, ...... , char * const envp[]);  
(3)int execv(const char *path, char *const argv[]);  
(4)int execve(const char *filename, char *const argv[], char *const envp[]);  
(5)int execvp(const char *file, char * const argv[]);  
(6)int execlp(const char *file, const char *arg, ......);
注:其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。
exec调用举例如下:
char *const ps_argv[] ={"ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL};
char *const ps_envp[] ={"PATH=/bin:/usr/bin", "TERM=console", NULL};
execl("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
execv("/bin/ps", ps_argv);
execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL, ps_envp);
execve("/bin/ps", ps_argv, ps_envp);
execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
execvp("ps", ps_argv);
请注意exec函数族形参展开时的前两个参数,
      第一个参数是带路径的执行码(execlp、execvp函数第一个参数是无路径的,系统会根据PATH自动查找然后合成带路径的执行码);
      第二个是不带路径的执行码,执行码可以是二进制执行码和Shell脚本。
exec函数族使用注意点

(1)在使用exec函数族时,一定要加上错误判断语句。

      因为exec很容易执行失败:判断execl的返回值,如果出错,可以用perror( )函数打印出错误信息。

如:因为错误返回-1;成功没有返回值;

if (execl(“path”,”..””(char *)0) < 0)
{
        perror(“execl error!”);
}

如果调用出错,可输出:execl error!: 错误原因   这样可方便查找出错原因

(2)execl调用shell 时,要在shell脚本中指明使用的shell版本

        : #!/bin/bash。在命令行下执行shell脚本,系统为它自动打开一个shell,在程序中没有shell,在调用shell脚本时,会出错,所以要在shell脚本中先打开shell。

其中最常见的原因有:

    ①找不到文件或路径,此时errno被设置为ENOENT。
    ②数组argv和envp忘记用NULL结束,此时errno被设置为EFAULT。
    ③没有对应可执行文件的运行权限,此时errno被设置为EACCES。




  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值