linux系统编程-exec函数族

exec函数族

  • fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。
  • 当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。
  • 调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

execlp函数

  • int execlp(const char *file, const char *arg, …):加载一个进程,借助PATH环境变量
  • 参数1:要加载的程序的名字(该参数需要配合PATH环境变量来使用,当PATH中所有目录搜索后没 有参数1则出错返回)
  • 参数 2、3…:argv[0]、argv[2]、…NULL(必须以NULL结尾)
  • 该函数通常用来调用系统程序。如:ls、date、cp、cat等命令。

实例代码:

   #include <stdio.h>
   #include <unistd.h>
   #include <stdlib.h>
   
   
   
   int main(void)
   {

        pid_t pid;
        pid = fork();
 
         if(pid<0)
         {
                 perror("fork error");
                 exit(1);
         }

         else if(pid>1)
         {
                 printf("i am parent");
                sleep(1);
         }
 
         else
         {
              int tmp = execlp("ls","ls","-l","-a",NULL);  //子进程执行 ls -al 命令
                 
                 if(tmp<0)
                 exit(1);
         }

         return 0;
 }

结果:运行app程序 和 运行 ls -al 命令结果一样

在这里插入图片描述


execl函数

  • int execl(const char *path, const char *arg, …):加载一个进程, 通过 路径来加载。
  • 对比execlp,如加载 “ls” 命令带有-l,-F参数
    execlp(“ls”, “ls”, “-l”, “-F”, NULL); 使用程序名在PATH中搜索。
    execl("/bin/ls", “ls”, “-l”, “-F”, NULL); 使用参数1给出的绝对路径搜索。

execle函数

  • int execle(const char *path, const char *arg, …, char *const envp[] ):使用路径调用程序,使用新的环境变量数组设置被调用的程序的环境变量

hello.c : 输出自己pid和环境变量

 #include <stdio.h>
 #include <unistd.h>
 extern char** environ;
 
 int main(void)
{
        printf("hello pid is:%d \n" ,getpid() );
        
        int i;
        for(i=0;environ[i];i++)
                 printf("%s\n",environ[i]);
         return 0;
}

直接运行的结果:
在这里插入图片描述
app.c

 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>

 int main(void)
 {

         pid_t pid;
         pid = fork();
 
        if(pid<0)
        {
                 perror("fork error");
                 exit(1);
         }
 
         else if(pid>1)
         {
                 printf("i am parent\n");
                 sleep(1);
         }

         else
         {
              char* envp[]={"AA=BBCCDD",NULL};
              int tmp = execle("./xx/hello","app1",NULL,envp); //hello 上面的程序

                 if(tmp<0)
                 {
                         exit(1);
                         printf("child dead");
                }
         }
 
         return 0;
 }

执行结果: hello 进程的 环境变量 变成 AA=BBCCDD
在这里插入图片描述


execv函数

  • int execv(const char *path, char *const argv[]);
 char* argv[]={"ls", "-l","-a","NULL"};
 execv("/bin/ls",argv)

execvp函数

  • int execvp(const char *file, char *const argv[]) :
 char* argv[]={"ls", "-l","-a","NULL"};
 execv("ls",argv)// ls借助PATH环境变量

execve函数

  • int execve(const char *path, char *const argv[], char *const envp[])

小结

  • 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(const char *path, char *const argv[]);
  • int execvp(const char *file, char *const argv[]);
  • int execve(const char *path, char *const argv[], char *const envp[]);

(1)

  1. path:传递的是可执行程序的路径
  2. file:可执行程序名,依靠环境变量来找
  3. arg:传递 “argv[0]” ,“argv[1]”,…NULL
  4. argv[]: 定义一个字符串指针数组(命令行参数) 传进去 :char* argv[]={“ls”, “-l”,"-a",“NULL”};:
  5. envp[]: 定义一个字符串指针数组(环境变量) 传进去: char* envp[]={“AA=BBCCDD”,NULL};

(2)

  • l (list)         命令行参数列表
  • p (path)       搜素file时使用path变量
  • v (vector)       使用命令行参数数组
  • e (environment)   使用环境变量数组 ,不使用进程原有的环境变量,设置新加载程序运行的环境变量

(3)

  • 事实上,只有execve是真正的系统调用,其它五个函数最终都调用execve,所以execve在man手册第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zzyczzyc/article/details/82937927
今日推荐