exec和system函数
程序员文章站
2022-05-07 18:46:19
...
exec函数:
概念:
提供一个在进程中启动另一个程序执行的方法,用新程序取代原调用进程的内存空间,当进程认为自己不能再为系统和用户做出任何贡献时,调用exec函数族让自己重生,如果一个进程想执行另一个程序,调用fork()创建新进程,然后调用exec,这样就实现了通过执行应用程序而产生一个新进程。
函数:
这6个函数在函数名和使用语法的规则上都有细微的区别,下面就可执行文件查找方式、参数传递方式及环境变量这几个方面进行比较说明。
- 查找方式:上表中前4个函数的查找方式都是完整的文件目录路径(即绝对路径),而最后两个函数(也就是以p结尾的两个函数)可以只给出文件名,系统就会自动从环境变量“$PATH”所指出的路径中进行查找。
- 参数传递方式:有两种方式,一种是逐个列举的方式,另一种是将所有参数整体构造成一个指针数组进行传递。(在这里,字母“l”表示逐个列举的方式,字母“v”表示将所有参数整体构造成指针数组进行传递,然后将该数组的首地址当做参数传递给它,数组中的最后一个指针要求时NULL)
- 环境变量:exec函数族使用了系统默认的环境变量,也可以传入指定的环境变量。这里以“e”结尾的两个函数就可以在envp[]中指定当前进程所使用的环境变量替换掉该进程继承的所有环境变量。
函数族关系:
注意:
在使用exec函数族时,一定要加上错误判断语句。因为exec很容易执行失败,其中最常见的原因有:
- 找不到文件或路径,此时errno被设置为ENOENT。
- 数组argv和envp忘记用NULL结束,此时errno被设置为EFAULT。
- 没有对用可执行文件的运行权限,此时errno被设置为EACCES。
/*
主进程用exec执行“ps -a”,用fork创建子进程,
子进程用exec函数替换为执行打印helloworld。
*/
#include"lib.h"
int main()
{
char *argv[]={"ps","-a",NULL};
//第一个子进程
if (fork()==0)
{
//./当前目录下找 第二个相当于参数
if(execlp("./hello","h",NULL)==-1);
{
perror( "execlp error " );
exit(0);
}
}
else
{
printf("\n1---------execl-------\n");
if(execl("/bin/ps","ps","-a",NULL)==-1)
{
perror("excel error");
exit(0);
}
}
wait(NULL);
return 0;
}
system函数:
int system(const char*string)
调用fork()产生子进程,由子进程调用string代表的命令。
返回值:-1出现错误
成功返回子进程退出状态
注意:用system()时执行的程序不能陷入死循环,否则system会一直等待。