ファイル記述子
ファイル記述子(ファイルきじゅつし、File Descriptor)とは、プログラミングにおいてファイルへの参照を抽象化したキーである。ファイルディスクリプタあるいはFDとも呼ばれる。Microsoft Windowsでは、「ファイルハンドル」がほぼ相当するが、技術的には異なるオブジェクトである。
概要
POSIXでは、ファイル記述子は整数であり、詳述すれはC言語の int型である。POSIXでは、全てのプロセスが持つべき3つのファイル記述子を定義している(デーモンなどはその限りではない)。
整数値 | 名前 |
---|---|
0 | 標準入力 (stdin) |
1 | 標準出力 (stdout) |
2 | 標準エラー出力 (stderr) |
一般にファイル記述子は、オープン中ファイルの詳細を記録しているカーネル内データ構造(配列)へのインデックスである。POSIXでは、これをファイル記述子テーブルと呼び、各プロセスが自身のファイル記述子テーブルを持つ。ユーザーアプリケーションは抽象キーをシステムコール経由でカーネルに渡し、カーネルはそのキーに対応するファイルにアクセスする。アプリケーション自身はファイル記述子テーブルを直接読み書きできない。
UNIX系システムでは、ファイル記述子がファイルだけでなく、ディレクトリ、ブロックデバイスやキャラクターデバイス(スペシャルファイルとも呼ぶ)、ソケット、FIFO(名前付きパイプ)、名前なしパイプなどのカーネルオブジェクトを汎用的に参照するのに使われる。
標準Cのライブラリの、FILE型(ライブラリが管理するデータ構造)へのポインタ(FILE *)があらわすものをストリームと言い[1]、POSIXではファイル記述子とストリームをひっくるめた用語として「ハンドル」を使っている(参: "Interaction of File Descriptors and Standard I/O Streams")。また、FILE *を「ファイルハンドル」と呼ぶ者がいる(K&R2版訳本改訂版では「ファイル・ポインタ」)。FILE型(ふつう構造体)は、UNIX系システムでは一般に低レベルのファイル記述子を含んでいる。これらは上位層のコンセプトであるため、ファイル記述子と同一視はできない。[2]
Microsoft Windowsカーネルでは、ファイル記述子と同様であるが、より汎用的な機構によりファイルオブジェクトを含むさまざまなカーネルオブジェクトをハンドルというものに関連づける枠組が採用されている。特にファイルを表すカーネルオブジェクトに関連づけられたハンドルを「ファイルハンドル」と呼ぶが、これはPOSIXにおけるファイル記述子とほぼ同等の役割を担うものと解釈することができる。このファイルハンドルは、前述の(ファイル)ハンドルとは異なるものを指すが、同一の語のため、混乱を生じることがある。(MS-DOSではファイル記述子ほぼそのものを指して「ファイルハンドル」と呼んでいた)
マイクロソフトのCランタイムライブラリ (CRT)は、C標準I/Oライブラリとは別に、UNIX互換関数群として、ネイティブのファイルハンドルをPOSIX的な整数のファイル記述子に変換して扱う機能を持っている。
ファイル記述子に関する操作
最近のUNIX系システムが提供するファイル記述子関連の操作(システムコールとライブラリ関数)は以下の通りである。
ファイル記述子の生成
- open(), open64(), creat(), creat64()
- socket()
- socketpair()
- pipe()
ひとつのファイル記述子に関する操作
- read(), write()
- recv(), send()
- recvmsg(), sendmsg()
- sendfile()
- lseek(), lseek64()
- fstat(), fstat64()
- fchmod()
- fchown()
複数のファイル記述子に関する操作
- select(), pselect()
- poll()
ファイル記述子テーブル上の操作
- close()
- dup()
- dup2()
- fcntl (F_DUPFD)
- fcntl (F_GETFD and F_SETFD)
プロセス状態を変更する操作
ファイルロック
- flock()
- fcntl (F_GETLK, F_SETLK and F_SETLKW)
- lockf()
ソケット
- connect()
- bind()
- listen()
- accept(): 接続要求から新たなソケットファイル記述子を生成する。
- getsockname()
- getpeername()
- getsockopt(), setsockopt()
- shutdown(): 全二重接続の一方または両方を切断する。
その他
- ioctl(): 一般にデバイスに対応するファイル記述子に関する様々な操作をする。
ケイパビリティとしてのファイル記述子
UNIXのファイル記述子は、一種のケイパビリティである。sendmsg() システムコールを使うとプロセス間でファイル記述子をやり取りすることができる。つまり、UNIXのプロセスが持つファイル記述子テーブルは「ケイパビリティリスト(C-list)」の実例と見ることもできる。