在我的简单自定义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传递。这是否足够正确?
答案 0 :(得分:16)
您需要在父代码中使用waitpid(3)
或wait(1)
等待孩子退出并收到错误消息。
语法为:
pid_t waitpid(pid_t pid, int *status, int options);
或
pid_t wait(int *status);
status
包含退出状态。查看man pages,了解如何解析它。
请注意,您无法从子进程执行此操作。一旦您致电execvp
子流程 去世 (出于所有实际目的),并由exec
'替换过程。只有exit(0)
本身失败才能达到execvp
的唯一方法,但失败的原因并不在于新程序的结束。这是因为它永远不会开始。
修改:子进程不会真的死掉。 PID和环境保持不变,但整个代码和数据都被exec
'进程替换。除非exec
失败,否则您可以指望不返回原始子进程。
答案 1 :(得分:3)
从你的问题来看,要弄清楚你在问什么有点困难。因此,我将尝试介绍几个相关问题:
execvp()
要么不返回(成功时),要么返回错误。这意味着您的子代码只需要处理错误条件。您的子代码应捕获execvp()
的结果,并按照您的建议在exit()
中使用该值。您的子代码永远不会返回0,因为唯一的成功意味着execvp
有效, 进程将返回0(或不是)。waitpid()
获取有关其退出状态的子信息。定义了几个宏来从返回的status
参数中提取信息。值得注意的是WIFEXITED
告诉您孩子是否“正常”退出,WEXITSTATUS
将孩子的状态传递给exit()
。有关其他宏,请参见waitpid
手册页。答案 2 :(得分:3)
在父进程中使用wait()
或waitpid()
。这里有一个例子:Return code when OS kills your process。
此外,当孩子死亡时,SIGCHLD
信号将被发送到父进程。