2012-12-05 22 views
25

短い質問は、ttyを所有していない孤立したプロセスグループにシェルがあればどうしたらいいでしょうか?しかし、私はそれが面白いので、長い質問を読むことをお勧めします。ここで孤立したプロセスグループで対話シェルを実行するにはどうすればよいですか?

は(あなたがそれらのtcshの変人の1でない限り)あなたの好きなシェルを使用して、ポータブルストーブにあなたのラップトップをオンにする楽しさと刺激的な方法である:

#include <unistd.h> 
int main(void) { 
    if (fork() == 0) { 
     execl("/bin/bash", "/bin/bash", NULL); 
    } 
    return 0; 
} 

これは、PEGにはbashを引き起こし100%のCPU。 zshと魚は同じことをしますが、kshとtcshはジョブコントロールについて何か不具合を起こしてしまいます。 OS XとLinuxはどちらも影響を受けています。

私の(潜在的に間違った)説明は次のとおりです:子のシェルは、フォアグラウンドにないことを検出します:tcgetpgrp(0) != getpgrp()。したがって、それ自体を停止しようとします:killpg(getpgrp(), SIGTTIN)。しかし、そのプロセスグループは親(Cプログラム)がリーダーであり、死んでしまって、孤立したプロセスグループに送られたSIGTTINが破棄されただけで孤立しています(そうでなければ何も再開できません)。したがって、子シェルは停止していませんが、バックグラウンドのままですので、すぐに再開します。すすぎ、繰り返します。

私の質問は、コマンドラインシェルがこのシナリオをどのように検出することができるのか、そしてそれが正しいことは何ですか?私の考えは、シェルがstdinからreadにしようとしていて、読み込みがEIOであれば終了します。

あなたの考えをありがとう!

編集:/ dev/ttyにゼロ長のread()を実行しようとしましたが、これは問題ありません。 EIOを入手するには、実際には/ dev/ttyのデータを読み込む準備が必要です。

:私が持っていた別の考えはkill(getpgrp(), 0)でした。プロセスグループが孤立している場合、これは常に失敗すると私は信じています。しかし、私はセッションリーダーに信号を送る許可がないので、失敗することもあります。

編集:これを後で知る人には、私がやったことはhttps://github.com/fish-shell/fish-shell/issues/422に記載されています。また、未来はどうですか?ここで

+5

+1ポータブルスペースヒーターのコメント。私はおびえた;) –

+2

は、http://unix.stackexchange.com/のベストスイートになります。 – mtk

+1

@ウィルこれはプログラミングの質問ではありません。 – Gilles

答えて

3

は何が起こっているのかstraceのは言うです:それについて何をすべきかについては

while ((terminal_pgrp = tcgetpgrp (shell_tty)) != -1) 
    { 
     if (shell_pgrp != terminal_pgrp) 
     { 
      SigHandler *ottin; 

      ottin = set_signal_handler(SIGTTIN, SIG_DFL); 
      kill (0, SIGTTIN); 
      set_signal_handler (SIGTTIN, ottin); 
      continue; 
     } 
     break; 
    } 

...よくそれは超えてい:jobs.cから、bashの4.2なぜ、

 
--- SIGTTIN (Stopped (tty input)) @ 0 (0) --- 
rt_sigaction(SIGTTIN, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
ioctl(255, TIOCGPGRP, [9954])   = 0 
rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
kill(0, SIGTTIN)      = 0 
--- SIGTTIN (Stopped (tty input)) @ 0 (0) --- 
rt_sigaction(SIGTTIN, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
ioctl(255, TIOCGPGRP, [9954])   = 0 
rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
kill(0, SIGTTIN)      = 0 
[repeat...] 

、ここでは、私の能力。しかし、私はこれが有用な情報だと思っていましたが、少しコメントになりました。

関連する問題