如何正确地将被杀死的子进程的退出状态传递到 shell?
How to properly pass a killed child process's exit state up to the shell?
(我正在开发一个简单的类似 expect 的程序。)
例如,我有一个程序 prog1.c
,其中 fork()
和 exec()
另一个程序 prog2
。当 prog2
被信号杀死时(例如 SIGPIPE
),prog1
可以通过 waitpid()
、WIFSIGNALED()
和 WTERMSIG()
获得其退出状态。然后 prog1
会将退出状态传递给 prog1
的调用者(shell,如 Bash 或 Ksh93),我想让它看起来像 shell 正在调用 prog2
所以我希望 shell 获得 prog2
.
的确切退出状态
我能想到的一种方法是 prog1
用杀死 prog2
的信号杀死自己,但这听起来有点奇怪所以我想知道是否有其他更好的方法来做到这一点.
正在将评论转换为答案。
如果您希望报告的状态准确无误(信号状态也是如此),则必须完全符合您的建议:
int status;
int corpse = wait(&status);
if (WIFSIGNALED(status))
kill(getpid(), TERMSIG(status));
else
exit(WEXITSTATUS(status));
请注意,Bash 通过 128 + signal_number
正常退出的信号报告儿童死亡。您可能仍然遇到核心转储问题。您可能需要以不同方式处理某些信号(例如作业控制信号)。
I only deal with scenarios where the child exits so would not handle things like WIFSTOPPED or WIFCONTINUED. Core dump is indeed something I have to think. Not sure if a C program can decide whether or not to dump a core but still be able to tell the caller that it's SIGSEGVed.
有时 o/s 特定接口可以控制核心转储。例如,POSIX 提供 getrlimit()
setrlimit()
可以将核心转储的大小限制为 0,从而防止核心转储。如果信号最初在孙进程中提供了核心转储,它可能也会为子进程提供核心转储——但这可能是个问题,因为子进程的核心覆盖了孙进程的核心,使您没有相关信息。我不确定您需要担心到什么程度,或者您可以使用 o/s 特定机制来处理它。我不知道即使未创建核心,您是否设置了 'core dumped' 位;可能不是。
(我正在开发一个简单的类似 expect 的程序。)
例如,我有一个程序 prog1.c
,其中 fork()
和 exec()
另一个程序 prog2
。当 prog2
被信号杀死时(例如 SIGPIPE
),prog1
可以通过 waitpid()
、WIFSIGNALED()
和 WTERMSIG()
获得其退出状态。然后 prog1
会将退出状态传递给 prog1
的调用者(shell,如 Bash 或 Ksh93),我想让它看起来像 shell 正在调用 prog2
所以我希望 shell 获得 prog2
.
我能想到的一种方法是 prog1
用杀死 prog2
的信号杀死自己,但这听起来有点奇怪所以我想知道是否有其他更好的方法来做到这一点.
正在将评论转换为答案。
如果您希望报告的状态准确无误(信号状态也是如此),则必须完全符合您的建议:
int status;
int corpse = wait(&status);
if (WIFSIGNALED(status))
kill(getpid(), TERMSIG(status));
else
exit(WEXITSTATUS(status));
请注意,Bash 通过 128 + signal_number
正常退出的信号报告儿童死亡。您可能仍然遇到核心转储问题。您可能需要以不同方式处理某些信号(例如作业控制信号)。
I only deal with scenarios where the child exits so would not handle things like WIFSTOPPED or WIFCONTINUED. Core dump is indeed something I have to think. Not sure if a C program can decide whether or not to dump a core but still be able to tell the caller that it's SIGSEGVed.
有时 o/s 特定接口可以控制核心转储。例如,POSIX 提供 getrlimit()
setrlimit()
可以将核心转储的大小限制为 0,从而防止核心转储。如果信号最初在孙进程中提供了核心转储,它可能也会为子进程提供核心转储——但这可能是个问题,因为子进程的核心覆盖了孙进程的核心,使您没有相关信息。我不确定您需要担心到什么程度,或者您可以使用 o/s 特定机制来处理它。我不知道即使未创建核心,您是否设置了 'core dumped' 位;可能不是。