在进程中运行新代码

摘要:本文主要讲述如何在进程中运行新代码,以及exec系列函数的基本使用方法.

在进程中运行新代码

用函数fork创建子进程后,如果希望在当前子进程中运行新的程序,可以调用exec函数执行另一个程序.当进程调用exec函数时,该进程用户空间资源(正文、数据、堆和栈)完全由新程序替代,新程序则从main函数开始执行.因为调用exec函数并没有创建新的进程,所以前后的进程ID并没有改变,也即内核信息基本不做修改.

exec系列函数共有7函数可供使用,这些函数的区别在于:指示新程序的位置是使用路径还是文件名,如果是使用文件名,则在系统的PATH环境变量所描述的路径中搜索该程序;在使用参数时使用参数列表的方式还是使用argv[]数组的方式.

1.exec系列函数

函数定义:

#include <unistd.h>

int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );

int execv(const char *pathname, char *const argv[]);

int execle(const char *pathname, const char *arg0, .../* (char *)0, char *const envp[] */ );

int execve(const char *pathname, char *const argv[], char *const envp[]);

int execlp(const char *filename, const char *arg0, ... /* (char *)0 */ );

int execvp(const char *filename, char *const argv[]);

int fexecve(int fd, char *const argv[], char *const envp[]);

返回值:如果执行成功将不返回,否则返回-1,失败代码存储在errno中.

前4个函数取路径名作为参数,后两个是取文件名作为参数,最后一个是以一个文件描述符作为参数.

2.函数具体分析

当指定filename作为参数时:

1)如果filename中包含/,则将其视为路径名.

2)否则就按PATH环境变量,在它所指的各目录搜寻可执行文件.

2.1 execl()函数

int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );

execl()函数用来执行参数path字符串所指向的程序,第二个及以后的参数代表执行文件时传递的参数列表,最后一个参数必须是空指针以标志参数列表为空.

例子1:演示exec()函数的基本使用.

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
        pid_t pid;
        pid = fork();
        if(pid<0)
        {
                printf("error fork:%m\n");
                exit(-1);
        }
        else if(pid==0)
        {
                //
                execl("/bin/ls","ls","-l","/etc",(char *)0);
        }
        else
        {
                printf("parent process\n");
        }
        return 0;
}

输出:

2.2 execle()函数

int execle(const char *pathname, const char *arg0, .../* (char *)0, char *const envp[] */ );

execle()函数用来执行参数path字符串所指向的程序,第二个及以后的参数代表执行文件时传递的参数列表,最后一个参数必须指向一个新的环境变量数组,即新执行程序的环境变量.

例子2:

#include <unistd.h>
int main(int argc, char *argv[], char *env[])
{
        execle("/bin/ls","ls","-l", "/etc",(char *)0,env);
        return 0;
}

输出:

2.3 execlp()函数

int execlp(const char *filename, const char *arg0, ... /* (char *)0 */ );

execlp()函数会从PATH环境变量所指的目录中查找文件名为第一个参数指示的字符串,找到后执行该文件,第二个及以后的参数代表执行文件时传递的参数列表,最后一个参数必须是空指针.

例子3:

#include <unistd.h>

int main()
{
        execlp("ls", "ls", "-l", "/etc", (char *)0);
        return 0;
}

输出:

2.4 execv()函数

int execv(const char *path, char *const argv[]);

execv()函数函数用来执行参数path字符串所指向的程序,第二个为数组指针维护的程序参数列表,该数组的最后一个成员必须是空指针.

例子4:

#include <unistd.h>

int main()
{
        char *argv[] = {"ls", "-l", "/etc", (char *)0};
        execv("/bin/ls", argv);
        return 0;
}

输出:

2.5 execvp()函数

int execvp(const char *file, char *const argv[]);

execvp()函数会从PATH环境变量所指的目录中查找文件名为第一个参数指示的字符串,找到后执行该文件,第二个及以后的参数代表执行文件时传递的参数列表,最后一个成员必须是空指针.

例子5:

#include <unistd.h>

int main()
{
        char *argv[] = {"ls", "-l", "/etc", (char *)0};
        execvp("ls", argv);
        return 0;
}

输出:

几个函数之间非常相似,没有找到更好的方法记忆,通过简单的例子暂时了解一下它们之间的不同调用方式.字母联想也不靠谱:

字母p表示该函数取filename作为参数,并且用PATH环境变量寻找可执行文件.

字母l表示该函数取一个参数表,它与字母v互斥.

字母v表示该函数取一个argv[]矢量.

字母e表示该函数取envp[]数组.

待续......

笔者:个人能力有限,只是学习参考...读者若发现文中错误,敬请提出.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------勿在浮沙筑高台,静下心来,慢慢地沉淀---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

时间: 2024-11-08 01:14:31

在进程中运行新代码的相关文章

