3.2. テキストモードとバイナリモード

UNIX システムでは、アプリケーションがファイルを読み込む際、ディスク上にあるファイルの内容をきっちり正確に読み取り、書き込む際もそれと同様に動作します。 DOS/Windows の世界ではこの状況は異なり、ファイルはバイナリ又はテキストという二つのモードのどちらかで読み込まれます。 バイナリモードでは、システムは UNIX と同様にきっちり正確に動作します。 しかしテキストモードにおける書き込みでは、NL(\n、^J)は CR (\r, ^M) NL の連続へと変換されます。

アプリケーションから見たバイト数が実際のものとは異なってくるため、seek/fseek を呼び出したときには大混乱が発生することでしょう。

以下のプログラミングの章に記述されているように、このモードは明示的に指定することが出来ます。 理想的な DOS/Windows の世界では、行をレコードとみなして動作するプログラム (bashmakesed ... など)はファイルをテキストモードでオープンします (そして標準入出力を使用するときはモードを変更します)。それ以外の全てのプログラム (catcmptr ... など)はバイナリモードを使用します。Cygwin の習慣では、 明示的にオブジェクトファイルを扱うプログラムではバイナリモードを指定します(CR 問題を診断する際に有用である od コマンドがこれに該当します)。 その他の多くのプログラム(catcmptrなど)はデフォルトのモードを使用します。

Cygwin システムには、明示的にモードを指定しなかった場合、どのようにファイルをオープンするかを決定するための柔軟性が備わっています。 このルールは発展中であり、本章ではデザインゴールを示します。

  1. ファイルがマウントされたファイルシステム中に存在するのであれば(パス名が mount によって表示されるディレクトリから始まっていれば)、デフォルトはマウントフラグによって指定されます。 もしファイルがシンボリックリンクであるなら、ターゲットファイルシステムのモードが適用されます。

  2. ファイルがマウントされていないファイルシステム中に存在するのであれば(パスがドライブ文字を含んでいるような場合)、デフォルトはバイナリモードとなります。

  3. CYGWIN 環境変数が nobinmode を含んでいる場合を除き、パイプと非ファイルデバイスはバイナリモードでオープンされます。

  4. Cygwin プログラムがシェルから起動された場合、パイプされるかリダイレクトされる場合を除き、 標準入力、標準出力、標準エラー出力は CYGWIN 環境変数が tty を含んでいればバイナリモードとなり、そうでなければテキストモードとなります。

    リダイレクト時、Cygwin シェルはルール(a-c)を使用します。 これらのシェルが使用する CYGWIN の値はシェルが起動した時点での値であり、プログラムが実行された時点の値ではありません。 非 Cygwin シェルは常にパイプとリダイレクトをバイナリモードで行います。 非 Cygwin シェルでは、テキストマウントされたパーティションに存在する filename に対しては、コマンド cat filename | program program < filename は、異なるものとなります。

最大限の移植性を考慮して書かれた UNIX プログラムはテキストとバイナリのファイルの違いを知っており、Cygwin の元でも適切に動作します。 これらのプログラムにおいては、デフォルトがテキストモードであるのは有用な選択です。公式な Cygwin の配布物中に含まれるプログラムはデフォルトのモードで正しく動作します。

Windows プログラムは通常 CRLF フォーマットを使用するので、テキストモードは Cygwin と Windows プログラムの間でのファイルの混在をより簡単なものにします。 あいにく、テキストモードにはまだ幾つかの問題があります。 まず、Cygwin に含まれる幾つかのユーティリティは、必要なときにもまだバイナリモードを指定しません。 次に、作成するテキストファイルに CR を持ち込むと、それらを UNIX システムに持ち帰った時点で問題が発生することになるでしょう。

UNIX マシンのリモートファイルシステムをマウントするなら、又はファイルを UNIX マシンへ持ち帰るか、持ってくるのであれば、ファイルへのアクセスをバイナリモードで行いたいと考えるでしょう。 テキストファイルは UNIX の NL フォーマットとして通常通り作成され、Cygwin プログラムは UNIX 上で理解可能なフォーマットで全てのファイルを保存することを期待するでしょう。 Makefile とシェルスクリプトからは必ず CR を取り除き、ファイルを編集する場合は NL で終了する行を正しく編集 / 保存することが可能な DOS/Windows のエディタだけを使わなければなりません。

モードはディスク単位で決定することが出来ます(例えば、ローカルディスクはテキストモードでマウントし、ネットワークディスクはバイナリモードでマウントすることが出来ます)。 ディスクのパーティションについても同様です。 例えば、c: をテキストモードで、c:\home をバイナリモードでマウント出来ます。