簡単な質問は、シェルが 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 はドロップされます (そうしないと、プロセス グループを再び開始することはできません)。したがって、子シェルは停止されませんが、まだバックグラウンドにあるため、すべてがすぐに再実行されます。すすいで繰り返します。
私の質問は、コマンド ライン シェルがこのシナリオをどのように検出できるのか、そしてそれが行うべき正しいことは何なのかということです。私の考えでは、シェルはread
stdin から試行し、read が EIO を与えると終了します。
ご感想ありがとうございます!
編集: /dev/tty で長さゼロの read() を実行しようとしましたが、成功しました。これは悪いことです。EIO を取得するには、/dev/tty からデータを読み取る準備をしておく必要があります。
編集:私が持っていた別の考えはkill(getpgrp(), 0)
. プロセス グループが孤立している場合、これは常に失敗すると思います。ただし、セッション リーダーに通知する権限がないため、失敗することもあります。
編集:後でこれを見つけた人のために、私がやったことはhttps://github.com/fish-shell/fish-shell/issues/422で説明されています。また、将来はどうですか?