执行新程序 execve()
新程序的执行
一:execve()
之所以叫新程序的执行,原因是这部分内容一般发生在fork()
和vfork()
之后,在子进程中通过系统调用execve()
可以将新程序加载到子进程的内存空间。这个操作会丢弃原来的子进程execve()
之后的部分,而子进程的栈、数据会被新进程的相应部分所替换。即除了进程ID之外,这个进程已经与原来的进程没有关系了。
举个例子:在shell(shell也是一个进程)
中执行最简单的HelloWorld
程序。它也是首先调用execve()
这个系统调用的,下面用strace
跟踪下执行HelloWorld
的过程,我们可以看到第一步执行的是execve()
。省略了后面信息,如图:
实际上Hello
进程的父进程是shell进程
,它是shell进程
fork出来的一个子进程然后执行execve
之后在执行的Hello
,所以我们下面来看看这个execve
:
#include <unistd.h>
int execve(const char *filename, char *const argv[],
char *const envp[]);
- filename:包含准备载入当前进程空间的新程序的路径名。既可以是绝对路径,又可以是相对路径。
- argv[]:指定了传给新进程的命令行参数,该数组对应于c语言main函数的argv参数数组,格式也相同,argv[0]对应命令名,通常情况下该值与filename中的basename(就是绝对路径的最后一个)相同。
- envp[]:最后一个参数envp指定了新程序的环境列表。参数envp对应于新程序的environ数组。
还要注意的是:由于是将调用进程取而代之,因此对execve
的调用将永远不能返回,也无需检查它的返回值,因为该值始终为-1
,实际上,一旦返回就表明了错误,通常会有error值来判断,下面是几个常用的:
- EACCES:参数pathname没有指向一个常规文件,未对该文件赋于可执行权限,或者因为目录没有x
权限。
- ENOTNT:pathname指定的文件并不存在。
- ETXTBSY:存一个或者多个进程已经以写入的方式打开pathname所指定的文件。
下面我们举个例子说明execve的用法:
filename:execve.c
#include<stdio.h>
#include<unistd.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[1];
argVec[1] = "hello world";
argVec[2] = "goodbye";
execve(argv[1],argVec,envVec); //分别传入三个参数
return 0;
}
filename:envargs.c
#include<stdio.h>
#include<stdlib.h>
extern char ** environ;
int main(int argc,char *argv[]) //argv[]相当于上面的argvec[]
{
int j;
char **ep;
for(j = 0;j < argc;j++) {
printf("argv[%d] = %s\n",j,argv[j]);
}
for(ep = environ;*ep != NULL;ep++) { //environ是上面的envVec[]
printf("environ:%s\n",*ep);
}
exit(EXIT_SUCCESS);
return 0;
}
二:exec()函数族
实际上有关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
结尾。
下面我们通过这个表格来介绍exec()函数族之间的差异:
函数 | 执行程序文件 | 参数 | 环境变量 |
---|---|---|---|
execve() | 路径名 | 数组 | envp参数 |
execle() | 路径名 | 列表 | envp数组 |
execlp() | 文件名 | 列表 | 调用者environ |
execvp() | 文件名 | 数组 | 调用者environ |
execv() | 路径名 | 数组 | 调用者environ |
execl() | 路径名 | 列表 | 调用者environ |
执行新程序 execve()的更多相关文章
- linux c 执行新程序
学习进程时,linu c上说新开的进程一般要执行另外一个程序,同时与父进程执行同一个程序没有意义 如下是如何执行一个新的程序 使用exec函数簇 exec函数簇包含如下函数
- 在进程中执行新代码 execl、execle、execlp、execv、execve和execvp函数
摘要:本文主要讲述怎样在进程中执行新代码,以及exec系列函数的基本用法. 在进程中执行新代码 用函数fork创建子进程后,假设希望在当前子进程中运行新的程序,能够调用exec函数运行还有一个程序.当 ...
- Linux进程线程学习笔记:运行新程序
Linux进程线程学习笔记:运行新程序 周银辉 在上一篇中我们说到,当启动一个新进程以后,新进程会复制父进程的大部份上下 ...
- JVM执行Java程序时内存的划分
Java虚拟机在执行Java程序过程中会把它所管理的内存区域划分为若干个不同的数据区域. Java虚拟机所管理的内存包括以下几个运行时区域: 1.程序计数器(Program Couter Regist ...
- docker~在centos容器中安装新程序
上一篇我们使用了阿里加速器安装了centos镜像,然后创建了一个新容器,运行了这个镜像,这一讲我们来为这个镜像添加一些应用程序,然后再保存容器,push容器到仓储,大家就可以直接pull我生产的容器了 ...
- Java程序导出成.jar文件、生成.exe可执行文件及打包成可执行安装程序(可在无Java环境的计算机上运行)--以个人所得税计算器为例
Java程序导出成.jar文件.生成.exe可执行文件及打包成可执行安装程序 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 需要准备的软件: jdk, ...
- VBA定时执行某程序
OnTime 方法参阅应用于示例特性安排一个过程在将来的特定时间运行(既可以是具体指定的某个时间,也可以是指定的一段时间之后). expression.OnTime(EarliestTime, Pro ...
- Shell脚本实现每个工作日定时执行指定程序
我们可能会遇到这样的情景:必须在每个工作日定时执行Linux服务器上的某个程序.那么有没有办法实现这一功能呢?答案是肯定的.我们可以运用Shell脚本简单实现这一功能. 原理很简单,Shell脚本内部 ...
- 在linux命令行下执行php 程序
如何在linux命令行下,执行php程序. 例子 打印当前时间 php -r "echo time()" 随机输出一个数字 php -r "echo rand(1,20) ...
随机推荐
- JDBC-1(概述&建立)
基于宋红康老师所讲JDBC所作笔记 1.JDBC概述 1.1 数据持久化 持久化:将数据保持到可掉电式存储设备中以供之后使用. 数据持久化意味着将内存中的数据保存到硬盘上加以固化,实现过程大多通过各种 ...
- Jmeter系列(15)- 常用断言之大小断言
大小断言 大小断言验证响应数据size大小,它的作用范围有主Sample与子Sample:适用场景,判断附件下载的大小,比如项目安装包 完整响应:全部响应信息 响应头:响应头信息,比如http协议的头 ...
- Linux系列(17) - >、>>的用法
适用场景 输出重定向,将命令结果写入文件当中 差异化 >:覆盖原文件内容 >>:追加文件内容 格式 [命令] > [文件名]:将[命令]的结果覆盖到[文件名]该文件中,如果目录 ...
- str.strip(chars)
strip会去除给定字符串的指定字符,指定字符可以是一个或多个,去除从左右分别进行,没有则忽略,如果需要去除某个中间的字符,必须先去除外围的字符 看几个例子,以s为例,故意设置为非对称结构, s = ...
- 5-让出CPU执行权的yield方法
让出CPU执行权的yield方法 Thread类有一个静态的yield方法,当一个线程在调用yield方法时,实际上就是暗示线程调度器请求让出自己的CPU使用,但是线程调度器可以无条件忽略这个暗示. ...
- 初探计算机网络之CPU和内存
CPU CPU是一块超大规模的集成电路板,是计算机的核心部件,承载着计算机的主要运算和控制功能,是计算机的最终解释模块和执行模块.总之,用一句话概括就是,CPU是由控制器和运算器组成的,而内部寄存 ...
- 使用node-gyp编写简单的node原生模块
通过样例,让我们了解如何编写一个node的原生模块.当然,这篇文章还有一个目的,是为了方便以后编写关于node-gyp的文章,搭建初始环境. 基于node-addon-api 基于node-addon ...
- Windows下node-gyp查找VS安装路径简单解析
node-gyp的作用我已经不想赘述了,这里给一个我之前文章的链接:cnblogs看这里,知乎看这里.本文主要从源码入手,介绍node-gyp查找VisualStudio的过程 为了方便我们研究nod ...
- 如何通过 Serverless 技术降低微服务应用资源成本?
前言 在大型分布式 IT 架构领域,微服务是一项必不可少的技术.从本质上来讲,微服务是一种架构风格,将一个大型的系统拆分为多个拥有独立生命周期的应用,应用之间采用轻量级的通信机制进行通信.这些应用都是 ...
- C 字符串相关的库函数
字符串操作函数 size_t strlen( char *string ); 返回字符串长度 char* strcpy( char *dst, char const *src ); 将src复制到ds ...