メタキャラクタの展開は誰の仕事か

MSDOSの時代には、ワイルドカード * と ? の展開は、アプリケーション側の仕事だった。command.com のコマンドラインで *.txt と入力されていれば、アプリケーション側にもそのままのかたちで渡されていた。Cでいったらargvに *.txt というのがそのまま入っていた。アプリケーションは自分でディレクトリのファイル一覧を取得して、パターンにマッチするものだけを取り出す必要があった。

UNIXではメタキャラクタの展開はシェルの仕事だ。シェルがexecvpなどを使ってアプリケーションを起動する前に、引数にメタキャラクタを含んだものがないかを探して、メタキャラクタが含まれていたらそれを展開してアプリケーションに渡す。そのため、展開した結果がでかかったりすると argument too long などと出て、シェルはアプリケーションを起動しなくなる。
Windowsになってワイルドカードを使える場面自体がほとんどなくなったが、いつのまにかWindowsでのワイルドカードの展開はファイルシステムの仕事になっていた。アプリケーションでもなくシェルでもなくてファイルシステムの仕事に。

コマンドラインで

dir e:\
としたとき、dirコマンドは e:\ がディレクトリかどうかを確認し、ディレクトリだとわかるとおそらく FindFirstFile を呼び出してファイルの一覧を取得する。第一引数に指定するファイル名には
A pointer to a null-terminated string that specifies a valid directory or path, and file name that can contain wildcard characters, for example, an asterisk (*) or a question mark (?).

という説明が加えてあることから、このAPIがワイルドカードをサポートしているのがわかる。このAPIの処理は、カーネルの中でさらに細かい単位に分解されて、最終的にファイルシステムドライバに IRP_MJ_DIRECTORY_CONTROL/IRP_MN_QUERY_DIRECTORY という、ディレクトリの一覧を返す処理をするリクエストになる。このときにもワイルドカードを含むファイル名が渡されてくる。カーネル内の FindFirstFile<=>IRP_MJ_DIRECTORY_CONTROL/IRP_MN_QUERY_DIRECTORY の変換を行う抽象化層でマッチングを行ってはくれないのだ。そのためファイルシステムドライバは自分でワイルドカードのマッチングを行って、一致するものだけを返す必要がある。さすがにファイルシステムごとにワイルドカードマッチングコードを書く必要はなく(カーネルモードで文字列処理をするコードを書くのはやや骨が折れる)、カーネルが FsRtlIsNameInExpression というAPIを提供していて、これを呼ぶことで与えた文字列が特定のワイルドカードを含むパターンにマッチするかを返してくれるようになっている。

Linuxの場合はVFSにreaddirというファンクションがあり、この関数を呼ぶと特定のノードのエントリすべてが返ってくるようになっている(とおもう)。おそらく、シェルはreaddirでディレクトリのすべてのエントリを取得し、ひとつひとつのエントリがパターンにマッチするかのテストを行って、マッチしたものをアプリケーションの引数として展開しているのだろう。

Windowsのディレクトリ内のファイル一覧取得に関する設計は、ファイルシステムドライバとカーネル間で転送されるデータ量を最小限にとどめ、パフォーマンスを改善することが可能だ。しかし、実際のところFindFirstFileがディレクトリ内のすべてのエントリを返す * 以外のパターンで呼ばれることはそう多くはないのではないだろうか。
結果としてUNIX系のOSよりもファイルシステムドライバに実装しなくてはいけないコードを増やしているように思える。

tags

  • windows
  • 「メタキャラクタの展開は誰の仕事か」のはてなブックマーク数
  • 「メタキャラクタの展開は誰の仕事か」deliciousブックマーク数
  • 「メタキャラクタの展開は誰の仕事か」をはてなブックマークに追加
  • save "メタキャラクタの展開は誰の仕事か" to del.icio.us
  • 「メタキャラクタの展開は誰の仕事か」をリアルタイムブログ検索
  • permalink
  • rootkitとWindowsの Installable FileSystem (IFS)
  • スクレイピングはもっと簡単にならなければいけない

comments

TypeKey Enabled
スタイル用のHTMLタグが使えます。
*required

trackbacks

トラックバック元エントリにこのエントリへのリンクがない場合はトラックバックを受け付けません。

http://labs.gmo.jp/mt/mt-tb.cgi/98
©2010 Kentaro Kumagai, GMO Internet Labs., GMO Internet, inc.
bits and bytes
2007 .02. 13 23:49

tagcloud

  • API1
  • C/C++2
  • E4X1
  • FUSE2
  • Firefox18
  • HTML4
  • IE1
  • MySQL1
  • OSX4
  • Opera2
  • PHP4
  • XML1
  • XPCOM4
  • XPath3
  • apache2
  • binary2
  • book1
  • data11
  • debug4
  • design1
  • experiments3
  • extension10
  • google gears1
  • google maps API1
  • greasemonkey3
  • httpd5
  • javascript17
  • linux1
  • logging2
  • mobile3
  • perl4
  • tips4
  • tool11
  • vim2
  • visualization2
  • widget1
  • wii1
  • windows7
  • サービス6
  • 和訳1

Archives

  • 2008.02 (6)
  • 2008.01 (3)
  • 2007.12 (4)
  • 2007.11 (5)
  • 2007.10 (4)
  • 2007.09 (4)
  • 2007.08 (4)
  • 2007.07 (8)
  • 2007.06 (7)
  • 2007.05 (4)
  • 2007.04 (5)
  • 2007.03 (6)
  • 2007.02 (4)
  • 2007.01 (6)

about

  • bits and bytesのXML
  • 「bits and bytes」のCreative Commons
  • Powered by Movable Type
  • イベントと地図 - モグ
  • Use ecto to blog!
  • bits and bytesのはてなブックマーク数
  • bits and bytesをMy Yahoo!に追加
  • Subscribe with Bloglines