パイプ ハンドルの継承

パイプ サーバーは、ハンドルを次の方法で継承できるかどうかを制御します。

  • CreatePipe 関数は、SECURITY_ATTRIBUTES構造体を受け取ります。 パイプ サーバーでこの構造体の bInheritHandle メンバーを TRUE に設定すると、 CreatePipe によって作成されたハンドルを継承できます。
  • パイプ サーバーは DuplicateHandle 関数を使用して、パイプ ハンドルの継承を変更できます。 パイプ サーバーは、継承可能なパイプ ハンドルの継承不可能な複製、または継承不可能なパイプ ハンドルの継承可能な複製を作成できます。
  • CreateProcess 関数を使用すると、パイプ サーバーは、子プロセスが継承可能なハンドルのすべてまたはまったく継承しないかどうかを指定できます。

子プロセスがパイプ ハンドルを継承すると、システムはプロセスがパイプにアクセスできるようにします。 ただし、親プロセスは、ハンドル値を子プロセスと通信する必要があります。 通常、親プロセスでは、次の手順に示すように、標準出力ハンドルを子プロセスにリダイレクトすることでこれを行います。

  1. GetStdHandle 関数を呼び出して、現在の標準出力ハンドルを取得します。子プロセスの作成後に元の標準出力ハンドルを復元できるように、このハンドルを保存します。
  2. SetStdHandle 関数を呼び出して、標準出力ハンドルをパイプへの書き込みハンドルに設定します。 親プロセスで子プロセスを作成できるようになりました。
  3. CloseHandle 関数を呼び出して、パイプへの書き込みハンドルを閉じます。 子プロセスが書き込みハンドルを継承した後、親プロセスはそのコピーを必要としません。
  4. SetStdHandle を呼び出して、元の標準出力ハンドルを復元します。

子プロセスでは 、GetStdHandle 関数を使用して標準の出力ハンドルを取得します。これは、パイプの書き込み終わりへのハンドルになりました。 その後、子プロセスは WriteFile 関数を使用して出力をパイプに送信します。 子がパイプの使用を終了したら、 CloseHandle を呼び出すか、 を終了してパイプ ハンドルを閉じる必要があります。これにより、ハンドルが自動的に閉じられます。

親プロセスでは 、ReadFile 関数を使用してパイプから入力を受け取ります。 データは、バイトストリームとして匿名パイプに書き込まれます。 つまり、親プロセスと子プロセスの両方がプロトコルを使用して書き込み操作が終了する場所を示さない限り、パイプからの読み取りでは、個別の書き込み操作で書き込まれたバイトを区別できません。 パイプへのすべての書き込みハンドルを閉じると、 ReadFile 関数は 0 を返します。 親プロセスでは、 ReadFile を呼び出す前に、パイプの書き込み側にハンドルを閉じる必要があります。 この操作を行わないと、親プロセスにパイプの書き込み終了に対する開いているハンドルがあるため、 ReadFile 操作は 0 を返すことができません。

標準入力ハンドルをリダイレクトする手順は、パイプの読み取りハンドルが子の標準入力ハンドルとして使用される点を除き、標準出力ハンドルをリダイレクトする手順と似ています。 この場合、親プロセスは、子プロセスがパイプの書き込みハンドルを継承しないようにする必要があります。 これを行わない場合、子プロセスがパイプの書き込み終了に対して開いているハンドルを持っているため、子プロセスによって実行される ReadFile 操作は 0 を返すことができません。

匿名パイプを使用して子プロセスの標準ハンドルをリダイレクトするプログラムの例については、「 リダイレクトされた入出力を使用した子プロセスの作成」を参照してください。