ファイル記述子

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

UnixおよびUnixライクなコンピュータオペレーティングシステムでは、ファイル記述子FD、頻度は低いがfildes )は、ファイルまたはパイプネットワークソケットなどの他の入出力リソースの一意の識別子(ハンドル)です

ファイル記述子は通常、負ではない整数値を持ち、負の値は「値なし」またはエラー状態を示すために予約されています。

ファイル記述子POSIXAPI の一部です。各Unixプロセス(おそらくデーモンを除く)には、3つの標準ストリームに対応する3つの標準POSIXファイル記述子が必要です

整数値 名前 < unistd.h >シンボリック定数[1] < stdio.h >ファイルストリーム[2]
0 標準入力 STDIN_FILENO stdin
1 標準出力 STDOUT_FILENO stdout
2 標準エラー STDERR_FILENO stderr

概要

単一のプロセス、ファイルテーブル、およびiノードテーブルのファイル記述子。複数のファイル記述子が同じファイルテーブルエントリを参照できることに注意してください(たとえば、dupシステムコール[3] :104 の結果として)。また、複数のファイルテーブルエントリが同じiノードを参照できることに注意してください(開いている場合)。複数回;iノードが複数の名前を持つことができる場合でも、ファイル名でiノードを表すため、テーブルは引き続き簡略化されます)。ファイル記述子3は、ファイルテーブル内の何も参照せず、閉じられたことを示します。

Unixの従来の実装では、ファイル記述子はプロセスごとにインデックスを付けますカーネルによって維持されるファイル記述子テーブル。これは、すべてのプロセスによって開かれるファイルのシステム全体のテーブルにインデックスを付けます。ファイルテーブルこのテーブル、ファイル(または他のリソース)が開かれたモード(読み取り、書き込み、追加、および場合によっては他のモード)が記録また、実際の基になるファイルを記述するiノードテーブル[3]入力または出力を実行するために、プロセスはシステムコール を介してファイル記述子をカーネルに渡し、カーネルはプロセスに代わってファイルにアクセスします。プロセスは、ファイルまたはiノードテーブルに直接アクセスできません。

Linuxでは、プロセスで開いているファイル記述子のセットにパス/proc/PID/fd/でアクセスできます。ここで、PIDはプロセス識別子です。ファイル記述子/proc/PID/fd/0stdin、、、、および/proc/PID/fd/1ですこれらへのショートカットとして、実行中のプロセスは、フォルダーとを介して独自のファイル記述子にアクセスすることもできます。[4]stdout/proc/PID/fd/2stderr/proc/self/fd/dev/fd

Unixライクなシステムでは、ファイル記述子はファイルシステムで指定された任意のUnixファイルタイプを参照できます。通常のファイルだけでなく、これには、ディレクトリブロックおよび文字デバイス(「特殊ファイル」とも呼ばれます)、Unixドメインソケット、および名前付きパイプが含まれます。ファイル記述子は、無名パイプネットワークソケットなど、通常はファイルシステムに存在しない他のオブジェクトを参照することもできます

C標準I/OライブラリのFILEデータ構造には、通常、Unixライクなシステムで問題のオブジェクトの低レベルのファイル記述子が含まれています。全体的なデータ構造は追加の抽象化を提供し、代わりにファイルハンドルとして知られています。

ファイル記述子の操作

以下に、最新のUnixライクなシステムでのファイル記述子の一般的な操作を示します。これらの関数のほとんどは<unistd.h>ヘッダーで宣言されていますが、<fcntl.h>代わりにヘッダーにあるものもあります。

ファイル記述子の作成

  • 開く()
  • creat()[5]
  • ソケット()
  • 受け入れる()
  • socketpair()
  • パイプ()
  • epoll_create()(Linux)
  • signalfd()(Linux)
  • eventfd()(Linux)
  • timerfd_create()(Linux)
  • memfd_create()(Linux)
  • userfaultfd()(Linux)
  • fanotify_init()(Linux)
  • inotify_init()(Linux)
  • clone()(フラグCLONE_PIDFD、Linux付き)
  • pidfd_open()(Linux)
  • open_by_handle_at()(Linux)

ファイル記述子の導出

  • dirfd()
  • fileno()

単一のファイル記述子に対する操作

  • 読み取り()、書き込み()
  • readv()writev()
  • pread()pwrite()
  • recv()send()
  • recvfrom()sendto()
  • recvmsg()sendmsg()(Unixドメインソケットを介して他のプロセスにFDを送信するためにも使用されます)
  • recvmmsg()sendmmsg()
  • lseek()llseek()
  • fstat()
  • fstatvfs()
  • fchmod()
  • fchown()
  • ftruncate()
  • fsync()
  • fdatasync()
  • fdopendir()
  • fgetxattr()fsetxattr()(Linux)
  • flistxattr()fremovexattr()(Linux)
  • statx(Linux)
  • setns(Linux)
  • vmsplice()(Linux)
  • pidfd_send_signal()(Linux)
  • waitid()(P_PIDFD IDタイプ、Linux)
  • fdopen()(stdio関数:ファイル記述子をFILE *に変換します)
  • dprintf()(stdio関数:ファイル記述子に出力)

