25.1 介绍

  • 在用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序
  • 当进程调用一种 exec 函数时,该进程完全由新程序代换,替换原有进程的正文,而新程序则从其 main 函数开始执行。因为调用 exec 并不创建新进程,所以前后的进程 ID 并未改变。exec 只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。
  • exec 函数族也称为代码替换函数族

25.1.1 函数说明

 #include <unistd.h>
int execl(const char * path,const char * arg,....);
int execv (const char * path, char * const argv[ ]);
int execle(const char * path,const char * arg,....,char *const envp[]);
int execve(const char * filename,char * const argv[ ],char * const envp[ ]);
int execvp(const char *file ,char * const argv []);
int execlp(const char * file,const char * arg,……);
  • 函数功能:

    • execl()用来执行参数 path 字符串所代表的文件路径,接下来的参数代表执行该文件时传递过去的argv(0)、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
    • execv() 用来执行参数 path 字符串所代表的文件路径,与 execl() 不同的地方在于 execve() 只需两个参数,第二个参数利用数组指针来传递给执行文件。

    • execle() 是用来执行参数 path 字符串所代表的文件路径,并为新程序复制最后一个参数所指示的环境变量。接下来的参数代表执行该文件时传递过去的argv(0)、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
    • execve()用来执行参数 filename 字符串所代表的文件路径,第二个参数系利用数组指针来传递给执行文件,最后一个参数则为传递给执行文件的新环境变量数组。
    • execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。
    • execlp() 会从 PATH 环境变量所指的目录中查找符合参 file 的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的 argv[0]、argv[1]……,最后一个参数必须用空指针 (NULL) 作结束。  
  • 返回值
    • 出错返回 -1,错误码存放,成功则不返回  
  • 错误码
    • EACCES

      • 欲执行的文件不具有用户可执行的权限。 
      • 欲执行的文件所属的文件系统是以 noexec 方式挂上。
      • 欲执行的文件或 script 翻译器非一般文件。
    • EPERM 
      • 进程处于被追踪模式,执行者并不具有 root 权限,欲执行的文件具有 SUID 或 SGID 位。
      • 欲执行的文件所属的文件系统是以 nosuid 方式挂上,欲执行的文件具有 SUID 或 SGID 位元,但执行者并不具有 root 权限。
    • E2BIG 参数数组过大
    • ENOEXEC 无法判断欲执行文件的执行文件格式,有可能是格式错误或无法在此平台执行。
    • EFAULT 参数 filename 所指的字符串地址超出可存取空间范围。
    • ENAMETOOLONG 参数 filename 所指的字符串太长。
    • ENOENT 参数 filename 字符串所指定的文件不存在。
    • ENOMEM 核心内存不足
    • ENOTDIR 参数 filename 字符串所包含的目录路径并非有效目录
    • EACCES 参数 filename 字符串所包含的目录路径无法存取,权限不足
    • ELOOP 过多的符号连接
    • ETXTBUSY 欲执行的文件已被其他进程打开而且正把数据写入该文件中
    • EIO I/O 存取错误
    • ENFILE 已达到系统所允许的打开文件总数。
    • EMFILE 已达到系统所允许单一进程所能打开的文件总数。
    • EINVAL 欲执行文件的ELF执行格式不只一个PT_INTERP节区
    • EISDIR ELF翻译器为一目录
    • ELIBBAD ELF翻译器有问题
  • 注意点
    • execve 函数为系统调用,其余为库函数。执行 execve 函数后面的代码不执行
    • execlp 和 execvp 函数中的 path,相对和绝对路径均可使用,其他四个函数中的 path 只能使用绝对路径。相对路径一定要在进程环境表对应的 PATH 中。
    • argv 参数为新程序执行 main 函数中传递的  argv 参数,最后一个元素为 NULL
    • envp 为进程环境表  
  • 六个函数都使以 "exec"四个字母开头的,后面的字母表示了其用法上的区别:

    • 带有字母 " l " 的函数,表明后面的参数列表是要传递给程序的参数列表,参数列表的第一个参数必须是 要执行的程序,最后一个参数必须是 NULL
    • 带有字母 “ p ”的函数,第一个参数可用是相对路径或程序名,如果无法立即找到要执行的程序,那么就在环境变量 PATH 指定的路径中搜索。其他函数的第一个参数必须是绝对路径
    • 带有字母 " v "的函数,表明程序的参数列表通过一个字符串数组来传递。这个数组和最后传递给程序的 main 函数的字符串数据 argv 完全一样。第一个参数必须是程序名,最后一个参数也必须是 NULL
    • 带有字母 " e " 的函数,用户可用自己设置程序接收一个设置环境变量的数组

  六个函数之间的关系如下:  

  

25.2 例子

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h> char *cmd1 = "cat"; //相对路径
char *cmd2 = "/bin/cat";//绝对路径
char *argv1 = "/etc/passwd";
char *argv2 = "/etc/group"; int main(void)
{
pid_t pid;
if((pid = fork()) < ){
perror("fork error");
exit();
} else if(pid == ) {
//子进程调用 exec 函数执行新的程序
//execl 不带 p 需要用绝对路径的
if(execl(cmd2, cmd1, argv1, argv2, NULL) < ) {
perror("execl error");
exit();
} else {
printf("execl %s success\n", cmd1);
}
} wait(NULL);
printf("=================================\n"); if((pid = fork()) < ){
perror("fork error");
exit();
} else if(pid == ) { char *argv[] = {cmd1, argv1, argv2, NULL};
if(execvp(cmd1, argv) < ) {
perror("execl error");
exit();
} else {
printf("execvp %s success\n", cmd1);
}
} wait(NULL);
printf("=================================\n");
return ;
}

  

