(根据/programming/13718394/what-should-interactive-shells-do-in-orphaned-process-groups中的建议在UNIX中重新发布)
简短的问题是,如果外壳程序位于不拥有tty的孤立进程组中,它应该怎么办?但我建议阅读冗长的问题,因为这很有趣。
这是一种有趣且令人兴奋的方法,可以使用您喜欢的外壳将笔记本电脑变成便携式太空加热器(除非您是那些tcsh怪人之一):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
这导致bash将CPU固定在100%。zsh和fish的作用相同,而ksh和tcsh则对工作控制含糊其辞,然后再进行龙骨化处理,这虽然好一些,但效果不明显。哦,这是与平台无关的违规者:OS X和Linux都受影响。
我的解释(可能是错误的)如下:子外壳检测到它不在前台:tcgetpgrp(0) != getpgrp()
。因此,它试图停止自身:killpg(getpgrp(), SIGTTIN)
。但是它的进程组是孤立的,因为它的父级(C程序)是领导者并死亡,并且SIGTTIN
发送给孤立进程组的操作只是被丢弃(否则什么也无法再次启动它)。因此,子外壳并没有停止,但是它仍然在后台,因此马上就可以再次执行所有操作。冲洗并重复。
我的问题是,命令行外壳程序如何检测到这种情况?正确的做法是什么?我有两个解决方案,都不是理想的:
- 尝试通知其pid与我们的组ID匹配的进程。如果使用失败
ESRCH
,则表明我们很可能成为孤儿。 - 尝试从中无阻塞读取一个字节
/dev/tty
。如果使用失败EIO
,则表明我们很可能成为孤儿。
(我们跟踪此问题的是https://github.com/fish-shell/fish-shell/issues/422)
感谢您的想法!