linux--exec函数族浅析
本篇博客经参考资料1整理、修改而成。
1 exec 函数执行时,是用一个全新的程序代替了当前进程的正文、数据、堆栈段,但是它并没有改变进程ID,执行后进程ID依旧是之前的进程ID。其函数原型如下:
#include <unistd.h>extern char **environ;int execl(const char *pathname, const char *arg, .../* (char *) NULL */);int execlp(const char *file, const char *arg, .../* (char *) NULL */);int execle(const char *pathname, const char *arg, .../*, (char *) NULL, char *const envp[] */);int execv(const char *pathname, char *const argv[]);int execvp(const char *file, char *const argv[]);int execvpe(const char *file, char *const argv[],char *const envp[]);
此6个函数按照exec后面的参数可以分为以下3类:
(1)带‘l’的。l是list,是指函数的参数以list的形式出现的,参数形式如下:arg0,arg1...argn,最后一个参数须以(char *)NULL结束。主要函数有execl(), execlp(), execle()。通常情况下,第一个参数是路径名,如果是完整路径名,则执行完整路径名,如果只是文件名,则从进程当前工作目录寻找。
程序1:execl.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>int main(int argc, char *argv[])
{printf("before execl\n");if(execl("/bin/ls","ls","-l",(char *)0)==-1){fprintf(stderr,"execl error ,error is %d,msg is %s\n",errno,strerror(errno));}printf("after execl\n");exit(0);
}
程序执行后,会用全新的程序替代当前进程,执行结果如下:
可以看出,程序执行结束后,"after execl" 没有打印出来,因为进
程上下文已被切换成新的,原程序不再执行。如果pathname 使用文件名,当从当前工作目录查找,如果查找不到,便会出错。
修改execl.c源文件中的execl行为(execl2.c):
if(execl("ls","ls","-l",(char *)0)==-1)
显示找不到文件,后main继续执行,打印出了“after execl”。如果更改工作目录为/bin,因为/bin目录有ls的执行文件,所以程序执行结果一样成功,类似第一个结果截图。
(2)带‘v’的,v 是vector,代表参数是以vector的形式出现,参数个数总数为2个,第二个参数为指针数组char *const argv[],代表了后面的参数以指数组的形式出现,并且以空指针NULL结束。主要函数有execv(), execvp(), execvpe()。第一个参数pathname的意义与execl的第一个参数pathname 相同。
源程序execv.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>int main(void)
{printf("before execl\n");char *argv[]={"ls","-l",(char *)0};if(execv("/bin/ls",argv)==-1){fprintf(stderr,"execv error ,error is %d,msg is %s\n",errno,strerror(errno));}printf("after execl\n");exit(0);
}
执行结果如下:
(3)带‘p’的,p 代表“PATH”,是指程序的第一个参数filename ,是从当前环境变量PATH值寻找,即如果第一个参数不是完整路径的话,将从PATH寻找可执行文件,也包括当前工作目录。如果第一个参数中有‘/’,则PATH寻找过程被忽略。主要函数有:execlp(), execvp(), execvpe()。
源程序execlp.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>int main(int argc, char *argv[])
{printf("before execl\n");if(execlp("ls","ls","-l",(char *)0)==-1){fprintf(stderr,"execlp error ,error is %d,msg is %s\n",errno,strerror(errno));}printf("after execl\n");exit(0);
}
执行结果如下
因为新建的文件越来越多,所以输出结果会相应的增加。
(4)带‘e’的。'e'代表environment,是指程序将当前的环境变量替换为参数char *const envp[]指向的环境表,并执行程序。这样的函数都有带有一个参数char *const envp[],出现在函数参数表中的位置均为最后一个位置。主要的函数有两个execle(), execvpe(),就是其它四个函数是用调用进程的环境表environ来执行,而这两个函数是用envp 代替environ 来执行,envp 是一个指针数组,以NULL 结束。
以下程序先打印当前环境表envrion的值,然后创建新环境表,并打印出来。
源程序:printenv.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>extern char **environ;int main(void)
{
char **p=environ;
while(*p)
{
printf("%s\n",*p);
p++;
}
exit(0);
}
输出执行文件,gcc printenv.c -o printenv ,
源程序execl3.c,先打印当前进程的环境表
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>int main(int argc, char *argv[])
{printf("before execl\n");if(execl("printenv","printenv",(char *)0)==-1){fprintf(stderr,"execl error ,error is %d,msg is %s\n",errno,strerror(errno));}printf("after execl\n");exit(0);
}
输出结果是进程中当前环境表的值
然后利用execle 函数打印新环境表的值
源程序execle.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>int main(int argc, char *argv[])
{printf("before execl\n");char * envp[]={"AA=11","BB=22","cc=33",NULL};if(execle("printenv","printenv",(char *)0,envp)==-1){fprintf(stderr,"execle error ,error is %d,msg is %s\n",errno,strerror(errno));}printf("after execl\n");exit(0);
}
输出结果如下:
可以看到环境表已经替换。
2 函数返回值。
上述6个函数,没有正确返回值,只有出错返回值,出错时,函数返回-1,并赋值errno,常见的错误码如下:
(1)E2BIG:envp,arg0等参数表太大
(2)EACCES :第一个参数执行权限不允许
(3)ENOENT:第一个参数文件或路径不存在
(4)ENOEXE 执行文件出错
3 补充
exec函数执行成功时,执行新程序的进程除了进程ID 不变外,还有下面项保持不变。
(1)进程ID 和父进程ID
(2)实际用户ID和实际组ID
(3)附加组ID
(4)进程组ID
(5)会话ID
(6)控制终端
(7)闹钟尚预留时间
(8)当前工作目录
(9)根目录
(10)文件模式创建屏蔽字
(11)文件锁
(12)进程信号屏蔽
(13)未处理信号
(14)资源限制
(15)tms_utime、tsm_stime、tms_cutime、tms_cstime
(16)environ(带‘e’函数的除外)。
参考资料:
(1)https://www.cnblogs.com/mickole/p/3187409.html
(2)https://man7.org/linux/man-pages/man3/execl.3.html
(3)https://man7.org/linux/man-pages/man2/execve.2.html
linux--exec函数族浅析相关推荐
- 12.Linux:exec函数族
(1)exec函数说明 fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法.它可以根据指定的 ...
- Linux下进程的建立 并附Linux exec函数族
我们都知道,进程就是正在执行的程序.而在Linux中,可以使用一个进程来创建另外一个进程.这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看 ...
- Linux exec函数族
如果我们使用fork()函数创建一个子进程,则该子进程几乎复制了父进程的全部内容,也就是说,子进程与父进程在执行同一个可执行程序.那么我们能否让子进程不执行父进程正在执行的程序呢? exec函数族提供 ...
- Linux——exec函数族原理及特性、execlp和execl函数
一.exec函数族原理 fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序. 当进程调用一种exec函数时,该进程的用户空间 ...
- Linux进程控制——exec函数族
1.简介 在Linux中,并不存在exec()函数,exec指的是一组函数,一共有6个,分别是: #include <unistd.h> extern char **environ; in ...
- 【Linux系统编程】进程替换:exec 函数族
00. 目录 文章目录 00. 目录 01. exec函数族 02. 参考示例 2.1 execl函数示例 2.2 execv函数示例 2.3 execlp() 或 execvp()函数示例 2.4 ...
- Linux系统编程--3(exec 函数族,僵尸进程和孤儿进程,wait和wait_pid回收子进程)
exec 函数族 fork 创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支) ,子进程往往要调用一种 exec 函数以执行另一个程序.当进程调用一种 exec 函数时,该进程的用户 ...
- 【Linux系统编程学习】Linux进程控制原语(fork、exec函数族、wait)
此为牛客Linux C++和黑马Linux系统编程课程笔记. 1. fork函数 1.1 fork创建单个子进程 #include<unistd.h> pid_t fork(void); ...
- Linux进程实践(3) --进程终止与exec函数族
进程的几种终止方式 (1)正常退出 从main函数返回[return] 调用exit 调用_exit/_Exit (2)异常退出 调用abort 产生SIGABOUT信号 由信号终止 Ctrl+ ...
- Linux多任务编程(三)---exec函数族及其基础实验
exec函数族 函数族说明 fork() 函数用于创建一个新的子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的子进程如何执行呢?exec 函数族就提供了一个在进程中启动另一个程序执行的方 ...
最新文章
- 还在为论文发愁?ACL组委会手把手教你论文投稿小技巧 | ACL 2017
- Micron Flash芯片识别心得
- Leetcode 189. 旋转数组 (每日一题 20210909)
- mysql数据的引用_MySQL数据库入门:mysql操作和程序引用
- 蓝牙模块音频BLE数据数传串口AT指令的使用方法
- intellij 快捷键_IntelliJ中的键盘快捷键
- c#设置开机自动启动程序本篇文章来源于:
- Linux的网络管理命令使用总结
- DXUT框架剖析(2)
- CoffeeScript、TypeScript 、 JavaScript 之间
- 服务器测试文档格式,服务器测试文档格式
- python HTTP请求过程
- 更新ADT20后无法创建Android项目
- JavaScript 打开新页面
- ubuntu安装中文输入法fcitx
- c语言求余运算作用,C语言中的整数除法和求余运算
- 我用php构建了魔兽世界服务器,只为证明php是世界上最好的语言
- 无法安装NET Framework3.5错误代码0x800F081F
- Java Web安全之代码审计
- 《地球概论》(第3版)笔记 第四章 地球运动的地理意义
热门文章
- 重装jdk后运行java程序出现Error: could not open `C:\Program Files\Java\jre68\lib\amd64\jvm.cfg'的解决办法
- vb怎么判断整数_VB数学函数大全
- 论述计算机与外设的访问控制方法,试论述计算机与外设访问控制的方法有多少种各有什么优缺点...
- java中取系统时间_JAVA中获取当前系统时间(示例代码)
- linux替换指定行指定列的内容,linux – sed替换特定行号的特定列号值
- windows下使用命令行将employees.sql导入mysql
- 笔记本windows7设置WIFI教程(超详细)
- sql server datetime取年月_快速定位数据库性能问题,RDS推出慢SQL统计分析
- linux漏洞知乎_Linux本地内核提权漏洞(CVE-2019-13272)
- 使用JAVA加jxl jar操作EXECL