Skip to main content.

managed オプションを利用したマウント

Cygwin 1.5.0 から mount 機能に導入された「managed」オプションを利用すると、大文字小文字が異なるだけのファイル名(例: Makefile と makefile)を区別することが出来るようになります。ここでは、managed オプションの利用方法と、その制限について説明します。

managed オプションとは

そもそも、Windows のファイルシステムには次のような制限があります。

Cygwin も Windows アプリケーションの一種なので、Windows のファイルシステム内に格納可能なファイル名しか扱うことが出来ません。 しかし Cygwin 1.5.0 から mount に追加された「managed」オプションを利用すれば、ファイル名を Cygwin そのものに管理させることが可能になります。Cygwin がファイル名の管理を行うことによって、Windows の中の世界では許されないようなファイル名のファイルを作成することが出来るようになるわけです。尤も、Cygwin は Windows アプリケーションの一つに過ぎませんから、managed オプションが提供する世界の実現のためにかなりの無理をしています。

managed オプションが採用した手法は、次のようなものです。

具体的には、次のようにしています。

  1. *」や「:」など、Windows ではファイル名として使えない文字を「% + ASCII」という形式で表現する。
  2. 大文字小文字が異なるだけのファイル名に対応するため、アルファベットの大文字は全て「% + ASCII」という形式で表現する。
  3. 「aux」や「prn」のような予約済みファイル名については、ファイル名の先頭を「% + ASCII」という形式で表現する。

*1: NTFS では区別することが可能ですが、互換性維持のため、区別しないようになっています。

利用方法

managed オプションを利用するには、

$ mount -u -o managed c:/somewhere /somewhere

のように「-o managed」を付けてマウントを実行します(「-o」オプションは 1.5.0 で新しく追加されたもので、複数のオプションを纏めて指定する際に利用します)。マウントの結果は次のようになりますが、マウント「somewhere」の「managed」という表示に注目して下さい。

$ ./mount.exe
D:Cygwin\usr\X11R6\lib\X11\fonts on /usr/X11R6/lib/X11/fonts type system (binmode)
c:\somewhere on /somewhere type user (binmode,managed)
D:Cygwin\bin on /usr/bin type system (binmode)
D:Cygwin\lib on /usr/lib type system (binmode)
  :

managed オプションの実際

大文字小文字の区別

managed オプションを有効にしてマウントしたディレクトリで、さっそく実験してみました。

$ touch makefile
$ touch Makefile
$ ls -la
合計 0
drwxr-xr-x+   2 riue     none            0 Jul  6ニ・17:26 ./
drwxr-xr-x+  10 root     none         4096 Jun 14ニ・21:50 ../
-rw-r--r--    1 riue     none            0 Jul  6ニ・17:26 Makefile
-rw-r--r--    1 riue     none            0 Jul  6ニ・17:26 makefile

見ての通り、「Makefile」と「makefile」が同居出来ています。しかしこのディレクトリをエクスプローラなどから参照すると、「Makefile」については「%4Dakefile」というファイル名になっているということが分かります。「ABC」というファイル名であれば、Windows 上での(正しい)ファイル名は「%41%42%43」となることになります。

特殊文字が含まれるファイル

特殊文字については、Windows 環境では利用出来ない「:」、「*」、「?」の 3 文字が新しく使えるようになりました。これによって、「aaa:bbb」といったファイルを作成することが出来るようになります。特殊文字も「% + ASCII」という形式で表現されますから、「aaa:bbb」の実際のファイル名は「aaa%3Abbb」となることになります。但し、「\」、「/」、「"」「<」、「>」、「|」については、やはり利用出来ません。

$ touch 1\\A 1\/A 1\:A 1\*A 1\?A 1\"A 1\<A 1\>A 1\|A
touch: creating `1\\A': No such file or directory
touch: creating `1/A': No such file or directory
touch: creating `1"A': No such file or directory
touch: creating `1<A': No such file or directory
touch: creating `1>A': No such file or directory
touch: creating `1|A': No such file or directory
$ ls
1*A  1:A  1?A

予約済みファイル名

予約済みファイル名は全て利用可能となっています。aux については「%61ux」、prn については「%70rn」のように、各予約済みファイル名の先頭の文字を「% + ASCII」という形式にエンコードしています。

$ touch con aux prn nul com1 lpt1
$ ls
aux  com1  con  lpt1  nul  prn

問題点

ちょっと使っただけでも、ボロボロと問題が見えてしまいました。

  1. touch 'c:bb'」を実行したところ、C ドライブのルートディレクトリにファイル「bb」が作成されました。Cygwin は現在利用可能なドライブを全て「ドライブ文字:」という名前でマウントするため、「c:bb」は「c: ドライブ直下の bb」と解釈されてしまうのです。
  2. Windows 上で「大文字が含まれたファイル」を作成した場合、そのファイルを Cygwin から扱おうとすると ENOENT が返ります(ユーザから見れば、「No such file or directory」です)。少なくとも現在の Cygwin DLL は「managed モードでマウントされている場所では、ファイル名中の大文字は常に『% + ASCII』として表現される」ことを前提としているようであり、Windows 側でファイル名に直接大文字が利用されることは想定していないようです。大文字が入ると駄目なので、一部の日本語の文字(例: 「新規」)なども使えません。
  3. 上記に関連しますが、ASCII の大文字が含まれる日本語の文字については、「% + ASCII」のエンコーディングによって酷い文字化けを起こします。仮に「touch '新規.txt'」を実行しようものなら、そのファイルは Windows 上では「・56・4B.txt」のように見えてしまいます。しかも、Cygwin 側でも「新規.txt」にはデコードされません。

実用に値するか?

少し使ってみただけでもこれだけの問題がある以上、全てのマウントに対して managed オプションを採用するのは危険過ぎます。必要がある場合にだけ利用するというのが正しい利用方法ではないでしょうか。特に、一般の Windows アプリケーションでファイルを頻繁に作成するようなディレクトリを managed してしまうと、悲惨な事態を招くことになると思います。