系统调用execve()函数作用

在Linux程序中,通过调用execve(),进程能够以全新程序来替换当前运行的程序。再次过程中,将丢弃旧有程序,进程的栈.数据以及堆段会被新程序所替换。这个 exec 函数族就提供了一个在进程中启动另一个程序执行的方法。
它根据指定的文件名或目录名找到可执行文件,并用它来代替当前进程的执行映像。也就是说,exec调用并没有生成新进程,一个进程一旦调用 exec函数,它本身就“死亡”了,系统把代码段替换成新程序的代码,放弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,惟一保留的就是进程的 ID。也就是说,对系统而言,还是同一个进程,不过执行的已经是另外一个程序了。

execve()函数原型

#include <unistd.h>
int execve(const char *filename, char *const argv[],char *const envp[]);
  1. filename:包含准备载入当前进程空间的新程序的路径名。既可以是绝对路径,又可以是相对路径。
  2. argv[]:指定了传给新进程的命令行参数,该数组对应于c语言main函数的argv参数数组,格式也相同,argv[0]对应命令名,通常情况下该值与filename中的basename(就是绝对路径的最后一个)相同。
  3. envp[]:最后一个参数envp指定了新程序的环境列表。参数envp对应于新程序的environ数组。

实例1

下面的每个代码我都放到了github上,欢迎大家fork/star
GeneralSandman
t_execve.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<string.h>
int main(int argc,char * argv[]){char * argVec[10];char * envVec[]={"环境变量1","环境变量2",NULL};argVec[0]=argv[0];argVec[1]=argv[1];argVec[2]="参数1";execve(argv[1],argVec,envVec);printf("the progress can't to here\n");exit(EXIT_SUCCESS);
}

envargs.c
下面的每个代码我都放到了github上,欢迎大家fork/star
GeneralSandman

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
extern char ** environ;
int main(int argc,char * argv[]){int i=0;char ** ep;printf("new progress\n");printf("参数\n");for(i=0;i<argc;i++)printf("\t%s\n",argv[i]);printf("环境变量:\n");for(ep=environ;*ep!=NULL;ep++)printf("\t%s\n",*ep);printf("new progress over\n");exit(EXIT_SUCCESS);return 0;
}

运行结果

程序说明

运行t_execve程序,会调用execve()函数,函数将会调用进程argv[1],也就是调用envargs,并将自己的环境变量,参数传递给他。我们发现,printf(“the progress can’t to here\n”); 永远不会被执行(除非调用execve()失败),因为调用execve(),会转到新的进程,自己会被“杀死”;

实例2

t_execve2.c
下面的每个代码我都放到了github上,欢迎大家fork/star
GeneralSandman

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<string.h>
#include<sys/wait.h>
int main(int argc,char * argv[],char ** environ){pid_t pid;printf("the example!!!\n");switch(fork()){case -1:printf("fork error\n");exit(EXIT_FAILURE);case 0:printf("child is running\n");printf("child pid=%d, child parent pid=%d\n",getpid(),getppid());printf("child uid=%d, child gid=%d\n",getuid(),getpid());execve(argv[1],argv,environ);printf("child can't in here\n");break;default:wait(NULL);printf("parent is running\n");break;}exit(EXIT_SUCCESS);
}

envargs2.c
下面的每个代码我都放到了github上,欢迎大家fork/star
GeneralSandman

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<string.h>
int main(int argc,char * argv[],char ** environ){int i;printf("running after the execve()\n");printf(" pid=%d,  parent pid=%d\n",getpid(),getppid());printf(" uid=%d,  gid=%d\n",getuid(),getpid());printf("the immage over\n");exit(0);
}

运行结果

程序说明

运行t_execve2程序,fork()之后,子进程会调用execve()函数,而父进程会等待子进程退出(也就是等待envargs2退出)。我们发现:执行新程序保持了原来进程的进程 ID、父进程ID、实际用户 ID 和实际组 ID。同时还可以看到,当调用新的可执行程序后,原有的子进程的映像被替代,不再被执行。

执行新程序后的进程除了保持原来的进程 ID、父进程 ID、实际用户 ID 和实际组 ID 之外,进程还保持了许多原有的特征,主要有:

  1. 当前工作目录
  2. 根目录
  3. 创建文件时使用的屏蔽字
  4. 进程信号屏蔽字
  5. 未决警告
  6. 和进程相关的使用处理器的时间
  7. 控制终端
  8. 文件锁

exec族

有 6 个以 exec 开头的函数族,他们之间的语法有细微的差别,函数原型如下所示:

  1. int execl(const char *path, const char *arg, …)
  2. int execv(const char *path, char *const argv[])
  3. int execle(const char *path, const char *arg, … , char *const envp[])
  4. int execve(const char *path, char *const argv[], char *const envp[])
  5. int execlp(const char *file, const char *arg, …)
  6. int execvp(const char *file, *const argv[])

区别

