在我的简单自定义 shell 中,我从标准输入读取命令并使用 execvp() 执行它们。在此之前,我创建当前进程的一个分支,并在该子进程中调用 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 传递吗?这足够并且正确吗?

有帮助吗?

解决方案

您需要使用waitpid(3)wait(1)父代码等待孩子退出,并收到错误信息。

的语法是:

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

pid_t wait(int *status);

status包含退出状态。看看手册页的就看你如何分析它。


请注意,你不能从子过程中做到这一点。一旦你调用execvp子进程 死亡(适用于所有实际目的),是的代替的由exec'd过程。可以达到exit(0)的唯一途径有如果execvp本身出现故障,但随后的失败不是因为新程序结束。这是因为它从来没有跑开始。

编辑:的子进程不会的真正的死亡。 PID和环境保持不变,但整个代码和数据与exec'd过程代替。您可以在的的计数返回到原来的子进程,除非exec失败。

其他提示

从你的问题来看,有点难以弄清楚你在问什么。因此,我将尝试讨论几个相关问题:

  • execvp() 要么不返回(成功时),要么返回错误。这意味着您的子代码只需要处理错误条件。您的子代码应该捕获以下结果 execvp() 并使用该值 exit() 正如你所建议的。你的子代码永远不应该返回 0,因为唯一的成功意味着 execvp 工作并且 进程将返回 0(或不返回)。
  • 家长可以通过以下方式获取孩子信息 waitpid() 关于它的退出状态。定义了几个宏来从返回的数据中提取信息 status 范围。值得注意的是您的目的是 WIFEXITED 告诉您孩子是否“正常”退出,以及 WEXITSTATUS 获取传递给的孩子的状态 exit(). 。请参阅 waitpid 其他宏的手册页。
scroll top