execve系统调用_Linux系统编程——进程替换:exec 函数族

在 Windows 平台下,我们可以通过双击运行可执行程序,让这个可执行程序成为一个进程;而在 Linux 平台,我们可以通过 ./ 运行,让一个可执行程序成为一个进程。

但是,如果我们本来就运行着一个程序(进程),我们如何在这个进程内部启动一个外部程序,由内核将这个外部程序读入内存,使其执行起来成为一个进程呢?这里我们通过 exec 函数族实现。

exec 函数族,顾名思义,就是一簇函数,在 Linux 中,并不存在 exec() 函数,exec 指的是一组函数,一共有 6 个:

#include <unistd.h>
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[]);

其中只有execve()是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。

exec 函数族提供了六种在进程中启动另一个程序的方法。exec 函数族的作用是根据指定的文件名或目录名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。

进程调用一种 exec 函数时,该进程完全由新程序替换,而新程序则从其 main 函数开始执行。因为调用 exec 并不创建新进程,所以前后的进程 ID (当然还有父进程号、进程组号、当前工作目录……)并未改变。exec 只是用另一个新程序替换了当前进程的正文、数据、堆和栈段(进程替换)。

6271ba933d56b0e0ac5d64d2a2462f5c.png

exec 函数族的 6 个函数看起来似乎很复杂,但实际上无论是作用还是用法都非常相似,只有很微小的差别。

83254300ce928bfa209978e3ccc13461.png

l(list):参数地址列表,以空指针结尾。

v(vector):存有各参数地址的指针数组的地址。

p(path):按 PATH 环境变量指定的目录搜索可执行文件。

e(environment):存有环境变量字符串地址的指针数组的地址。

exec 函数族装入并运行可执行程序 path/file,并将参数 arg0 ( arg1, arg2, argv[], envp[] ) 传递给此程序。

exec 函数族与一般的函数不同,exec 函数族中的函数执行成功后不会返回,而且,exec 函数族下面的代码执行不到。只有调用失败了,它们才会返回 -1,失败后从原程序的调用点接着往下执行。

需要C/C++ Linux服务器架构师学习资料加qun获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

2569e45fe2a5e79ed12d62f08201c657.png

execl() 示例代码:

#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[])
{printf("before execnn");/* /bin/ls:外部程序,这里是/bin目录的 ls 可执行程序,必须带上路径(相对或绝对)ls:没有意义,如果需要给这个外部程序传参,这里必须要写上字符串,至于字符串内容任意-a,-l,-h:给外部程序 ls 传的参数NULL:这个必须写上,代表给外部程序 ls 传参结束*/execl("/bin/ls", "ls", "-a", "-l", "-h", NULL);// 如果 execl() 执行成功,下面执行不到,因为当前进程已经被执行的 ls 替换了perror("execl");printf("after execnn");return 0;
}

运行结果如下:

e386ebddcb88a145edb3a3f5173a178a.png

execv()示例代码:

execv() 和 execl() 的用法基本是一样的,无非将列表传参,改为用指针数组。

#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[])
{// execv() 和 execl() 的用法基本是一样的,无非将列表传参,改为用指针数组// execl("/bin/ls", "ls", "-a", "-l", "-h", NULL);/* 指针数组ls:没有意义,如果需要给这个外部程序传参,这里必须要写上字符串,至于字符串内容任意-a,-l,-h:给外部程序 ls 传的参数NULL:这个必须写上,代表给外部程序 ls 传参结束*/char *arg[]={"ls", "-a", "-l", "-h", NULL};// /bin/ls:外部程序,这里是/bin目录的 ls 可执行程序,必须带上路径(相对或绝对)// arg: 上面定义的指针数组地址execv("/bin/ls", arg);perror("execv");return 0;
}

execlp() 或 execvp() 示例代码:

execlp() 和 execl() 的区别在于,execlp() 指定的可执行程序可以不带路径名,如果不带路径名的话,会在环境变量 PATH指定的目录里寻找这个可执行程序,而 execl() 指定的可执行程序,必须带上路径名。

#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[])
{// 第一个参数 "ls",没有带路径名,在环境变量 PATH 里寻找这个可执行程序// 其它参数用法和 execl() 一样execlp("ls", "ls", "-a", "-l", "-h", NULL);/*char *arg[]={"ls", "-a", "-l", "-h", NULL};execvp("ls", arg);*/perror("execlp");return 0;
}

execle() 或 execve() 示例代码:

execle() 和 execve() 改变的是 exec 启动的程序的环境变量(只会改变进程的环境变量,不会影响系统的环境变量),其他四个函数启动的程序则使用默认系统环境变量。

