日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトル
目次
まえがき
リファレンス・セクション
   ≫ライブラリ関数一覧
索引
PDF
OpenVMS ホーム

HP OpenVMS
HP C ランタイム・ライブラリ・リファレンス・マニュアル (下巻)


目次 索引




親プロセスと子プロセスの間でデータの読み書きに使用できる一時的なメールボックスを作成します。プロセスが通信に使用するチャネルは,パイプと呼ばれます。

形式

#include <unistd.h>

int pipe (int array_fdscptr[2]); (ISO POSIX-1)

int pipe (int array_fdscptr[2], ...); (HP C Extension)


引数



array_fdscptr

ファイル記述子の配列。パイプは,メールボックスに関連付けられたファイル記述子の配列として実装されます。これらのメールボックス記述子は, isapipe関数に渡されたときに 1 を返すファイル記述子であるという点で特殊な存在です。

ファイル記述子は,次のように割り当てられます。

  • 最初の利用可能なファイル記述子が書き込みに割り当てられ,次の利用可能なファイル記述子が読み込みに割り当てられる。

  • その後,ファイル記述子は配列に逆順に格納される。要素 0 には読み込みのためのファイル記述子が格納され,要素 1 には書き込みのためのファイル記述子が格納される。



...

3 つのオプションの定位置引数 flagbufsize,およびbufquota を表します。

flag

ビットマスクとして使用されるオプションの引数。

O_NDELAY または O_NONBLOCK ビットが設定されていると, array_fdscptr ファイル記述子を通してのメールボックスへの I/O 操作は,他のプロセスを待つのではなく,ただちに終了します。

たとえば,O_NDELAY ビットが設定されており,親プロセスがメールボックスにデータを入れる前に,子プロセスがメールボックスに対する read要求を発行すると, readは 0 ステータスでただちに終了します。 O_NDELAY ビットも O_NONBLOCK ビットも設定されていない場合は,子プロセスは,親プロセスがメールボックスにデータを書き込むまで待ってから読み込みを行います。これは,flag 引数が指定されなかった場合のデフォルトの動作です。

O_NDELAY と O_NONBLOCK の値は <fcntl.h>ヘッダ・ファイルに定義されています。 flag 引数の中のその他のビットはすべて無視されます。この引数は,第 2 のオプションの定位置引数 bufsize が指定されている場合には,必ず指定する必要があります。 bufsize 引数を指定するためだけの目的に flag 引数を指定する場合には,flag として 0 を指定してください。

bufsize

メールボックスのサイズをバイト単位で指定する int型の引数 (オプション)。 512 〜 65535 の値を指定します。

この引数に 0 を指定するか,この引数を省略すると,オペレーティング・システムはデフォルトのサイズ (512 バイト) のメールボックスを作成します。

0 より小さい,または 65535 より大きい値を指定すると,予期できない結果となります。

この引数を指定する場合は, flag 引数を前に指定してください。

DECC$PIPE_BUFFER_SIZE 機能論理名を使用しても,メールボックスのサイズを指定できます。 bufsize を指定すると, DECC$PIPE_BUFFER_SIZE の値よりも優先されます。指定しないと,DECC$PIPE_BUFFER_SIZE の値が使用されます。

bufsize と DECC$PIPE_BUFFER_SIZE のどちらも指定しなかった場合は,デフォルトのバッファ・サイズ 512 が使用されます。

bufquota

パイプのメールボックスのバッファ・クォータを指定する int型の引数 (オプション)。 512 〜 2147483647 の値を指定します。

OpenVMS Version 7.3-2 で,この引数が追加されました。以前のバージョンの OpenVMS では,バッファ・クォータとバッファ・サイズは同じでした。

DECC$PIPE_BUFFER_QUOTA 機能論理名を使用しても, バッファ・クォータを指定できます。 pipe関数の bufquota オプション引数を指定すると, DECC$PIPE_BUFFER_QUOTA の値よりも優先されます。指定しないと,DECC$PIPE_BUFFER_QUOTA の値が使用されます。

bufquota と DECC$PIPE_BUFFER_QUOTA のどちらも指定しなかった場合,バッファ・クォータは以前と同じように,デフォルトでバッファ・サイズとなります。


説明

パイプのために使われるメールボックスは,一時的なメールボックスです。メールボックスは,そのメールボックスに対するチャネルをオープンしているすべてのプロセスがそれらのチャネルをクローズするまでは削除されません。パイプを最後にクローズするプロセスは,メールボックスに対して,ファイルの終端を示すメッセージを書き込みます。

メールボックスは,以下の特性を指定して,$CREMBX システム・サービスを使って作成されます。

  • 最大メッセージ長は 512 文字

  • バッファ・クォータは 512 文字

  • USER および GROUP にすべての特権を与え, SYSTEM または WORLD には何の特権も与えない保護マスク

