[英]about fork and execve system call
据说fork
系统调用创建了一个调用进程的克隆,然后(通常)子进程发出execve
系统调用来更改其映像并运行一个新进程。 为什么这两步?
顺便说一下, execve
代表什么?
两步的原因是灵活性。 在这两个步骤之间,您可以修改新执行程序将继承的子进程的上下文。
您可能想要改变的一些事情是:
如果你没有拆分fork和exec而是有一个类似spawn的系统调用,那么如果你想在子进程中设置不同的那些,就需要为每个这些进程属性设置参数。 例如,请参阅Windows API中的CreateProcess参数列表。
使用fork / exec,您可以在执行新程序之前更改子项中所需的任何可继承的进程属性。
设置文件描述符是在子进程上下文中更改的常见事项之一。 如果要捕获程序的输出,通常会在父系统中使用pipe(2)系统调用创建管道,在fork(2)之后,您将关闭父进程中的写入结束并关闭在调用execve(2)之前,在子进程中读取结束。 (您还将使用dup(2)将管道的子端设置为文件描述符1(stdout))。 这在单个系统调用中可能是不可能的或限制性的。
exec的其他变体比比皆是:
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[]);
每一步都比较简单。
在Unix中,您的进程有两个部分 - 带有应用程序代码(“text”)的只读存储区和读写存储区(“data”)。
fork克隆了读写区域,只留下文本页面。 您现在有两个进程运行相同的代码。 它们的区别在于寄存器值 - 来自fork的返回值 - 它将父项与子项分开。
exec替换文本页面,仅保留数据页面。 有许多形式的exec,取决于你传递给它的环境信息量。 有关其他变体列表,请参见http://linux.die.net/man/3/exec 。
“exec”系列函数用新的过程映像替换当前过程映像(从其调用的位置),因此调用映像将被新过程映像替换。 例如。 如果你要从shell(/ bin / sh或/ bin / csh)运行'ls'命令,那么shell将分叉到一个新进程,然后执行ls。 一旦ls命令退出,它就会将控制权返回给父进程,在本例中是父进程。
如果没有fork功能,那么shell将被'ls'进程替换,该进程在退出时会留下一个无法访问的终端,因为在exec调用ls时,shell的内存映像被替换。
对于'exec'系列中的变体,请查看0x6adb015的答案。
execve
代表什么?
C中的exec函数的6种变体是exec{l,v}{,e,p}
。 请参阅下面的函数原型以获取详细信
命令行参数
v
- 命令行参数作为指针的数组( v ector)传递给函数。 l
- 命令行参数单独传递(a l ist)到函数。 环境变量(可选)
e
-指针数组至e nvironment变量被明确地传递给新的过程映像 找到要执行的文件(可选)
p
-使用在P ATH环境变量来查找文件参数命名的文件来执行 int execl (char const *path, char const *arg0, ...);
int execle(char const *path, char const *arg0, ..., char const *envp[]);
int execlp(char const *file, char const *arg0, ...);
int execv (char const *path, char const *argv[]);
int execve(char const *path, char const *argv[], char const *envp[]);
int execvp(char const *file, char const *argv[]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.