【问题标题】:How to exit a child process and return its status from execvp()?如何退出子进程并从 execvp() 返回其状态?
【发布时间】:2010-10-28 13:55:14
【问题描述】:

在我的简单自定义 shell 中,我从标准输入读取命令并使用 execvp() 执行它们。在此之前,我创建了当前进程的 fork,并在该子进程中调用 execvp(),之后,我调用 exit(0)。

类似这样的:

pid = fork();

if(pid == -1) {
    perror("fork");
    exit(1);
}

if(pid == 0) {
    // CHILD PROCESS CODE GOES HERE...
    execvp(pArgs[0], pArgs);
    exit(0);
} else {
    // PARENT PROCESS CODE GOES HERE...
}

现在,使用 execvp() 运行的命令可以返回错误,对吧?我想正确处理它,现在我总是调用 exit(0),这意味着子进程将始终处于“OK”状态。

如何从 execvp() 调用中返回正确的状态并将其放入 exit() 调用中?我是否应该只获取 execvp() 返回的 int 值并将其作为 exit() 参数而不是 0 传递。这是否足够且正确?

【问题讨论】:

  • execvp 不会返回(除非 pArgs[0] 不是有效的可执行文件),因此永远不会到达 exit(0) 语句。
  • "除非 pArgs[0] 不是一个有效的可执行文件" - exec* 可能失败的原因有很多,只有一个。权限、资源计数、内存 - errno 会告诉你。
  • 如果 execvp() 确实失败了,你应该有 exit(1) 或 exit(EXIT_FAILURE) 或 exit(0) 以外的任何东西 - 以指示失败。
  • 旁注:你可能想要_Exit() 而不是exit()

标签: c exec fork exit


【解决方案1】:

您需要在父代码中使用waitpid(3)wait(1) 等待子退出并得到错误消息。

语法是:

pid_t waitpid(pid_t pid, int *status, int options);

pid_t wait(int *status);

status 包含退出状态。看man pages看你怎么解析。


请注意,您不能从子进程中执行此操作。一旦您调用execvp,子进程死亡(出于所有实际目的)并被exec'd 进程替换。到达exit(0) 的唯一方法是execvp 本身失败,但失败不是因为新程序结束。这是因为它从一开始就没有跑过。

编辑:子进程真的不会死掉。 PID 和环境保持不变,但整个代码和数据都替换为exec'd 进程。你可以指望不会返回原来的子进程,除非exec 失败。

【讨论】:

  • 我已经在 else { } 中这样做了,我只是没有发布代码...但是由于 exit(0),状态不总是为 0 吗??跨度>
  • 最后一件事,如果 execvp() 返回 -1,我应该执行 exit(0) 还是应该将其他值传递给 exit() 调用?
  • 像 exit(errno) 可能更好,是吗?
  • @Nazgulled:进程的唯一标准返回值是 0/EXIT_SUCCESS 和 EXIT_FAILURE (stdlib.h)。您可以返回其他值,但请记住,只能检索 8 个最低有效位。
  • 那么我应该在 exit() 中返回什么?
【解决方案2】:

在父进程中使用wait()waitpid()。这里有一个例子:Return code when OS kills your process

此外,当子进程死亡时,SIGCHLD 信号会发送到父进程。

【讨论】:

    【解决方案3】:

    根据您的问题,很难弄清楚您在问什么。因此,我将尝试讨论几个相关问题:

    • execvp() 要么不返回(成功时),要么返回错误。这意味着您的子代码只需要处理错误情况。您的子代码应捕获execvp() 的结果,并按照您的建议在exit() 中使用该值。您的子代码永远不应返回 0,因为唯一的成功意味着 execvp 工作并且 进程将返回 0(或不返回)。
    • 父母可以从waitpid()获得关于它的退出状态的孩子信息。定义了几个宏来从返回的status 参数中提取信息。值得注意的是WIFEXITED 告诉您孩子是否“正常”退出,WEXITSTATUS 将孩子的状态传递给exit()。有关其他宏,请参见 waitpid 手册页。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-01
      • 2015-03-11
      • 2012-01-17
      • 2020-10-24
      • 2017-03-19
      • 2012-04-21
      • 2011-08-04
      • 2014-09-23
      相关资源
      最近更新 更多