良许Linux教程网 干货合集 Linux下exec系列函数详解

Linux下exec系列函数详解

exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件,下面良许教程网为大家详细讲解一下Linux下exec系列函数。

Linux下exec系列函数详解

exec系列函数。都是以execl开头或者execv开头(l表示列表list,v表示矢量vector),exec()函数将当前进程映像替换为新的进程映像, 在ubuntuman execv,则可以看到

 #include 
 
 extern char **environ;
 
 int execl(const char *path, const char *arg, ... /* (char  *) NULL */);
 
 int execlp(const char *file, const char *arg, ... /* (char  *) NULL */);
 
 int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);
 
 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[]);

下面两个是分别man execve和man fexecve之后出现的

 int execve(const char *filename, char *const argv[], char *const envp[]);
 
 int fexecve(int fd, char *const argv[], char *const envp[]);

函数返回值

成功: 函数不会返回

出错: 返回-1,失败原因记录在error中。

函数之间的区别是:

这些函数之间的第一个区别就是execl、execle、execv函数取路径作为参数,execlp、execvp、execvpe取文件名作为参数,当指定的filaname作为参数时: 1、如果filename中包含/,则将视为路径名 2、如果不包含/,则按照PATH环境变量,在它所指定的各个目录中搜寻可执行文件。 第二个区别与参数表的传递有关(l表示列表list,v表示矢量vector) 1、函数execl、execlp、execle要求将新程序的每个命令行参数都说明为一个单独的参数,这种参数以空指针结束。 2、函数execv、execvp、execvpe应该先构造一个指向各个参数的指针数组,然后将该数组的地址作为函数的参数。 在使用ISO C原型之前,对execl、execle、execlp三个函数的表示命令行参数的一般方法是: char *arg0, char *arg1, …, char *argn, (char *)0 需要在最后一个命令行参数之后跟一个char *的空指针,比如上面的表示方法(char *)0 如果不转换成(char *)的指针,那么exec函数的实际参数出错。 第三个区别与向新程序传递环境表有关。 1、execle可以传递一个直线环境字符串指针数组的指针 2、其他的函数则使用进程中的environ变量为新程序复制现有的环境。 通常,一个进程允许将其中环境传播给器子程序,但有时也会有,进程想要为子进程指定某一个确定的环境。在使用ISO C原型之前,execle的参数是:

 char *path, char *arg0, ..., char *argn, (char *)0, char *envp[]

所以,最后一个参数时指向环境字符串的各个字符串构成的数组的指针 关于exec函数,其中名称中的不同字符代表不同的意思: 1、字母p标识改函数去filename作为参数,并且用PATH环境变量寻找你可执行的文件。 2、字母l表示该函数取一个参数表,与字母v互斥,v表示该函数取一个argv[]矢量。 3、字母e表示该函数取envp[]数组,而不是用当前环境。

在这种安排中,库函数execlp和execvp使用PATH环境变量,查找、第一个包含名为filename的可置信文件的路径名前缀,fexecv库函数使用/proc吧文件描述符参数转换为路径名,execve用该路径去执行程序。

下面的图片说明exec函数之间的关系(图片摘自UNIX环境高级编程 第三版):

img

下面的所有的测试代码均以调用新的程序为例

首先,先编写一个简单的测试程序execTest.c,代码如下:

 #include 
 
 
 
 int main(int argc, const char **argv)
 
 {
 
     int ret = 0, i = 0;
 
 
 
     for(i = 0; i 

execTest.c编译生成可执行文件execTest,运行程序,简单的效果如下所示:

img

1、execl函数测试,新建代码文件为execl.c,代码如下:

 #include 
 
 #include 
 
 
 
 int main(int argc, const char **argv)
 
 {
 
     int retval = 0;
 
     
 
     if((retval = execl("/home/songtb/Desktop/songshuai/exec/test", "args0", "args1", "args2", (char *)0)) 

将文件execl.c编译生成可执行文件execl,运行之后的效果为:

img

可以看出,调用的程序正常执行,并且没有打印出retval的值。

2、execlp函数的测试,新建文件execlp.c,代码如下:

 #include 
 
 #include 
 
 extern char **environ;
 
 
 
 int main(int argc, const char **argv)
 
 {
 
     int retval = 0;
 
     
 
     if((retval = execlp("execTest", "abcd", "1234", "myTest", (char *)NULL)) 

编译execlp.c生成可执行文件execlp,直接运行效果为:

img

可以看到提示错误,没有找到文件,那么将execlp中参数修改为如下:

 if((retval = execlp("./execTest", "abcd", "1234", "myTest", (char *)NULL)) 

再次编译执行,可以看出效果为:

img

3、execle函数的测试,新建文件execle.c,代码如下:

 #include 
 
 #include 
 
 
 
 
 
 int main(int argc, const char **argv)
 
 {
 
     char *envp[] = {"USER=songshuai", "PATH=null", NULL};
 
 
 
     if(execle("execTest", "abcd", "1234", "my Test", (char *)NULL, envp))
 
         perror("execle return error ");
 
 
 
     return 0;
 
 }

编译execle.c生成可执行文件execle,直接运行效果为:

img

4、下面的这三个函数(execv、execvp、execvpe),做一个循环调用的效果,新建三个文件,代码分别为:

execv.c

 #include 
 
 #include 
 
 #include 
 
 
 
 int main(int argc, const char **argv)
 
 {
 
     time_t   timep;
 
     time   (&timep);
 
 
 
     char *args[] = {"execv1 args1", "execv2", NULL};
 
     sleep(1);    
 
     printf("I am execv,   Time is : %s", ctime(&timep));
 
 
 
     if(execv("execvp", args))
 
         perror("execvp return error ");
 
     
 
     
 
     return 0;
 
 }

execvp.c

 #include 
 
 #include 
 
 #include 
 
 
 
 int main(int argc, const char **argv)
 
 {
 
     time_t   timep;
 
     time   (&timep);
 
     char *args[] = {"execvp1 args1", "execvp2", NULL};
 
     sleep(1);    
 
     printf("I am execvp,  Time is : %s", ctime(&timep));
 
 
 
     if(execvp("./execvpe", args))
 
         perror("execvp return error ");
 
     
 
     
 
     return 0;
 
 }

execvpe.c

 #include 
 
 #include 
 
 #include 
 
 
 
 int main(int argc, const char **argv)
 
 {
 
     time_t   timep;
 
     time   (&timep);
 
 
 
     char *args[] = {"execvpe1 args1", "execvpe2", NULL};
 
     char *envp[] = {"PATH=/home", "null2", NULL};
 
     sleep(1);
 
     printf("I am execvpe, Time is : %s", ctime(&timep));
 
 
 
     if(execvpe("./execv", args, envp))
 
         perror("execvpe return error ");
 
     
 
     
 
     return 0;
 
 }

编译生成可执行文件,名称为execv、execvp、execvpe;

执行的效果为:

img

可以查看进程管理,这三个进程中每一次都只有以一个进程在运行;

以上就是良许教程网为各位朋友分享的Linux系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你!

137e00002230ad9f26e78-265x300

本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部