ファイル記述子(ファイルきじゅつし、、FD)とは、Unix系オペレーティングシステムにおいて、プロセスがファイル、端末、パイプ、ソケットなどの入出力対象を参照するために割り当てられる番号である。
プロセスはこの番号を通じて入出力資源を統一的に扱うことができ、Unix の「すべてをファイルとして扱う」設計思想の基盤となっている。Microsoft Windows などのファイルハンドルは概念的に類似するが、実装方式は異なる。
概要 POSIXでは、ファイル記述子は整数型の値であり、詳述すればC言語のint型である。POSIXでは、全てのプロセスが持つべき3つのファイル記述子を定義している(デーモンなどはその限りではない)。
整数値名前0標準入力 (stdin)1標準出力 (stdout)2標準エラー出力 (stderr)
一般にファイル記述子は、オープン中のファイルの詳細を記録するカーネル内データ構造(配列)へのインデックスである。POSIXでは、これをファイル記述子テーブルと呼び、各プロセスが自身のファイル記述子テーブルを持つ。ユーザーアプリケーションは抽象キー(=ファイル記述子)をシステムコール経由でカーネルに渡し、カーネルはそのキーに対応するファイルにアクセスする。アプリケーション自身はファイル記述子テーブルを直接読み書きできない。
Unix系システムでは、ファイル記述子がファイルだけでなく、ディレクトリ、ブロックデバイスやキャラクターデバイス(スペシャルファイルとも呼ぶ)、ソケット、FIFO(名前付きパイプ)、名前なしパイプなどのカーネルオブジェクトを汎用的に参照するのに使われる。
標準Cライブラリの、FILE型(ライブラリが管理するデータ構造)へのポインタ(FILE *)があらわすものをストリームと言い、POSIXではファイル記述子とストリームを包括する用語として「ハンドル」を使っている(参考: "Interaction of File Descriptors and Standard I/O Streams")。『プログラミング言語C』第2版ではFILE *を「ファイル・ポインタ」と呼んでいる。原著『The C Programming Language』では「file pointer」と呼んでいる。FILE型の実装は規格で規定されておらず、オブジェクト型(object type)であることのみが規定されているが、通例構造体であり、Unix系システムでは一般に低レベルのファイル記述子を含んでいる。これらはプラットフォームではなくプログラミング言語によって標準化された上位層のコンセプトであるため、ファイル記述子と同一視はできない。
Javaの標準クラスライブラリには、ファイル記述子を表現するハンドルとしてがあり、主にまたはを作成するために使用される。
DOS・Microsoft Windows Microsoft Windowsカーネルでは、ファイル記述子と同様であるが、より汎用的な機構によりファイルオブジェクトを含むさまざまなカーネルオブジェクトを「ハンドル」という抽象的な識別子に関連づける枠組みが採用されている。特にファイルを表すカーネルオブジェクトに関連づけられたハンドルを「ファイルハンドル」と呼ぶが、これはPOSIXにおけるファイル記述子とほぼ同等の役割を担うものと解釈することができる。このファイルハンドルは、前述の(ファイル)ハンドルとは異なるものを指すが、同一の語のため、混乱を生じることがある。DOSではファイル記述子ほぼそのものを指して「ファイルハンドル」と呼んでいた。
マイクロソフトのCランタイムライブラリ (CRT) は、C標準I/Oライブラリとは別に、POSIX互換関数群として、オペレーティングシステムにおけるネイティブのファイルハンドルとPOSIX的な整数のファイル記述子を相互変換して扱える機能を持っている_get_osfhandle | Microsoft Docs_open_osfhandle | Microsoft Docs。
ファイル記述子に関する操作 のUnix系システムが提供するファイル記述子関連の操作(システムコールとライブラリ関数)は以下の通りである。
ファイル記述子の生成
open(), open64(), creat(), creat64() socket() socketpair() pipe()
ひとつのファイル記述子に関する操作
read(), write() recv(), send() recvmsg(), sendmsg() sendfile() lseek(), lseek64() fstat(), fstat64() ftruncate() fchmod() fchown()
複数のファイル記述子に関する操作
select(), pselect() poll()
ファイル記述子テーブル上の操作
close() dup() dup2() fcntl (F_DUPFD) fcntl (F_GETFD and F_SETFD)
プロセス状態を変更する操作
fchdir(): プロセスのカレントディレクトリを指定されたファイル記述子の示すディレクトリに変更する。 mmap(): ファイルの指定された範囲をプロセスのアドレス空間にマップする。
ファイルロック
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)」の実例と見ることもできる。
脚注
注釈
出典
関連項目 ファイル (コンピュータ)
de:Handle#Datei-Handle