实际上有关exec是一个函数族,包括execle,execlp,execvp,execv,execl但是他们具体的实现都是调用execve()之上。它们的区别就在于对路径名,参数以及环境变量的指定上。下面分别从这三个方面来区分这几个函数:
- 路径名:带p的表示可以通过环境变量PATH去查找,所以我们可以不用绝对路径,比如execlp和execvp就可以直接用filename。
- 参数:带l的execle()和execlp()以及execl()要求在调用中以字符串形式指定参数。首个参数相当于新程序main中的argv[0],因而通常与filename中的basename相同(就是绝对路径的最后一个)。
- 环境变量:以e结尾的允许我们通过envp为新程序显式的指定环境变量,其中envp必须以NULL结尾。

Linux 执行新程序:execve() 函数相关推荐

  1. 用exec()函数执行新程序

    使用fork或vfork创建子进程后,子进程通常会调用exec函数来执行另外一个程序.系统调用exec用于执行一个可执行程序以代替当前进程的执行映像. exec调用没有生成新进程.一个进程一旦调用ex ...

  2. Linux系统运行Windows程序(Linux执行windows程序)

    dpkg --add-architecture i386 && apt-get update && apt-get install wine32 需要安装32位wine ...

  3. linux执行指定程序的命令,linux 下使用指定的用户来执行命令

    有时间,我们需要在开机的时候执行一些特定的程序或都脚本,因为涉及到安全主面的问题,所以又不想用root来执行,那怎样办呢. 经过查看 su 的帮助提示,发现: [root@redhat6 ~]# su ...

  4. 在进程中执行新代码 execl、execle、execlp、execv、execve和execvp函数

    在进程中执行新代码 execl.execle.execlp.execv.execve和execvp函数 摘要:本文主要讲述怎样在进程中执行新代码,以及exec系列函数的基本用法. 在进程中执行新代码 ...

  5. Linux系统调用之execve函数与标准C库exec函数族(有关于进程方面的函数族)

    前言 如果,想要深入的学习Linux系统调用里面的execve函数与标准C库中的exec函数族,还是需要去自己阅读Linux系统中的帮助文档. 具体输入命令: man 2 execve man 3 e ...

  6. linux 脚本 java_Linux 通过脚本执行Java程序

    由于要统计不同的IP,代码中应用了HashSet来存放IP地址. 上述Java程序是在Windows下编写的,如果在Linux服务器上运行,只需要把上面文件的路径和文件更换了就可以了. 2.编写好ja ...

  7. Unix/Linux编程:exec()族函数

    执行新程序:execve() 系统调用execve()可以将新程序加载到某一进程的内存空间.在这一操作过程中,将丢弃就有程序,而进程的栈.数据以及堆段会被新程序的相应不见所替换.在执行了各种C语言函数 ...

  8. Linux内核Hook系统调用execve

    资源下载地址:linux内核hook系统调用execve函数-Linux文档类资源-CSDN下载 (已在内核为 4.19.0-amd64-desktop版本uos编译通过,并成功达到目的) 在Linu ...

  9. linux exec 二程序,二十五、Linux 进程与信号---exec函数

    25.1 介绍 在用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序 当进程调用一种 exec 函数时,该进程完全由新程序代换,替换原有进程的正文,而新程序则从其 m ...

最新文章

  1. 对付网络盗贼的三板斧
  2. DDD领域驱动设计特点及难点
  3. 导出EXCEL2003
  4. 拉格朗日插值法(Lagrange)
  5. Linux上安装wkhtmltopdf,以及调试所遇到的问题
  6. STM8单片机串口同时识别自定义协议和Modbus协议
  7. Oracle数据库是如何执行SQL的
  8. 搞懂这三个指标,数据分析起码少费一半力
  9. python找到文件夹下指定文件类型_python 读取指定文件夹中的指定文件类型的文件名...
  10. 海康8700联网网关如何通过GB28181接入安防摄像头互联网直播流媒体解决方案EasyGBS实现web端无插件直播
  11. React-Native之轮播组件looped-carousel的介绍与使用
  12. Unity Shader: Blend混合
  13. Android 扫码盒子全局接收付款码(全局事件上层接收多重下发)
  14. 华为交换机的应用案例(小)
  15. Android如何判定一张图片是不是灰度的
  16. 华为日历登录qq邮箱的解决方案
  17. linux下用vi,vim编辑时退出编辑模式(wq)无法保存退出
  18. 《手机拍照与视频》那点事
  19. 十大ios开发者喜爱的开源库
  20. 模拟非同期运行java_基于JavaME技术的移动终端设备信息查询系统的设计分析.pdf...

热门文章

  1. 倾角传感器精度校准检测
  2. oracle中12560,解决ORA-12560的方法(转载)
  3. 颠覆物理学的中微子:宇宙中飞行速度几乎达到光速
  4. 不小心把java文件删除了_如何使用Java恢复已删除的文件?
  5. oracle找回删除的表
  6. 虚拟机云服务器6.0教程pdf,虚拟机云服务器6.0教程pdf
  7. 结合推荐营销和社交媒体的最佳实践有哪些?
  8. 提升: 建立一个如下的学生情况表,要求先依次输入学生数据元素,然后依次显示当前表中的学生数据元素。 学号 姓名 性别 年龄 2000001 张三 男 20 2000002
  9. 显著图(Saliency map)
  10. java过滤xss_java处理XSS过滤的方法