execle()示例代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> // getenv()int main(int argc, char *argv[])
{// getenv() 获取指定环境变量的值printf("before exec:USER=%s, HOME=%sn", getenv("USER"), getenv("HOME"));// 指针数据char *env[]={"USER=MIKE", "HOME=/tmp", NULL};/* ./mike:外部程序,当前路径的 mike 程序,通过 gcc mike.c -o mike 编译mike:这里没有意义NULL:给 mike 程序传参结束env:改变 mike 程序的环境变量,正确来说,让 mike 程序只保留 env 的环境变量*/execle("./mike", "mike", NULL, env);/*char *arg[]={"mike", NULL};		execve("./mike", arg, env);	*/perror("execle");return 0;
}

外部程序,mike.c 示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char *argv[])
{printf("nin the mike fun, after exec: n");printf("USER=%sn", getenv("USER"));printf("HOME=%sn", getenv("HOME"));return 0;
}

运行结果如下:

38d6c51df7cfca68cfc4f090957fd236.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503422.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea shell 使用linux_Linux使用shell定时任务实现ffmpeg视频转码和截图

Linux安装操作系统&#xff1a;CentOS7 ffmpeg版本&#xff1a;3.4.1安装先访问ffmpeg官网下载linux安装包 http://ffmpeg.org/download.html &#xff0c;这里我下载的是官方已经编译过的版本&#xff0c;别问我为啥不自己编译&#xff0c;因为我自己编译耗费了好久&#xff0…

曾辉机器人_武昌理工学子在2020年中国机器人大赛中夺冠

“它在过弯的时候非常稳&#xff0c;而且速度快&#xff0c;跑完一圈的时间比第二名少十秒左右。”武昌理工学院学生余辉激动地说。11月27日从武昌理工学院获悉&#xff0c;在刚刚结束的2020中国机器人大赛中&#xff0c;武昌理工学院人工智能学院“晨旭队”&#xff0c;经过激…

升级bios_华硕400系主板升级BIOS:静待11代酷睿CPU

1月份对PC玩家来说还有很多惊喜&#xff0c;AMD、NVIDIA、Intel都会在CES上推出新一代产品&#xff0c;其中Intel针对桌面端的产品是11代酷睿&#xff0c;代号Rocket Lake-S。Rocket Lake仍将采用14nm制造工艺&#xff0c;基本确定也将是Intel最后一代14nm处理器。CPU架构方面&…

取得数组下标_《零基础C++入门教程》——(8)搞定二维数组与循环嵌套

一、学习目标了解二维数组的使用方法了解循环嵌套的使用方法目录预备第一篇&#xff0c;使用软件介绍在这一篇&#xff0c;C与C使用的软件是一样的&#xff0c;查看这篇即可&#xff1a;《零基础看得懂的C语言入门教程》——(二)简单带你了解流程 想了解编译原理和学习方法点这…

linux 的swap具体分析_Linux SWAP 深度解读

概述本文讨论的 swap基于Linux4.4内核代码 。Linux内存管理是一套非常复杂的系统&#xff0c;而swap只是其中一个很小的处理逻辑。希望本文能让读者了解Linux对swap的使用大概是什么样子。阅读完本文&#xff0c;应该可以帮你解决以下问题&#xff1a;1、 swap到底是干嘛的&…

物联卡的使用_物联卡在手机上使用有什么影响?网友:寿命分别是3个月,16天,9天...

个人使用物联卡是否合法&#xff1f;当然&#xff0c;个人是可以使用的&#xff0c;只不过是使用在除手机、平板以外的智能设备上。重点提醒&#xff1a;手机和平板除外。物联卡&#xff0c;是运营商为物流网服务企业提供的用于智能终端设备联网的&#xff0c;仅面对企业用户进…

多行文字cad提取数据_利用CAD自带的数据提取功能手动提取假表格至Excel

“吾生也有涯&#xff0c;而知也无涯&#xff0c;以有涯随无涯&#xff0c;殆已&#xff01;”&#xff0c;在已经有了免费的“源泉设计”插件可以自动提取假表格至Excel之后&#xff0c;笔者为什么还要讲解手动提取的方法&#xff1f;无他&#xff0c;生命在于折(zhuang)腾(bi…

gridview标题居中显示_Pr:制作片尾滚动字幕(旧版标题法)

本文介绍使用 Pr 的旧版标题设计器来制作传统片尾滚动字幕的方法。效果视频◆ ◆ ◆一般方法与步骤1、首先&#xff0c;将文字内容输入到一个文本文件中。按 Ctrl/Cmd A 全选&#xff0c;按 Ctrl/Cmd C 复制以备用。2、Pr菜单&#xff1a;文件/新建/旧版标题。3、点击“滚动…

mysql 从库状态_大神教你自动发现监控mysql从库状态

