关于fork和execve系统调用

时间:2009-05-29 14:13:11

标签: linux unix

据说fork系统调用会创建调用进程的克隆,然后(通常)子进程发出execve系统调用以更改其映像并运行新进程。为什么这两步?

BTW,execve代表什么?

5 个答案:

答案 0 :(得分:15)

两步的原因是灵活性。在这两个步骤之间,您可以修改新执行程序将继承的子进程的上下文。

您可能想要改变的一些事情是:

  • 文件描述符
  • 用户/组ID
  • 处理组和会话ID
  • 当前目录
  • 资源限制
  • 调度优先级和亲和力
  • 文件创建掩码(umask)

如果你没有拆分fork和exec而是有一个类似spawn的系统调用,那么如果你想在子进程中设置不同的那些,它需要为每个这些进程属性设置参数。例如,请参阅Windows API中的CreateProcess参数列表。

使用fork / exec,您可以在执行新程序之前更改子项中您想要的任何可继承的进程属性。

设置文件描述符是孩子进程上下文中更常见的事情之一。如果要捕获程序的输出,通常会在父系统中使用pipe(2)系统调用创建管道,在fork(2)之后,您将关闭父进程中的写入结束并关闭在调用execve(2)之前,在子进程中读取结束。 (您还将使用dup(2)将管道的子端设置为文件描述符1(stdout))。在单个系统调用中,这可能是不可能的或限制性的。

答案 1 :(得分:11)

  • exec:执行新流程
  • v:使用参数数组
  • e:指定环境

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[]);
  • l:列出arg on function
  • p:使用$ PATH查找可执行文件

答案 2 :(得分:8)

每一步都相对简单。

在Unix中,您的进程有两个部分 - 带有应用程序代码(“text”)的只读存储区和读写存储区(“data”)。

一个fork克隆了读写区域,只留下了文本页面。您现在有两个进程运行相同的代码。它们的区别在于寄存器值 - 来自fork的返回值 - 它将父级与子级分开。

exec替换文本页面,仅保留数据页面。有许多形式的exec,取决于你传递给它的环境信息量。有关其他变体列表,请参阅http://linux.die.net/man/3/exec

答案 3 :(得分:3)

“exec”系列函数用新的过程映像替换当前过程映像(从中调用它),因此调用映像将被新过程映像替换。例如。如果你要从shell(/ bin / sh或/ bin / csh)运行'ls'命令,那么shell将分叉到一个新进程,然后执行ls。一旦ls命令退出,它就会将控制权返回给父进程,在本例中就是shell进程。

如果没有fork功能,那么shell将被'ls'进程替换,在退出时会留下一个无法访问的终端,因为在exec调用ls时,shell的内存映像被替换。

对于'exec'系列中的变体,请查看0x6adb015的答案。

答案 4 :(得分:0)

  

execve代表什么?

C中 exec 函数的6个变体是exec{l,v}{,e,p}。有关详细信息,请参阅下面的函数原型。

命令行参数

  • v - 命令行参数作为指针的数组( v ector)传递给函数。
  • l - 命令行参数单独传递( l ist)到函数。

环境变量(可选)

  • e - 一系列指向 e 环境变量的指针显式传递给新的过程图像

找到要执行的文件(可选)

  • 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[]);

Source