二十五、Linux 进程与信号---exec函数的更多相关文章

  1. 二十、Linux 进程与信号---非局部跳转

    20.1 setjmp 和 longjmp 函数 20.1.1 函数介绍 #include <setjmp.h> int setjmp(jmp_buf env); 函数功能:设置非局部跳转 ...

  2. 二十六、Linux 进程与信号---system 函数 和进程状态切换

    26.1 system 函数 26.1.1 函数说明 system(执行shell 命令)相关函数 fork,execve,waitpid,popen #include <stdlib.h> ...

  3. 三十、Linux 进程与信号——信号的概念及 signal 函数

    30.1 信号的基本概念 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化 信号是软件中断 信号是异步事件 ...

  4. 二十三、Linux 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程

    23.1 进程链和进程扇 23.1.1 概念 进程链:一个父进程构建出一个子进程,子进程再构建出子子进程,子子进程构建出子子子进程.... 这种就为进程链 进程扇:一个父进程构建出多个子进程,子进程都 ...

  5. 二十四、Linux 进程与信号---wait 函数

    24.1 wait 函数说明 24.1.1 waitpid---等待子进程中断或结束 waitpid(等待子进程中断或结束) 相关函数 wait,fork #include <sys/types ...

  6. 二十一、Linux 进程与信号---进程查看和进程状态、进程调度和进程状态变化、进程标识

    21.1 进程查看和进程状态 21.1.1 ps 指令 ps 指令通常可以查看到进程的 ID.进程的用户 ID.进程状态和进程的 Command ps:查看当前用户启动的进程 ps -ef:详细查看后 ...

  7. 二十一、Linux 进程与信号---进程资源限制

    21.1 进程资源限制 在操作系统中,我们能够通过函数getrlimit().setrlimit()分别获得.设置每个进程能够创建的各种系统资源的限制使用量. 21.1.1 函数 #include & ...

  8. 二十七、Linux 进程与信号---进程组和组长进程

    27.1 进程组 27.1.1 进程组介绍 进程组为一个或多个进程的集合 进程组可以接受同一终端的各种信号,同一个信号发送进程组等于发送给组中的所有进程 每个进程组有唯一的进程组 ID 进程组的消亡要 ...

  9. Linux学习之CentOS(二十六)--Linux磁盘管理:LVM逻辑卷的创建及使用

    在上一篇随笔里面 Linux学习之CentOS(二十五)--Linux磁盘管理:LVM逻辑卷基本概念及LVM的工作原理,详细的讲解了Linux的动态磁盘管理LVM逻辑卷的基本概念以及LVM的工作原理, ...

随机推荐

  1. 逆元(inv)

    当求解公式:(a/b)%m 时,因b可能会过大,会出现爆精度的情况,所以需变除法为乘法: 设c是b的逆元,则有b*c≡1(mod m): 则(a/b)%m = (a/b)*1%m = (a/b)*b* ...

  2. ArcGIS for qml - 地址地标转换为经纬度(地理编码)

    实现输入地址地标转换为其经纬度 本文链接:地理编码 作者: 狐狸家的鱼 Github: 八至 一.地理编码 1.地理编码含义 地址编码(或地理编码)是使用地址中包含的信息来插入地图上的相应位置的过程. ...

  3. HDU/HDOJ 4864 Task

    贪心题. 贪心方法很是naive...... 首先我们就能注意到一个性质:优先选择时间(x)长的,然后才是等级(y). 所以我们把机器和任务排好序,从大到小枚举任务.对于每一个x满足的机器,x也一定满 ...

  4. 洛谷P3195 玩具装箱

    P3195 [HNOI2008]玩具装箱TOY 第一道斜率优化题. 首先一个基本的状态转移方程是 要使f[i]最小,即b最小. 对于每个j,可以表示为一个点. 然后我们取固定斜率时截距最小的即可,高中 ...

  5. (转)从一道面试题彻底搞懂hashCode与equals的作用与区别及应当注意的细节

    背景:学习java的基础知识,每次回顾,总会有不同的认识.该文系转载 最近去面试了几家公司,被问到hashCode的作用,虽然回答出来了,但是自己还是对hashCode和equals的作用一知半解的, ...

  6. Python模块之time、random、os、sys、序列化、re

    Time模块 和时间有关系的我们就要用到时间模块.在使用模块之前,应该首先导入这个模块. #常用方法 1.time.sleep(secs) (线程)推迟指定的时间运行.单位为秒. 2.time.tim ...

  7. ubuntu下 pthread_mutex_init man中查不到

    问题: 如题所述,包括pthread_mutex_init 和 pthread_mutex_lock 这些函数都找不到 解决办法: 安装manpages:manpages-posix-dev Mint ...

  8. plsql界面/command界面

    存储过程执行CALL PRO_DELETE_OND_FOR_ORDERNO('120000000208');    --在PLSQL的SQL窗口执行 EXEC PRO_DELETE_OND_FOR_O ...

  9. Linux基础-兄弟连Linux

    Linux基础增强与辅助知识梳理... ------------ Linux学习基础需要学习那些知识 学习Linux对于程序开发的好处 怎样开始学习Linux Linux的学习方法参考 Linux系统 ...

  10. python机器学习-sklearn挖掘乳腺癌细胞(三)

    python机器学习-sklearn挖掘乳腺癌细胞( 博主亲自录制) 网易云观看地址 https://study.163.com/course/introduction.htm?courseId=10 ...