パイプ処理
以前javaエディタを作った時、コンパイル結果をパイプ経由で取得することにしました。
google先生で調べたら CreatePipe関数→ReadFile関数としなさい、とあったのでその通りにしました。
ところが実行中の標準出力も同じように取得してみたところ、その実行が終わるまでエディタが固まってしまいます。
というのも、ReadFile関数はブロック関数で、何か受信するまで処理を返さないからです。
ネットワーク関数でいうselectに相当するものはないかとMSDNを眺めていると、PeekNamedPipe関数というのがありました。
標準出力を覗き見る関数です。何かあれば(ReadFileするタイミング)教えてくれます。
NamedPipeなのに名前無しパイプも扱えます。(その変な名前のおかげで探すのに時間掛かりました^^;;)*1
while(1)
{
// ウィンドウメッセージ処理
...// データがあるかどうか見る
if (::PeekNamedPipe(hRead, NULL, 0, NULL, &dwRead, NULL)==0) {
// 対象のプロセスが終了した
break;
}
if (dwRead==0) {
// データがない!
::Sleep(50);
continue;
}
// 読み取る
::ReadFile(hRead, pBuffer.get(), nSize, &dwRead, NULL);
}
ということでした。