0

コードが問題を引き起こした場合に親に影響を与えず、親が報告できるように、特定のコードをフォークされた子にカプセル化するコードがあります。

私は電話execの後ではありません。fork単純forkに、通常は親で実行されるコードが実行されます。

子のコードは、 と に出力しstdoutますstderr。出力のインターリーブとstdioバッファリングに問題があるため、より良い解決策を求めてTLPIを検討していました。

私が思いついたアイデアは、おおよそ次のとおりです。

  • pipe()ストリームごとに
  • fork()
  • 子で:
    • close()パイプの終わりを読む
    • dup2()stdoutおよびstderrそれぞれのファイル記述子への書き込みが終了します
    • setbuf(fd, NULL)stdio子内のストリーム バッファリングをオフにします。
  • 親で:
    • close()パイプの端を書く
    • select/ pselect/ epolletc(Linux、BSD、AIX、Solarisなどで実行する必要があります)を使用して、新しいデータのパイプの読み取り端を監視し、それがwrite()親プロセスのそれぞれのファイル記述子に直接到着したとき。

さて、私は子供dup2の中で と の間に 1 つのステップが欠けていると思います。setbufそれは何ですか?

setbufFILE*当然のことですが、にdup2作用しintます。

freopen頭に浮かびましたが、それにはパスが必要です。新しい fileno をストリームに割り当てたいだけの場合は、どうすればよいですか?

4

1 に答える 1

1

extern変数、およびstdinはポインターです。これらを/に渡すことができます。ただし、子には別のアドレス空間があるため、 の時点でバッファの状態を継承しますが、両方ともバッファを安全に使用し続けることができます。stdoutstderrFILE *setbufsetvbuffork()fflush STDOUTSTDERR

これは私が子で行う方法です(テストされていないため、エラー処理を追加してください):

void
child ( ... )
{
  const char *devnull = "/dev/null";

  /* turn off buffering */

  setvbuf (stdin, NULL, _IONBF);
  setvbuf (stdout, NULL, _IONBF);
  setvbuf (stderr, NULL, _IONBF);

  for (i = getdtablesize () - 1; i >= 0; i--)
    {
      if ((i != write_end_of_pipe1) && (i != write_end_of_pipe2))
        close (i);
    }

  i = open (devnull, O_RDWR);
  if (i == -1)
    {
      fprintf (stderr, "Unable to open /dev/null\n");
      return;
    }

  i = open (devnull, O_RDONLY);
  if (i != 0)
    {
      dup2 (i, 0);
      close (i);
    }

  dup2 (write_end_of_pipe1, 1);
  close (write_end_of_pipe1);

  dup2 (write_end_of_pipe2, 2);
  close (write_end_of_pipe2);

  return;
}
于 2014-04-03T12:50:16.020 に答える