题
在我的简单自定义 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
其他宏的手册页。
在父进程使用wait()
或waitpid()
。这个范例:返回代码OS杀死你的进程一当>
此外,当儿童死亡的SIGCHLD
信号被发送到父进程。
不隶属于 StackOverflow