POSIXベースのプログラムを使用してVOSの構造化ファイルを処理しようとしたことがある人は、いくつかの制限に遭遇したり、理解できない動作を見たことがあるかもしれません。この記事では、何が起こっているのかを説明してみたいと思います。
VOSは、シーケンシャルファイル、相対ファイル、固定ファイル、ストリームファイルの4種類のファイルをサポートしています。最初の3つの形式は、ファイルシステムがレコードの境界を追跡するため、「構造化された」ファイルと呼ばれています。利用可能なI/O操作は、レコード全体を読み書きします。最後の形式は、レコードの境界が暗黙のうちにあるため、「非構造化」と呼ばれます。利用可能なI/O操作は、バイトのシーケンスを読み書きします。
Unix® や Linux© システムで見られるような POSIX 準拠の環境では、「レギュラーファイル」と呼ばれるネイティブのファイルタイプが 1 つしかありません。VOS ストリームファイルの構成は POSIX レギュラーファイルと同等です。
VOS POSIXランタイム環境は、4種類のファイルをすべてPOSIXレギュラーファイルとして分類します。したがって、少なくとも理論的には、どんなPOSIXプログラムでも4つのファイルタイプのいずれかを読み書きすることができます。しかし、それほど単純ではありません。
POSIX APIはすべてのI/O操作をバイトのシーケンスで定義していますが、VOSは(構造化ファイル上の)I/O操作をレコードのシーケンスで定義しているため、VOS POSIXランタイムは、ユーザー空間に現在のレコードをバッファリングし、そのバッファ上でPOSIX I/O操作を実行し、バッファリングされたレコードを適切なポイントに書き戻すことで、その違いを仲介します。
POSIXプログラムが各レコードのサイズを知っていて(例えば、固定ファイルの場合)、正確なバイト数を読み書きしていれば、バッファの存在は操作に影響を与えず、2種類のI/O操作のマッピングは理解しやすく効率的です。
しかし、POSIXプログラムが基本的なレコードサイズを無視してバイトのストリームを読み書きしている場合、POSIXセマンティクスとVOSセマンティクスのマッピングは、よく定義されているものの、一般的にはあまり有用ではなく、非常に非効率的であることが多いです。バイトの位置を求めたり、レコードの境界を越えたバイト列を書き換えたりするような特定の操作は、よくても非効率的で、最悪の場合は不可能です。
次に、改行文字の扱いの問題があります。
POSIX レギュラーファイルと VOS ストリームファイルの両方とも、レコードの境界を区別するために改行文字を使用します。しかし、構造化ファイル内のVOSレコードは、通常、改行文字を含みません。例えば、VOSエディタ(edit、emacs、line_editなど)が新しいシーケンシャルファイルを作成すると、各レコードには1行のテキストが含まれます。しかし、レコードは改行文字では終わりません。慣習的に、プログラムはすべて、テキストを含むシーケンシャルファイルは、各レコードの最後に暗黙の改行があると仮定しています。これは相対ファイルや固定ファイルでも同じことが言えます。しかし、ここで重要な点があります: どんなファイル(VOS、Unix、構造化、非構造化)の属性も、そのファイルがテキストデータを含んでいるかバイナリデータを含んでいるかを記録しません。この区別は、ファイルにアクセスするプログラムに委ねられています。
この状況は、VOS POSIXランタイムのための何かの難問を作成します。それは、各レコードに改行を追加するかどうかを知るために、VOS構造化ファイルがテキストまたはデータを含むかどうかを知る必要があります。ファイルにテキストが含まれている場合、改行を追加する必要があります。データが含まれている場合は、改行を追加すべきではありません。
答えは、VOS POSIXランタイムがこの情報を提供するかどうかは呼び出し元に依存しているということです。デフォルトでは、POSIXランタイムは、構造化ファイルをテキストを含むかのように扱い、改行を追加します。VOS 構造化ファイルをデータを含むように扱いたい呼び出し元は、O_BINARY 開きモードを提供する必要があります。これら 2 つのモードは相互に排他的で、一方を指定した場合、他方を指定してはいけません。これらのモードはストリームファイルには必要ないので、この場合は無視されます。
この投稿を読んでいる言語専門家のために、O_TEXTとO_BINARYはPOSIX標準の拡張であり、POSIX自体で定義されていないことを簡単に説明しておきます。これらは通常、(VOSのように)テキストファイルとバイナリファイルを区別したり、(Windows のようにCR-LFを使用して)特別な行末規則を持つオペレーティングシステムにのみ存在するものである。
ポリシーにより、Stratus が POSIX ベースのソフトウェアを OpenVOS に移植する際には、FIXED ファイルおよび RELATIVE ファイルの使用を排除するように変更し、SEQUENTIAL ファイルには読み取り専用のアクセスを制限する。また、すべてのシーケンシャルファイルにはテキストが含まれていると仮定しています。私たちの経験では、これらの規則はPOSIXプログラムの入力としてSTREAMファイルやSEQUENTIALファイルを使用することを実用的にし、SEQUENTIAL出力ファイルでバイト指向の演算を実行しようとする際の固有の非効率性を回避します。
まとめると、POSIXベースのプログラムではSTREAMファイル(入力または出力用)とSEQUENTIALファイル(テキストのみの入力用)のみを使用することにこだわるのが最善の方法です。構造化ファイルにバイナリデータがある場合は、小さなプログラムを書いてそれをストリームファイルにコピーし、POSIXプログラムでそのファイルのストリームバージョンを使用します。POSIX系プログラムで処理したいFIXEDファイルやRELATIVEファイルにテキストデータがある場合は、まずSTREAMファイルにコピーします。