进程的替换
exec 函数族, 是由六个 exec 函数组成的
         exec 函数族提供: 六种在进程中启动另一个程序的方法
         exec 函数族可根据 指定的文件名或目录名找到 可执行文件
         调用 exec 函数的进程并不创建新的进程, 故调用 exec 前后, 进程的进程号并不会改变, 其执行的程序完全由新的程序替换, 而新程序则从其 main 函数开始执行
      exec 函数族取代调用进程的数据段、 代码段和堆栈段
exec 函数族
  
  
#include <unistd.h>
int execl(const char *pathname,
          const char *arg0,...
          NULL);
int execlp(const char *filename,
           const char *arg0,...
           NULL);
int execle(const char *pathname,
           const char *arg0,..
           NULL,
           char *const envp[]);
int execv(const char *pathname,
          char *const argv[]);
int execve(const char *pathname,
           char *const argv[],
           char *const envp[])       六个 exec 函数中只有 execve 是真正意义的系统调用(内核提供的接口), 其它函数都是在此基础上经过封装的库函数
   l(list):
           参数地址列表, 以空指针结尾。
      参数地址列表:
           char *arg0, char *arg1, ..., char *argn, NULL
v(vector):
          存有各参数地址的指针数组的地址
         使用时,先构造一个指针数组, 指针数组存各参数的地址, 然后将该指针数组地址作为函数的参数
 p(path): 
        按 PATH 环境变量指定的目录搜索可执行文件
        以 p 结尾的 exec 函数取文件名做为参数
       当指定 filename 作为参数时, 若 filename 中包含/, 则将其视为路径名, 并直接到指定的路径中执行程序
 e(environment):
       存有环境变量字符串地址的指针数组的地址
      execle 和 execve 改变的是 exec 启动的程序的环境变量( 新的环境变量完全由 environment 指定), 其他四个函数启动的程序则使用默认系统环境变量
 注意:
        exec 函数族与一般的函数不同, exec 函数族中的函数执行成功后不会返回
只有调用失败了, 它们才会返回- 1
失败后从原程序的调用点接着往下执行
在平时的编程中, 如果用到了 exec 函数族, 一定要记得加错误判断语句
 getenv函数:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    printf("USER = %s\n",getenv("USER"));
    printf("GONGSI = %s\n",getenv("GONGSI"));
    return 0;
}  打印:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    execl("/bin/ls","ls","-a","-l","-h",NULL);
        perror("execl");
    return 0;
}  打印:
execlp函数:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    execlp("ls","ls","-a","-l","-h",NULL);
        perror("execlp");
    return 0;
}  打印:
execv函数
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    char *arg[] = {"ls", "-a", "-l", "-h", NULL};
    execv("/bin/ls",arg);
        perror("execv");
    return 0;
}  打印:
execvp函数:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    char *arg[] = {"ls","-a","-l","-h",NULL};
    execvp("ls",arg);
        perror("execvp");
    return 0;
}  打印:
execve函数:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    char *arg[]={"test", NULL};
    char *env[]={"USER=ME", "GONGSI=AIPU", NULL};
    execve("./test", arg, env);
        perror("execve");
    return 0;
}  一个进程调用 exec 后, 除了进程 ID, 进程还保留了下列特征不变:
         父进程号 , 进程组号 , 控制终端 , 根目录 , 当前工作目录 , 进程信号屏蔽集 , 未处理信号

 京公网安备 11010502036488号
京公网安备 11010502036488号