Android应用程序在新的进程中启动新的Activity的方法和过程分析

Android应用程序在新的进程中启动新的Activity的方法和过程分析 - 老罗的Android之旅 - 博客频道 - CSDN.NET ? ? ? ?前面我们在分析Activity启动过程的时候,看到同一个应用程序的Activity一般都是在同一个进程中启动,事实上,Activity也可以像Service一样在新的进程中启动,这样,一个应用程序就可以跨越好几个进程了,本文就分析一下在新的进程中启动Activity的方法和过程. ?? ? ? ?在前面Android进程间通信(IPC)机制B

IIS网站不可用:同一 IIS 进程中运行两个不同的 ASP.NET 版本问题

出错现象: 在IIS中的网站刚部署的网站可以用,过一段时间就不能用了.然后出现网站不可用的提示. 查看系统日志: 发现在系统日志中有这么一条信息:"在同一 IIS 进程中不可能运行两个不同的 ASP.NET 版本.请使用 IIS 管理工具重新配置服务器以在一个单独的进程中运行应用程序." 解决方案: 因为在同一个IIS应用程序池中不能运行两个asp.net的版本.将不同asp.net版本的网站分配不同的应用程序池就好了

在notepad++中运行python代码

#在notepad++中运行python代码 ''' 1.安装插件pyNPP, 2.允许插件pyNPP中的第一个和第二个选项即可,如果代码过少代码执行一闪而过,可能无法看到,可加入少量sleep时间即可 ''' 方法二:1.安装插件NppExec2.打开NppExec--Execute,在下拉菜单中选择<temporary script>,在输入框中输入:cmd /k python "$(FULL_CURRENT_PATH)" & EXIT然后,点击save,并给该

Pycharm中运行Python代码的几种方式

在pycharm中的Python代码运行会出现各种奇葩的问题,比如,密码输入时不显示或没有提示,给我们带来一些麻烦,下面介绍几种代码运行的几种方式: 一.直接运行(Run按钮或者快捷键shift+F10) 1.进入pychram主界面,输入代码后,直接Run就可以: 2.Termnal下运行.py文件 在pycharm的主界面,点termnal,进入命令面板,选择路径,回车键执行相应的文件(python 文件名.py). 3.终端命令行 1>进入pycharm主界面,选中要执行的文件或目录; 2

在Sublime Text3中运行PHP代码

一.前言 最近由于工作需要要与第三方系统对接,另外由于文档中关于其中几个接口就只有很简单的描述,弄了半天都没有弄成功.跟第三方负责的人沟通后还是没有找到具体问题出在哪里,另外因为他们没有开发人员懂.net的,所以也只能提供php的代码,而我本人之前也只简单地看过php的语法,对php也不是很了解,所以发过来的代码也只是大概看得懂,具体一些关键代码运行效果也是怎样的就不知道了,所以要把php翻译成C#代码的难度也可想而知.但如果能知道那些关键代码的运行效果,那就容易多了,但对于就只懂一些基本的ph

python中运行js代码—js2py

import js2py # 实例化一个执行js的环境对象 context_js_obj = js2py.EvalJs() js_str = """ function A(a,b){ return a+b } """ # 传递js_str,执行js context_js_obj.execute(js_str) result = context_js_obj.A(1, 2) print(result) # 创建变量 context_js_obj.n

【Win 10 应用开发】在App所在的进程中执行后台任务

在以往版本中,后台任务都是以独立的专用进程来运行,因此,定义后台任务代码的类型都要位于 Windows 运行时组件项目中. 不过,在14393中,SDK 作了相应的扩展,不仅支持以前的独立进程中运行后台任务,也允许后台任务与应用程序位于同一个进程中执行,即单进程后台任务(Single – Process). 听起来很高深?其实很Easy,和以往的多进程模式的后台任务差不多,只是有以下两点不同: 对于独立进程的后台任务,实现方法是实现 IBackgroundTask 接口,然后实现 Run 方法:

禁止在 .NET Framework 中执行用户代码。启用 &quot;clr enabled&quot; 配置选项

解决方法: 查询分析器中运行如下代码即可: use <databasename> go exec sp_configure 'show advanced options', '1';goreconfigure;goexec sp_configure 'clr enabled', '1'goreconfigure;exec sp_configure 'show advanced options', '1';go

将dll文件注入到其他进程中的一种新方法

http://www.45it.com/windowszh/201212/33946.htm http://www.hx95.cn/Article/OS/201212/65095.html 我们知道将动态连接库注入到其他进程中有很多种方法.最常见的方法是使用钩子函数(Hook),但是这种方法主要有两个缺点:第一如果某个进程没有加载User32.dll,那么Hook DLL将永远也不会被加载.第二Hook DLL加载的时机问题,只有在进程发出User32调用的时候, Hook DLL才有可能被加载