导读zabbix从库如果复制有问题&#xff0c;在主库机器有问题的时候&#xff0c;切为主就会导致数据的丢失。或者主从分离的时候&#xff0c;如果从库出现延时状态的话&#xff0c;会导致前端页面展示的数据不是为最新的数据。因此&#xff0c;监控mysql从库的状态是必要的。mys…

服务器搭建php mysql5_Windows下php5+apache+mysql5 手工搭建笔记

Windows下php5apachemysql5 手工搭建笔记更新时间&#xff1a;2011年02月15日 01:35:09 作者&#xff1a;php运行环境对于站长们或者初学者来说可以直接用一键包的方式或者直接从服务提供商处得到支持&#xff0c;不必自己手工按部就班的搭建&#xff0c;所以这篇文章是写给我…

Java编程和C语言哪个更好?

学编程用哪一个编程语言好?很多人刚开始接触编程的时候都不知道自己该学哪个好&#xff0c;软件开发编程语言多达600余种&#xff0c;每种都有各自的特点和应用领域。目前&#xff0c;热门编程语言无外乎Java、C、C了&#xff0c;实际上&#xff0c;Java确实是从C语言和C语言继…

Java程序员常犯的几类错误

1.忽视异常 相信很多小伙伴在编程的过程中经常对异常置之不理。针对初学者和有经验的 Java 程序员&#xff0c;最佳实践仍是处理它们。异常抛出通常是带有目的性的&#xff0c;因此在大多数情况下需要记录引起异常的事件。不要小看这件事&#xff0c;如果必要的话&#xff0c;…

jdk1.8 mysql_Centos 7配置JDK1.8+MySQL5.7+Tomcat 8 开发环境

工具腾讯云服务器(可通过公网ip访问)Xshell 6Xftp 61、Xshell 6 连接云服务器打开xshell很简单&#xff0c;直接上图配置好之后连接云服务器&#xff0c;之后就可以对云服务器进行操作了。2、配置JDK 1.8a、下载JDK1.8如果直接在云服务器的命令行中使用wget http://download.or…

做为一名java高级程序员,需要了解哪些岗位?

一、Java高级程序员 要想成为JAVA&#xff08;高级&#xff09;程序员也称Java高级工程师&#xff0c;肯定要学习JAVA。一般的程序员或许只需知道一些JAVA的语法结构就可以应付了。但要成为JAVA高级程序员&#xff0c;您要对JAVA做比较深入的研究。您应该多研究一下JDBC、IO包…

Java 程序员必读的五本书籍

如果你是一名程序员&#xff0c;想知道如何提高你对Java的了解或者成为更好的Java开发人员。在本文中&#xff0c;我将分享一些最好的Java书籍。这些书经受住了时间的考验&#xff0c;随着岁月的流逝变得越来越重要。不管你是学生还是职业者&#xff0c;你总有很多东西要学&…

使用sqlserver连接mysql服务_Sqlserver创建连接MySql的链接服务器

第一步&#xff1a;在MySql服务器上安装与系统对应的 MySql-Connector-ODBC安装过程中可能会报 缺失 msvcr100.dll的错误&#xff0c;这需要你根据系统到网上下载对应的这个dll文件。(当初遇到这个问题的时候&#xff0c;在网上试了很多的这种文件 最后才找到一个合适自己的)第…

什么人适合学习Java编程?编程好学吗?

什么人适合学习Java编程&#xff1f;编程好学吗&#xff1f;首先自己做个自我评估&#xff0c;包括能力、兴趣、逻辑思维、性格特点等等&#xff0c;结合这些特质判断自己是否适合学习Java。评估自己时&#xff0c;要尽量客观&#xff0c;追随内心&#xff0c;切勿轻易抬高或者…

not support mysql_MYSQL(解决方法):Client does not support authentication

mysql4.1以上版本连接时出现Client does not support authentication protocol问题解决办法shell> mysqlClient does not support authentication protocol requestedby server; consider upgrading MySQL client官方的说法是MySQL 4.1 and up uses an authentication proto…

大神程序员都懂英文翻译,而你却因英语不行遭拒?

程序员中很多人都是在外企里面工作的。这样的话就会涉及到&#xff0c;跟外籍同事的沟通和协作。上下级之间的汇报工作。虽然我们的主要工作是开发软件。是技术类工作。跟计算机打交道比较多&#xff0c;但是沟通对技术来说&#xff0c;还是非常重要的。跟外籍同事沟通&#xf…

android找不到符号_快速搭建Android开发环境——Android Studio(附ADB找不到设备)...

由于毕设大概率最终要使用Android来实现&#xff0c;所以现在要开始学习一些Android开发基础了。学习一门技术&#xff0c;最先要解决的问题就是开发环境的问题。就如同两年前学java那样&#xff0c;在windows下配置环境总是一件不那么令人开心的事。Android也是一样&#xff0…