512 文字のバッファ・クォータは,メールボックスの全体または一部の読み込みを行うまで,メールボックスに 512 文字以上の書き込みを行えないということを意味しています。メールボックス・レコードは,それが含んでいるメッセージのデータ部よりも若干大きいので, 512 文字すべてをメッセージ・データに使用できるわけではありません。バッファのサイズは, pipe関数のオプションの第 3 引数によって代替サイズを指定することで増やすことができます。 OpenVMS システムにおけるパイプは,キャリッジ・コントロール属性を持たないストリーム型のファイルです。 HP C RTL では,これはデフォルトで完全にバッファリングされます。パイプとして使用されるメールボックスは,アプリケーションによって作成されるメールボックスとは異なります。アプリケーションによって作成されるメールボックスは,デフォルトでは,キャリッジ・リターンとキャリッジ・コントロールを含むレコード型のファイルになります。さらに,メールボックスに長さゼロのレコードを書き込んだときと,メールボックスがクローズされるたびに,EOF が書き込まれます。一方,パイプでは,パイプの最後のクローズのみが EOF を書き込みます。

パイプは, vforkexec関数が呼び出される前に,親プロセスによって作成されます。子プロセスは,まず pipeを呼び出すことで,パイプのオープン・ファイル記述子を継承します。その後, getname関数を使って,必要ならばパイプに関連付けられているメールボックスの名前を返すことができます。 getnameから返されるメールボックス名は, nnnn または nnnnn を一意の数として, _MBAnnnn: (Alpha only) または _MBAnnnnn: (Integrity only) の形式を持っています。

親と子の両方が,パイプに対してどのファイル記述子が割り当てられるのかを事前に知る必要があります。この情報は実行時に取得することはできません。このため, HP C for OpenVMS プログラムにおいてファイル記述子がどのように使われるかを理解しておくことが重要となります。ファイル記述子の詳細については,『HP C ランタイム・ライブラリ・リファレンス・マニュアル(上巻)』第 2 章を参照してください。

ファイル記述子 0,1,および 2 は, HP C for OpenVMS プログラムでは,それぞれ stdin(SYS$INPUT), stdout(SYS$OUTPUT), および stderr(SYS$ERROR) に対してオープンされています。このため, pipeが呼び出されたときに他のファイルがオープンされていない場合, pipeはファイル記述子 3 を書き込み用に,ファイル記述子 4 を読み込み用に割り当てます。 pipeから返される配列では,要素 0 に 4 が,要素 1 に 3 が格納されます。

他のファイルがオープンされている場合, pipeは最初の利用可能なファイル記述子を書き込み用に,次の利用可能なファイル記述子を読み込み用に割り当てます。この例では,パイプは必ずしも隣接するファイル記述子を使用しません。たとえば,2 つのファイルがオープンされ,ファイル記述子 3 と 4 が割り当てられた後に,前者のファイルがクローズされたとします。この時点で pipeが呼び出されると,ファイル記述子 3 が書き込み用に,ファイル記述子 5 が読み込み用に割り当てられます。配列の要素 0 には 5 が,要素 1 には 3 が格納されます。

大量の I/O を行う大きなアプリケーションでは,パイプにどのファイル記述子が割り当てられるかを予測するのがさらに困難になります。しかし,子プロセスは,どのファイル記述子が使われるかを知っていないと,パイプの読み書きを正しく行うことができません。

正しいファイル記述子が使われるようにするには,次の手順を使用する方法があります。

  1. 親と子の両方が知っている 2 つの記述子番号を選択する。これらの番号は,パイプが作成される前に行われる I/O を考慮に入れて,十分に大きな値でなくてはならない。

  2. 親プロセスの中で, exec関数を呼び出す前のいずれかの時点で pipeを呼び出す。

  3. 親プロセスの中で, dup2を使用して, pipeから返されたファイル記述子を,上で選んだファイル記述子に割り当てる。これにより,これらのファイル記述子がパイプ用に予約される。それ以降の I/O は,パイプと干渉することはない。

UNIX I/O 関数の readwriteを使用し,適切なファイル記述子を指定することで,パイプを通しての読み書きを行うことができます。別の方法として, fdopen呼び出しを発行して,これらのファイル記述子にファイル・ポインタを関連付ければ,標準 I/O 関数 ( freadfwrite) を使用できるようになります。

パイプの読み込みと書き込みには 2 つの異なるファイル記述子が使用されますが,使用されるメールボックスは 1 つだけなので,何らかの I/O の同期化が必要となります。たとえば,親プロセスがパイプにメッセージを書き込んだとします。親プロセスがパイプから読み込みを行う最初のプロセスだった場合には, 図 1-1 に示すように,自分のメッセージを読み戻すことになります。

  注意
UNIX との互換性を高めるため,以下の機能論理名を使用して, C RTL のパイプ処理の動作を制御することができます。

  • DECC$STREAM_PIPE 機能論理名に ENABLE を定義すると, pipe関数がレコード入出力ではなくストリーム入出力を使用するようになります。

  • DECC$POPEN_NO_CRLF_REC_ATTR 機能論理名に ENABLE を定義すると, popen関数でオープンしたパイプのパイプ・レコードに,CR/LF のキャリッジ制御が追加されなくなります。この機能を有効にすると, getsのようなキャリッジ・リターン文字に依存している関数で,望ましくない動作になる可能性がある点に注意してください。

図 1-1 パイプの読み込みと書き込み



戻り値

0 成功を示します。
-1    エラーを示します。


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.