exec

一、进程替换:

1.exec族函数的作用:

将fork()产生的子进程的.text和.data段替换成目标进程的.text和.data
”换核不换壳“
除了产生子进程,期间并没有新的进程产生

2.linux下进程产生机制:

1.编辑一个helloworld程序
2.gcc -o main main.c 得到一个可执行文件main
3.在我们的终端bash执行./main,实际上bash也是一个进程

第3步发生了什么:
1.首先系统进行fork(),产生了一个子进程,也就是子bash
(实际上调用的是sys_vfork())
此时子进程的3G的虚拟地址空间和父进程几乎完全一样,当然包括.data和.text
父子进程执行同样的代码,只不过我们在编程时,用if else语句使他们执行不同的分支

2.系统调用exec族中的某个函数,将子进程中.data和.text替换成main进程的.data和.text
这下,子进程就有了新的代码和数据,不再是共享父进程的
不过exec()前后的进程的ID不变

所以我们可以发现期间并没有新的进程,是将子进程中的内容换成main的即可。

所以,进程替换,替换的是进程的.data和.text。

3.exec族函数的使用:

int execl(const char*path,const char *argv,...(char*)0);
int execlp(const char*file,const char *argv,...(char*)0);
int execle(const char *path, const char *argv, ..., char * const envp[]);  
int execv(const char *path, char *const argv[]);  
int execvp(const char *file, char *const argv[]);  

l代表list参数列表       
e代表environment环境变量     
v代表vextor使用命令行参数数组argv

path:
指的是可执行文件的路径+名称,路径可以是相对路径
比如“/bin/ps”
arg:
传入的参数,如argv[0]可执行文件名,后面的是参数
file:
代表可执行文件的文件名
(char*)0:
实际上是一个哨兵,由于一些函数是可变参的,所以告诉编译器参数传递完了


其余五个都是调用该函数完成的:
int execve(const char *path, char *const argv[], char *const envp[])    (真正的系统调用)

这些函数有一个特点:没有成功返回值,失败才会返回-1
执行成功后不会返回,而且,exec 函数族下面的代码执行不到。
调用失败了,它们才会返回 -1,失败后从原程序的调用点接着往下执行。

写一点伪代码:

1.
if(pid == 0)  //子进程中
{
	execlp("ls","ls","-l","-a",NULL);
}
其中:argv[0]="ls",argv[1]="-l",argv[2]="-a",
NULL是哨兵为,告诉编译器参数完毕
argv是传递给第一个 ls 的参数

2.
if ( pid == 0 )
{
	execl("/bin/ls","ls","-a",NULL);
}
其中:第一个参数是可执行文件的路径+名称,第二个是可执行文件名,
之后的参数是给可执行文件的参数,最后一个同样是哨兵位

3.
char *argv[]={"ls","-l","-a",NULL};
if( pid == 0 )
{
	execv("/bin/ls",argv);
}

exec类函数既可以加载系统的进程,也可以加载我们用户的进程,写法一样的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值