(/programming/13718394/what-should-interactive-shells-do-in-orphaned-process-groupsの提案に従ってUNIXに再投稿する)
簡単な質問は、ttyを所有していない孤立したプロセスグループ内にある場合、シェルは何をすべきかということです。しかし、面白いので、長い質問を読むことをお勧めします。
以下は、お気に入りのシェルを使用して、ラップトップをポータブルスペースヒーターに変える楽しくてエキサイティングな方法です(tcshの変人の1人でない限り)。
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
これにより、bashはCPUを100%に固定します。zshとfishは同じことをしますが、kshとtcshはジョブ制御について何かをつぶやいてからキールします。これは少し優れていますが、それほど多くはありません。ああ、それはプラットフォームにとらわれない犯罪者です。OSXとLinuxの両方が影響を受けます。
私の(潜在的に間違っている)説明は次のとおりです:子シェルがそれがフォアグラウンドにないことを検出しました:tcgetpgrp(0) != getpgrp()
。したがって、それ自体を停止しようとしますkillpg(getpgrp(), SIGTTIN)
。しかし、その親(Cプログラム)がリーダーで死亡したため、そのプロセスグループは孤立SIGTTIN
しています。孤立したプロセスグループに送信されたものは削除されるだけです(それ以外の場合は、再び起動できません)。したがって、子シェルは停止されませんが、まだバックグラウンドにあるので、すぐにすべてが再び実行されます。すすぎ、繰り返します。
私の質問は、コマンドラインシェルがこのシナリオをどのように検出できるか、そしてそれを行うための正しいことは何ですか?私には2つの解決策がありますが、どちらも理想的ではありません。
- pidがグループIDと一致するプロセスにシグナルを送ろうとします。それがで失敗する場合
ESRCH
、それはおそらく孤立していることを意味します。 - から1バイトのノンブロッキング読み取りを試みます
/dev/tty
。それがで失敗する場合EIO
、それはおそらく孤立していることを意味します。
(これを追跡する私たちの問題はhttps://github.com/fish-shell/fish-shell/issues/422です)
あなたの考えをありがとう!