【问题标题】:How can I keep execv from killing my program? [duplicate]如何防止 execv 杀死我的程序? [复制]
【发布时间】:2014-02-22 11:49:16
【问题描述】:

我的任务是编写一个简单的 linux shell。我正在使用外部命令。我们需要使用 execv。

for (int i = 0; i < count; i++){
  char path[1024];
  strcpy(path, PATHS[i]);         // PATHS is an array of cstrings, the paths in $PATH
  strcat(path, "/");
  strcat(path, command[0]);       // command and commands are essentially the same
  printf("%d %s",i,path);         // they are essentially argv[]
  if (!execv(path, commands))     // for ls -l $HOME
    break;                        // commands[0] = ls [1] = -l [2] = my home dir

现在我只用 ls 测试它。 ls 完全按照它应该运行的方式运行,但程序在 execv 成功后立即关闭。有什么办法让我继续使用 execv 来检查路径是否正确,并让程序在 execv 成功后继续运行?

【问题讨论】:

标签: c linux execv


【解决方案1】:

exec family 函数不会杀死您的进程。它们替换现有流程图像为您执行的流程。

基本上,它的工作方式就像该进程(及其 PID 和相关的内核资源)保持不变,只是旧映像中的所有代码都被删除并替换为随后加载到内存中的程序中的代码,并且初始化就好像它完全是一个新进程。 PID不会改变,所以如果你想创建一个有自己PID的子进程,你必须使用另一个函数。

正确的方法是先fork,然后从子进程中使用exec*。这样您就可以在父实例中使用wait 函数来等待子实例终止并收回控制权。

+--------------+             +--------------+                             +----------------------+
|Parent process|+---fork()-->|Parent process|+---------wait()------------>|Parent process resumes|
+--------------+      +      +--------------+                             +----------------------+
                      |                                                               +
                      |                                                               |
                      |                                                               |
                      |      +-------------+              +-----------------+         |
                      +----->|Child process|+--execv()--->|New process image|+--exit--+
                             +-------------+              +-----------------+

【讨论】:

  • execv替换现有进程时,旧进程会怎样?
  • 已执行的 image 更改。该进程仍然存在,并且 PID 保持不变。编辑我的帖子以使其更清晰。
  • 谢谢,现在很清楚了。如果你可以请解释更多关于这条线if you want to create a child process with its own PID, you have to use another function.
  • @sujin,解释就在fork/exec/wait这句话的正下方。您可以通过 Google 找到大量示例,例如 cs.duke.edu/courses/spring01/cps110/slides/proc-ux/sld012.htm
【解决方案2】:

各种形式的 exec() 实际上替换当前进程映像为请求的进程映像。它们不会产生新的进程。所以你需要自己做,使用 fork()。

【讨论】:

    猜你喜欢
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    相关资源
    最近更新 更多