ファイル記述子(ファイルきじゅつし、英語: file descriptor)とは、コンピュータプログラミングにおいてファイルへの参照を抽象化したキーである。ファイルディスクリプタあるいはFDとも呼ばれる。UNIX系システムでテキストターミナルを含むファイルストリームを参照する際に用いられる。

標準入力 (stdin)、標準出力 (stdout)、標準エラー出力 (stderr) のファイル記述子の概念図

MS-DOS[1]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"[要文献特定詳細情報])。『プログラミング言語C』第2版ではFILE *を「ファイル・ポインタ」と呼んでいる。原著『The C Programming Language』では「file pointer」と呼んでいる。FILE型の実装は規格で規定されていないが、通例構造体であり、UNIX系システムでは一般に低レベルのファイル記述子を含んでいる。これらはプラットフォームではなくプログラミング言語によって標準化された上位層のコンセプトであるため、ファイル記述子と同一視はできない。[注釈 2]

MS-DOS・Microsoft Windows  編集

Microsoft Windowsカーネルでは、ファイル記述子と同様であるが、より汎用的な機構によりファイルオブジェクトを含むさまざまなカーネルオブジェクトを「ハンドル」という抽象的な識別子に関連づける枠組が採用されている。特にファイルを表すカーネルオブジェクトに関連づけられたハンドルを「ファイルハンドル」と呼ぶが、これはPOSIXにおけるファイル記述子とほぼ同等の役割を担うものと解釈することができる。このファイルハンドルは、前述の(ファイル)ハンドル[どれ?]とは異なるものを指すが、同一の語のため、混乱を生じることがある。(MS-DOSではファイル記述子ほぼそのものを指して「ファイルハンドル」と呼んでいた)

マイクロソフトのCランタイムライブラリ (CRT) は、C標準I/Oライブラリとは別に、POSIX互換関数群として、オペレーティングシステムにおけるネイティブのファイルハンドルとPOSIX的な整数のファイル記述子を相互変換して扱える機能を持っている[2][3]

ファイル記述子に関する操作 編集

最近[いつ?]の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)

プロセス状態を変更する操作 編集

  • 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)」の実例と見ることもできる。

脚注 編集

注釈 編集

  1. ^ JIS X 3010-1993 §7.9の中に「ハンドル」という語はない。
  2. ^ 他のUNIX系仕様で、NFSなどにファイルハンドルの語が見られる。

出典 編集

  1. ^ MS-DOS温故知新 ~ソースコード公開を期にパソコン大衆化の原点を振り返る~:MS-DOS歴史的遺産化記念企画 - @IT
  2. ^ _get_osfhandle | Microsoft Docs
  3. ^ _open_osfhandle | Microsoft Docs

関連項目 編集