複数のファイル記述子の操作

  • select() pselect()
  • poll() ppoll()
  • epoll_wait()epoll_pwait()epoll_pwait2()(Linux、単一のepollファイル記述子を使用して他の多くのファイル記述子を待機します)
  • epoll_ctl()(Linuxの場合)
  • kqueue()(BSDベースのシステムの場合)。
  • ファイルを送信()
  • splice() tee()(Linuxの場合)
  • copy_file_range()(Linuxの場合)
  • close_range()(Linuxの場合)[6]

ファイル記述子テーブルの操作

fcntl()関数は、渡されたコマンド引数に応じて、ファイル記述子に対してさまざまな操作を実行するために使用されます。F_GETFD、F_SETFD、F_GETFL、F_SETFLなどファイル記述子に関連付けられた属性を取得および設定するコマンドがあります

  • 選ぶ()
  • closefrom()(BSDおよびSolarisのみ。指定された数以上のすべてのファイル記述子を削除します)
  • dup()(既存のファイル記述子を複製して、使用可能なファイル記述子の最小数になることを保証します)
  • dup2() dup3()(必要に応じてfd1を閉じ、ファイル記述子fd1がfd2の開いているファイルを指すようにします)
  • fcntl(F_DUPFD)

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

  • fchdir()(ディレクトリファイル記述子に基づいてプロセスの現在の作業ディレクトリを設定します)
  • mmap()(ファイルの範囲をプロセスのアドレス空間にマップします)

ファイルロック

  • 群れ()
  • fcntl()(F_GETLK、F_SETLKおよびF_SETLKW)
  • lockf()

ソケット

  • 接続()
  • 練る()
  • 聞く()
  • accept()(着信接続用の新しいファイル記述子を作成します)
  • getockname()
  • getpeername()
  • getockopt()
  • setsockopt()
  • shutdown()(全二重接続の一方または両方の半分をシャットダウンします)

その他

  • ioctl()(多くの場合、デバイスに関連付けられている、単一のファイル記述子に対するその他の操作の大規模なコレクション)

今後の操作

ファイル記述子に対する一連の新しい操作が、多くの最新のUnixライクなシステム、および多数のCライブラリに追加され、POSIXの将来のバージョンで標準化される予定です。[7]接尾辞は、関数が相対パスを解決atするファイル記述子を提供する追加の最初の引数を取ることを意味します。したがって、接尾辞がない形式は、現在の作業ディレクトリに対応するファイル記述子を渡すことと同等になりますこれらの新しい操作の目的は、特定のクラスのTOCTOU攻撃 から防御することです。at

  • openat()
  • faccessat()
  • fchmodat()
  • fchownat()
  • fstatat()
  • futimesat()
  • linkat()
  • mkdirat()
  • mknodat()
  • readlinkat()
  • renameat()
  • symlinkat()
  • unlinkat()
  • mkfifoat()
  • fdopendir()

機能としてのファイル記述子

Unixファイル記述子は、機能としてさまざまな方法で動作します。これらは、システムコールを使用してUnixドメインソケット間でプロセス間で受け渡すことができます。sendmsg()ただし、実際に渡されるのは、可変状態(ファイルオフセット、ファイルステータスおよびアクセスフラグ)を持つ「開いているファイルの説明」への参照であることに注意してください。これにより、ファイル記述子を機能として安全に使用することが複雑になります。プログラムが同じ開いているファイル記述へのアクセスを共有する場合、オフセットを変更したり、ブロックまたは非ブロックであるかなどによって、プログラムが相互に干渉する可能性があるためです。[8] [9]機能システムとして特別に設計されたオペレーティングシステムでは、機能自体に関連付けられた変更可能な状態がほとんどありません。

Unixプロセスのファイル記述子テーブルは、Cリストの例です。

も参照してください

参照

  1. ^ オープングループ「TheOpenGroupBase Specification Issue 7、IEEE Std 1003.1-2008、2016Edition」2017年9月21日取得
  2. ^ オープングループ。「TheOpenGroupBase Specification Issue 7、IEEE Std 1003.1-2008、2016Edition」<stdio.h> 2017年9月21日取得
  3. ^ a b バッハ、モーリスJ.(1986)。UNIXオペレーティングシステムの設計(8版)。Prentice-Hallpp。92–96。  _ ISBN 9780132017992
  4. ^ 「デバイス-'ll/ Proc / Self / Fd /'('ll / Dev / Fd'から)の出力はどういう意味ですか?」
  5. ^ オープングループ「TheOpenGroupBase Specification Issue 7、IEEE Std 1003.1-2008、2018 Edition –creat」2019年4月11日取得
  6. ^ スティーブン・キット、マイケル・ケリスク。"close_range(2)—Linuxのマニュアルページ" 2021-03-22を取得
  7. ^ 拡張APIセット、パート2オープングループ。2006年10月。ISBN 1931624674
  8. ^ ブリンクマン、マーカス(2009-02-04)。「ブリッジの構築:ライブラリAPIとファイル記述子?」キャップトーク2012年7月30日にオリジナルからアーカイブされました2017年9月21日取得
  9. ^ de Boyne Pollard、ジョナサン(2007)。「共有ファイル記述子を非ブロッキングI/Oモードに設定しないでください」2017年9月21日取得