exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。另外,这里的可执行文件既可以是二进制文件,也可以是 Linux 下任何可执行的脚本文件。
在Linux中使用exec函数族主要有两种情况:
(1)当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec函数族让自己重生;
(2)如果一个进程想执行另一个程序,那么它就可以调用 fork 函数新建一个进程,然后调用任何一个 exec,这样看起来就好像通过执行应用程序而产生了一个新进程。 (这种情况非常普遍)
exec函数族有下列6个函数:
#include
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(constchar* path,char* const argv[]);
int execvp(const char* file,char* const argv[]);
int execve(const char* path, char* const argv[],char * const envp[]);
Execlp实例
/*execlp.c*/
#include
#include
#include
int main()
{
if(fork()==0)
{
/*调用execlp函数,这里相当于调用了“ps”命令*/
if(execlp("ps","ps",NULL)<0)
perror("execlp error!");
}
}
将源码文件execlp.c保存到/nfs/project目录下并交叉编译:
[root@localhost project]# arm-linux-gcc -o execlp execlp.c
Execlp运行
在该程序中,首先使用fork函数新建一个子进程,然后在子进程里使用execlp函数。可以看到,这里的参数列表就是在shell中使用的命令名和选项。并且当使用文件名的方式进行查找时,系统会在默认的环境变量 PATH 中寻找该可执行文件。将编译后的结果下载到目标板上,运行结果如下所示:
Execle实例
/*execle.c*/
#include
#include
#include
int main()
{
/*命令参数列表,必须以NULL结尾*/
char *envp[]={"PATH:=/tmp:$PATH",NULL};
if(fork()==0){
/*调用execle函数,注意这里也要指出env的完整路径*/
if(execle("/usr/bin/env","env",NULL,envp)<0)
perror("execle error!");
}
return 1;
}
将源码文件execlp.c保存到/nfs/project目录下并交叉编译:
[root@localhost project]# arm-linux-gcc -o execle execle.c
Execle运行
exec函数族使用注意点:
在使用 exec 函数族时,一定要加上错误判断语句。因为 exec 很容易执行失败,其中最常见的原因有:
找不到文件或路径,此时errno被设置为 ENOENT;
数组argv和envp忘记用NULL结束,此时errno被设置为 EFAULT;
没有对应可执行文件的运行权限,此时errno被设置为 EACCES。
阅读(1420) | 评论(0) | 转发(1) |