exec()函数的简单介绍
exec函数族的作用是根据指定的文件名找到可执行的文件,并用它来取代调用进程的内容,话句话说,就是在调用进程内部执行一个可执行文件。
exec函数族的函数执行成功后不会返回,因为调用进程的实体。包括代码段,数据段和堆栈等都已被新的内用取代,只留下进程ID等一些表面上的信息让保持原样。看上去是旧的躯壳,却以注入新的灵魂。只有调用失败了,函数返回-1,从原程序的调用点接着往下执行。
可以使用命令:man 3 exec
查看函数的具体描述:
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
int execve(const char *filename, char *const argv[], char *const envp[]); //这个函数在第二章--man 2 execve
下面介绍两个比较常用的函数:
int execl(const char *path, const char *arg, ...);
参数:
- path:需要指定执行文件的路径或名称(推荐使用绝对路径)
- arg:是执行可执行文件所需要的列表
第一个参数一般没什么作用,为了方便,一般写的实质性程序的名称
从第二个参数往后,就是程序所需要的参数列表
参数最后需要以NULL结尾(哨兵)
返回值:
只有当程序调用失败后,才会有返回值,返回-1,并设置error
如果调用成功,没有返回值
int execlp(const char *file, const char *arg, ...);
- 会到环境变量中查找指定的可执行文件,如果找到了就执行,找不到就执行不成功
参数:
- file:需要执行的可执行文件的文件名
a.out
ps
pwd
- arg:是执行可执行文件所需要的列表
第一个参数一般没什么作用,为了方便,一般写的实质性程序的名称
从第二个参数往后,就是程序所需要的参数列表
参数最后需要以NULL结尾(哨兵)
返回值:
只有当程序调用失败后,才会有返回值,返回-1,并设置error
如果调用成功,没有返回值
下面是execl()
函数和execlp()
函数的简单使用案例:
#include <unistd.h>
#include <iostream>
using std::cout;
using std::endl;
namespace execl_test{
void test01(){
//创建一个子进程,在子进程中执行exec函数族中的函数
pid_t pid = fork();
if(pid > 0){
//父进程
cout << "I am parent process,pid:"<<getpid()<<endl;
sleep(1); //防止孤儿进程
}
else if(pid==0){
//子进程
cout << "I am child process,pid:"<<getpid()<<endl;
//执行一个可执行文件
//execl("hello","hello",NULL);
//或者执行shell命令
//execl("/bin/pwd","pwd",NULL);
execl("/bin/ps","ps","aux",NULL);
//成功进入可执行文件后这行代码不会被执行
cout << "I am child process again"<<endl;
}
}
}
namespace execlp_test{
void test01(){
//创建一个子进程,在子进程中执行exec函数族中的函数
pid_t pid = fork();
if(pid > 0){
//父进程
cout << "I am parent process,pid:"<<getpid()<<endl;
sleep(1); //防止孤儿进程
}
else if(pid==0){
//子进程
cout << "I am child process,pid:"<<getpid()<<endl;
//执行一个可执行文件
//execlp("/home/coder/linux/leason19/hello","hello",NULL);
//或者执行shell命令
//execlp("pwd","pwd",NULL);
execlp("ps","ps","aux",NULL);
//成功进入可执行文件后这行代码不会被执行
cout << "I am child process again"<<endl;
}
}
}
int main(){
//execl_test::test01();
execlp_test::test01();
return 0;
}
下面做一些补充,关于exec函数的后缀单词的介绍:
- l(list) 参数地址列表,以空指针结尾
- v(vector) 存有各参数地址的指针数组
- p(path) 按PATH环境变量指定的目录搜索可执行文件
- e(enviroment) 存有环境变量字符串地址的指针数组
简单介绍:
int execv(const char *path, char *const argv[]);
argv是需要参数的字符串数组
例如:
char* argc[]={"ps","aux",NULL};
execv("/bin/ps",argv);
int execve(const char *filename, char *const argv[], char *const envp[]);
例如:
char* envp[] = {"home/coder/aaa","home/coder/bbb","home/coder/ccc"};
execve("hello",envp);