• exec函数族


    exec函数族

    fork()函数创建子进程后,子进程往往要调用一种e x e c函数以执行另一个程序。当进程调用一种exec函数时,该进程完全由新程序代换,而新程序则从其 ma i n函数开始执行。 因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。 有六种不同的e x e c函数可供使用,它们常常被统称为exec函数。

    #include<unistd.h>  
    int execl(const char *pathname, const char * arg0,.../*(char*)0*/);  
    int execv(const char *pathname, char *const argv[]);  
    int execle(const char *pathname,const char * arg0,.../*(char*)0,char *const envp[]*/);  
    int execve(const char *pathname, char *const argv[],char * const envp[]);  
    int execlp(const char *filename, const char * arg0,.../*(char*)0*/);  
    int execvp(const char *filename, char *const argv[]);  
    //六个函数返回:若出错则为-1,若成功则不返回  

    这些函数之间的第一个区别是前四个取路径名作为参数,后两个则取文件名作为参数。当指定filename作为参数时:

    如果filename中包含/,则就将其视为路径名。否则就按PAT H环境变量,在有关目录中搜寻可执行文件。

    PATH变量包含了一张目录表 (称为路径前缀),目录之间用冒号( : )分隔。例如下列na me = value环境字符串:

    PATH = /bin:/usr/bin:/usr/local/bin: 指定在四个目录中进行搜索。(零长前缀也表示当前目录。在value的开始处可用:表示,在行中间则要用::表示,在行尾以:表示。)

    如果execlp和execvp中的任意一个使用路径前缀中的一个找到了一个可执行文件,但是该文件不是由连接编辑程序产生的机器可执行代码文件,则就认为该文件是一个 shell脚本,于是 试着调用/bin/sh,并以该filename作为shell的输入。第二个区别与参数表的传递有关 ( l表示表( l i s t ),v表示矢量( v e c t o r ) )。函数execl、execlp和execle要求将新程序的每个命令行参数都说明为一个单独的参数。这种参数表以空指针结尾。

    对于另外三个函数( execv, execvp和execve ),则应先构造一个指向各参数的指针数组,然后将该数组地址作为这三个函数的参数。 在使用ANSIC原型之前,对execl , execle和execlp三个函数表示命令行参数的一般方法是: char *arg 0, char *arg 1, ..., char *arg n, (char *) 0 应当特别指出的是:在最后一个命令行参数之后跟了一个空指针。如果用常数 0来表示一个空指针,则必须将它强制转换为一个字符指针,否则它将被解释为整型参数。如果一个整型数的长度与char *的长度不同,exec函数实际参数就将出错。 最后一个区别与向新程序传递环境表相关。以e结尾的两个函数( execle和execve)可以传递一个指向环境字符串指针数组的指针。其他四个函数则使用调用进程中的 environ变量为新程序复制现存的环境。通常,一个进程允许将其环境传播给其子进程,但有时也有这种情况,进程想要为子进程指定一个确定的环境。

    例如,在初始化一个新登录的 shell时,login程序创建一个只定义少数几个变量的特殊环境,而在我们登录时,可以通过 shell启动文件,将其他变量加到环境中。

    在使用 ANSI C原型之前, execle 的参数是:char * pathname, char *arg 0, ⋯, char *a rg n, (char *)0, char *envp[ ] 从中可见,最后一个参数是指向环境字符串的各字符指针构成的数组的指针。而在 ANSIC原型中,所有命令行参数,包括空指针,e n v p指针都用省略号(⋯)表示。 这六个e x e c函数的参数很难记忆。函数名中的字符会给我们一些帮助。字母 p表示该函数

    取filename作为参数,并且用PATH环境变量寻找可执行文件。字母l表示该函数取一个参数表,它与字母v互斥。v表示该函数取一个arg v[ ]。最后,字母e表示该函数取e nvp[ ]数组,而不使用当前环境

    这六个函数中只有一个execve是内核的系统调用。另外五个只是库函数,它们最终都要调用系统调用。这六个函数之间的关系示于图8 - 2中。在这种安排中,库函数 execlp 和execvp 使用PATH环境变量查找第一个包含名为filename的可执行文件的路径名前缀。

    例1:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<unistd.h>
     4 
     5 int main(int argc,char * argv[])
     6 {
     7     if(argc<2)
     8     {
     9         perror("you haven't input the filename,please try again!
    ");
    10         exit(EXIT_FAILURE);
    11     }
    12     if(execl("./create_file","create_file",argv[1],NULL)<0)
    13         perror("execl error");
    14 }

    可以看见的是有一个名为create_file的可执行文件用于创建文件。在这里我们使用execl函数替换程序。

     

    例2:

    代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<unistd.h>
     4 
     5 int main(int argc,char * argv[])
     6 {
     7         if(argc<2)
     8         {
     9                 perror("you haven't input the filename,please try again!
    ");
    10                 exit(EXIT_FAILURE);
    11         }
    12         if(execl("/bin/touch","touch",argv[1],NULL)<0)
    13                 perror("execl error");
    14 }                                                                

    可以看见我们将exec2 成功的替换为了touch。并成功的执行了。

     

    参考资料

    Linux/Unix系统编程手册

    Unix环境高级编程

    Linux程序设计

  • 相关阅读:
    几个概率题
    几个智力题。。
    [算法]各种二分查找
    深入 JavaScript 时间对象 Date
    Leaflet 调用百度瓦片地图服务
    JavaScript中进制和字符编码问题
    DOM事件流
    flex 弹性布局
    javascript 闭包内部机制
    HTML DOM setAttribute()、与createAttribute()
  • 原文地址:https://www.cnblogs.com/mumu597/p/12897935.html
Copyright © 2020-2023  润新知