/dev ファイルシステムと /proc ファイルシステム
Cygwin の /dev 以下には様々なデバイスファイルが格納されていますが、「どのようなデバイスファイルが存在するのか」「それぞれどのようにして利用するのか」という情報については、あまり知られていないようなので記述しました。
Cygwinには「ls」で見えないディレクトリが 3 つ存在します。一つは /cygdrive であり、後の2つは /dev と /proc です。ここでは、/dev と /proc について説明しましょう。
/dev ファイルシステム
UNIX 系 OS の特徴の一つとして「各種のデバイスをファイルとして表現している」という点が挙げられます。Cygwin は UNIX 系 OS との互換性を提供するため、/dev ディレクトリと、その中に含まれる各種のデバイスファイルを用意しています
なお、Cygwinでは「ls /dev」を実行しても、/dev の内容は表示されません。/dev 以下に格納されているファイルは Cygwin が仮想的に実現していますので、ファイルとしての実体が存在しないからです。デバイスファイルの存在を確認するためには、
$ ls -l /dev/null crw-rw-rw- 1 0 19, 0 Apr 5 23:30 /dev/null
のように、フルパスで指定して ls を実行する必要があります。
| 名称 | メジャー番号 / マイナー番号 | 説明 |
|---|---|---|
| 端末 | ||
| /dev/tty | 1/0 | 制御端末 |
| /dev/conin | 1/0 | コンソール(入力)及び制御端末(*1) |
| /dev/conout | 1/0 | コンソール(出力)(*2) |
| /dev/ttyX | 5/X | コンソール(*3) |
| /dev/ptmx(/dev/ttym) | 255/255 | 仮想端末マスタ |
| /dev/ttysX | 7/0 | 仮想端末(スレーブ)(*4) |
| シリアルポート / 外部記憶装置(*5) | ||
| /dev/ttySX(/dev/comX) | 7/0 | シリアルポート(*6) |
| /dev/fd0 | 17/0 | フロッピーディスクドライブ |
| /dev/scd0 | 17/16 | CD-ROM ドライブ |
| /dev/sda | 17/32 | ハードディスク |
| /dev/sda1 | 17/32 | ハードディスクの第一パーティション |
| /dev/st0 | 18/0 | テープドライブ(巻き戻しあり) |
| /dev/nst0 | 18/128 | テープドライブ(巻き戻しなし) |
| パイプ(*7) | ||
| /dev/pipe | -/0 | パイプ |
| /dev/piper | -/0 | パイプの読み込み終端 |
| /dev/pipew | -/0 | パイプの書き込み終端 |
| ソケット(*8) | ||
| /dev/tcp | -/0 | TCP ソケット |
| /dev/udp | -/0 | UDP ソケット |
| /dev/streamsocket | -/0 | UNIX ドメインソケット(ストリーム型) |
| /dev/dgsocket | -/0 | UNIX ドメイン(データグラム型) |
| その他 | ||
| /dev/windows | 12/0 | Windows メッセージキュー |
| /dev/null | 19/0 | NULL デバイス |
| /dev/zero | 20/0 | Zero デバイス |
| /dev/random | 21/8 | 乱数発生器 |
| /dev/urandom | 21/9 | 乱数発生器 |
| /dev/mem | 22/0 | 全物理メモリへのアクセス(*9) |
| /dev/port | 22/0 | 物理メモリの最初の 64KB へのアクセス(*10) |
| /dev/clipboard | 23/0 | クリップボード |
| /dev/dsp | 24/0 | サウンド入出力 |
*1: コマンドプロンプト利用時。
*2: コマンドプロンプト利用時。
*3: 「X」には0から始まる一意な番号が付与されます(例: tty0、tty1…)。
*4: 「X」には0から始まる一意な番号が付与されます(例: ttys0、ttys1…)。
*5: 外部記憶装置は、ディスク番号やパーティション番号単位で異なるデバイス名が与えられます。
*6:
「X」には0から始まる一意な番号が付与されます。「ttySX」と「comX」は同じシリアルポートを指しており、「ttyS0」と「com0」は、それぞれ Windows のシリアルポート「COM1」を指すデバイスとなっています。
*7: パイプの作成時に内部的に利用されるデバイス。
*8: ソケットの作成時に内部的に利用されるデバイス。
*9: NT 系 Windows でのみ利用可能であり、アクセスには Administrator 権限が必要です。
*10: NT 系 Windows でのみ利用可能であり、アクセスには Administrator 権限が必要です。
コンソール及び端末デバイス
コンソール及び端末の扱われ方は、利用しているコンソールがコマンドプロンプトかそれ以外(rxvt や X 上の xterm / kterm など)か、また、環境変数 CYGWIN に tty を設定しているか否かによって変わります。
コマンドプロンプト以外の端末(rxvt、kterm など)を利用している場合の動作は、UNIX 系 OS とほぼ同様です。制御端末は「/dev/tty」であり、各コンソールにはそれぞれ固有のデバイス名が割り当てられます(/dev/tty0 から順番に、tty1、tty2…となります)。この場合、/dev/conin 及び /dev/conout を利用することは出来ません。
一方、コンソールとしてコマンドプロンプトを利用している場合、現在のコマンドプロンプトの入力及び制御端末は常に /dev/conin 、出力は常に /dev/conout が利用されます(この場合でも、/dev/tty は制御端末として利用出来ます)。環境変数 CYGWIN に tty を設定している場合、各コンソールには「/dev/tty0」のようなデバイス名も割り当てられますが、その場合でも /dev/conin 及び /dev/conout は有効となっています。
Cygwin ではユーザが異なってもコンソールは保護されません。ユーザ A がコンソール tty0 を、ユーザ B がコンソール tty1 を利用しているとしましょう。このときユーザ A は「echo hoge > /dev/tty1」などを実行して、ユーザ B の利用しているコンソールに文字を書き出すことが出来てしまいます。
制御端末 / 仮想端末とは
「制御端末」や「仮想端末」という概念は一般的にはあまり馴染みがない存在だと思いますので、簡単に説明しましょう。
ある種のプログラムでは、現在利用中のコンソールを表現するデバイスファイルへとアクセスしなければならないことがあります。UNIX 系 OS では、システムに備わっているコンソールには tty0 や tty1 のように、番号で識別されるデバイスファイル名がそれぞれ付与されています。しかし、利用するコンソールごとにコンソールのデバイスファイル名が異なるのでは、「まず現在利用中のコンソールの番号を調べ、それからコンソールにアクセスする」という手順を踏まなければなりません。これでは不便なので、現在利用中のコンソールに対して、必ずアクセス出来ることが保証されるデバイスファイルが準備されています。これを「制御端末」と言い、一般的な UNIX では「/dev/tty」が制御端末となっています。
「仮想端末(擬似端末)」とは、プログラムの制御下でシリアル端末の振る舞いをエミュレートするために、ソフトウェア的に作成される仮想的な端末です。仮想端末は「マスタ」と「スレーブ」の二つのデバイスから構成され、xterm のような端末エミュレータや、telnet などのリモートログインの受け付けなどに利用されます。例えば telnet の場合、telnet クライアントが読み書きするのはマスタデバイスであり、telnet デーモンから起動されたシェルが読み書きするのはスレーブデバイスです。
Cygwin は UNIX 98 で導入された「仮想端末マスタ(pty master)」をサポートしており、「/dev/ptmx」が仮想端末マスタとして利用されています。
外部記憶装置
UNIX 系 OS と同様、Cygwin にも外部記憶装置を表現するデバイスファイル(raw デバイスファイル)が準備されています。しかし、現在の Cygwin には外部記憶装置へと直接アクセス可能なプログラムがほとんどありませんので、利用する意味は薄いかもしれません。
Cygwin の raw デバイスファイルは、NT 系 Windows の「内部デバイス」を利用して実現されています。NT の内部では、各デバイスは「\device\cdrom0」のような形式で表現されていますが、これを UNIX 風の名称にマッピングしたものだと考えればよいでしょう。結果として、raw デバイスファイルは NT 系でしか利用出来ませんし、デバイスの数は内部デバイスの制限に依存します。
- フロッピーディスクドライブ
- フロッピーディスクドライブは、一番目のドライブが「
fd0」、二番目が「fd1」として、「fd15」までが利用可能です。マイナー番号も同様に 0 から 15 の範囲を取ります。 - CD-ROM ドライブ
- CD-ROM ドライブは、一番目のドライブが「
scd0」、二番目が「scd1」として、「scd15」までが利用可能です。マイナー番号は 16 から 31 の範囲を取ります。 - ハードディスク
- ハードディスクは一番目のディスク全体を示すのが「
sda」、一番目のハードディスクの一番目のパーティションが「sda0」、二番目のパーティションが「sda1」のようになります。パーティション、ディスクともに 15 までが利用出来るので、最大のデバイス名は「sdl15」となります。マイナー番号の計算式は「16 + (ディスク番号 × 16) + パーティション番号」となっています。 - テープドライブ
- テープドライブは、巻き戻しを行うデバイスが「
stX」、巻き戻しを行わないデバイスが「nstX」となります。ドライブの番号は 0 から 15 までが利用出来ます。マイナー番号は 128 から 144(128 + ドライブの番号)の範囲を取ります。
その他のデバイス
Cygwin では UNIX 系 OS にも存在するものから、Cygwin にしか存在しないものまで、上記以外にも様々なデバイスが利用出来ます。UNIX 系 OS に存在するデバイスは UNIX 系 OS 上とほぼ同様の動作をしますので、ここでは Cygwin 特有のデバイスについて説明しましょう。
/dev/windows − Windowsメッセージキュー
Windows という OS の基盤を支えているのは「メッセージによるコミュニケーション」です。Windows の各アプリケーションは、受信したメッセージを適切に処理することによって動作します。例えば、キーボードから文字が入力されるとメッセージ「WM_CHAR」がアプリケーションに通知されますし、ユーザがタイトルバーの「?」を押してヘルプメッセージを得ようとしたときは、「WM_HELP」メッセージが通知されます。また、メッセージはユーザのアクションだけでなく、他のアプリケーションが別のアプリケーションへと送信することも出来ます。
/dev/windows は、Cygwin アプリケーションが他のアプリケーションへメッセージを送信したり、他のアプリケーションからのメッセージを受け取るためのインタフェースを提供するデバイスです。このデバイスを利用するにはプログラミングの知識が必要ですが、Cygwin DLL のソースコード中の fhandler_windows.cc に利用方法が記されていますので、興味のある方は参照して下さい。
/dev/clipboard − クリップボード
/dev/clipboard は、Windows のクリップボードを操作するためのデバイスです。/dev/clipboard 経由でやり取りが可能なデータ形式はテキスト形式に限定されています。
$ echo 'Cygwin' > /dev/clipboard
を実行し、それから適当な Windows アプリケーションでペーストを実行すると、「Cygwin」という文字列がペーストされるはずです。
/dev/dsp − サウンド入出力
このデバイスは Cygwin 特有というわけではありませんが、簡単に説明しましょう。/dev/dsp はサウンド入出力用のデバイスであり、その動作は Linux の OSS サウンドモデルをエミュレートしたものとなっています。
/dev/dsp にデータを流し込むと、その結果はサウンドとして再生されます。例えば、
$ cat /cygdrive/c/WINNT/Media/ding.wav > /dev/dsp
を実行すれば、Windows のサウンドファイルが再生出来ることが分かるでしょう。サウンドファイル以外のデータを流し込んだ場合でも、流し込まれたデータはサウンドデータであると解釈され、何らかのサウンドが再生されます。但しこれは「データ用 CD-ROM を CD プレイヤーで再生する」ような乱暴な行為ですので、十分に注意して下さい。
/proc ファイルシステム
幾つかの UNIX 系 OS は、「/proc ファイルシステム」というものを備えています。このファイルシステム中には、カーネルや実行中のプロセスに関する様々な情報がテキスト形式で格納されています。
/proc ファイルシステムが出来るまで、このような情報を取得するためのアプリケーションを作成するには、様々な手法を駆使してカーネルやプロセスの情報を取得しなければなりませんでした。しかし /proc ファイルシステムが出来たことにより、単純にテキストファイルの読み書きだけでこのような情報にアクセス出来るようになりました。もちろん、cat や more などのコマンドを利用すれば、シェルからでもこれらの情報を参照することが出来ます。
Cygwin にも、互換性の観点から /proc ファイルシステムが準備されており、Linux に似た感覚で利用出来ます。しかし、現時点で /proc ファイルシステムから取得出来る情報はあまり多くありません。
以下に、Cygwin の /proc から取得出来る情報の一覧を挙げておきます。これらの情報は各種の Win32 API や NT のネイティブコールなどを駆使して取得していますが、中にはレジストリ内の情報を流用したり、アセンブリ言語で CPU を直接叩いて取得しているようなものもあります。
| 名称 | 説明 |
|---|---|
| cpuinfo | CPUについての情報 |
| loadavg | 平均負荷(現在未実装)(*11) |
| meminfo | メモリ情報(総メモリ量、使用メモリ量、空きメモリ量、スワップ総量、スワップ使用量など) |
| partitions | パーティション情報(*12) |
| registry | Windows レジストリを階層的に表現 |
| stat | システム統計情報(CPU 消費時間、スワップ、割り込み、起動経過秒数など) |
| uptime | システム起動時以降に経過した秒数 |
| version | Windows 及び Cygwin のバージョン |
| (数値) | 当該数値で示されるプロセス ID を持つプロセスの情報(実行時のコマンドラインやファイル名、プロセスの状態など) |