概要
単一プロセスのファイルディスクリプタ、ファイルテーブル、およびinodeテーブル。複数のファイルディスクリプタが同じファイルテーブルエントリを参照する可能性があること(たとえば、dupシステムコール[ 4 ] : 104の結果など)、および複数のファイルテーブルエントリが同じinodeを参照する可能性があること(複数回開かれた場合。inodeは複数の名前を持つことができるにもかかわらず、テーブルはファイル名でinodeを表すため、簡略化されています)に注意してください。ファイルディスクリプタ3はファイルテーブル内の何も参照していないため、閉じられていることを示しています。Unixの従来の実装では、ファイルディスクリプタはプロセスごとにインデックス付けされます。カーネルによって管理されるファイル記述子テーブルは、すべてのプロセスによって開かれたファイルのシステム全体のテーブルにインデックス付けされ、ファイル テーブル。このテーブルには、ファイル (またはその他のリソース) が開かれたモードinode テーブル。 [ 4 ]入力または出力を実行するために、プロセスはシステム コール を介してファイル ディスクリプタをカーネルに渡し、カーネルはプロセスに代わってファイルにアクセスします。プロセスはファイル テーブルまたは inode テーブルに直接アクセスすることはできません。
Linuxでは、プロセスで開いているファイルディスクリプタのセットは/proc/PID/fd/、パス の下からアクセスできます。ここで、PID はプロセス識別子です。ファイルディスクリプタ/proc/PID/fd/0はstdin、/proc/PID/fd/1はstdout、は、/proc/PID/fd/2ですstderr。これらへのショートカットとして、実行中のプロセスは、フォルダおよびを介して自身のファイルディスクリプタにアクセスすることもできます。[ 5 ]/proc/self/fd/dev/fd
Unix系システムでは、ファイルディスクリプタはファイルシステム内で指定されたあらゆるUnixファイルタイプを参照できます。通常のファイルに加え、ディレクトリ、ブロックデバイス、キャラクタデバイス(「特殊ファイル」とも呼ばれる)、Unixドメインソケット、名前付きパイプなども含まれます。また、ファイルディスクリプタは、匿名パイプやネットワークソケットなど、通常はファイルシステム内に存在しないオブジェクトも参照できます。
C言語の標準入出力ライブラリFILEにおけるデータ構造は、通常、Unix系システム上の対象オブジェクトに対応する低レベルのファイル記述子を含んでいます。このデータ構造全体は、さらに抽象化されており、ファイルハンドルと呼ばれています。
ファイルディスクリプタに対する操作
以下に、最新のUnix系システムにおけるファイルディスクリプタに対する一般的な操作を列挙します。これらの関数のほとんどは<unistd.h>ヘッダーファイルで宣言されていますが、一部は<fcntl.h>別のヘッダーファイルで宣言されています。
ファイルディスクリプタの作成
- 開ける()
- creat() [ 6 ]
- ソケット()
- 受け入れる()
- ソケットペア()
- パイプ()
- 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)
- kqueue() (BSD)
- pdfork() (kFreeBSD)
単一ファイルディスクリプタに対する操作
- read ()、write ()
- readv()、writev()
- pread()、pwrite()
- recv()、send()
- recvfrom()、sendto()
- recvmsg()、sendmsg()(Unixドメインソケットを介して他のプロセスにファイルディスクリプタを送信するためにも使用されます)
- 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)
- pdkill() (kFreeBSD)
- waitid()(P_PIDFD IDタイプ、Linux)
- fdopen()(標準入出力関数:ファイルディスクリプタをFILE*に変換します)
- dprintf()(標準入出力関数:ファイルディスクリプタに出力する)
複数のファイルディスクリプタに対する操作
- select()、 pselect()
- poll()、 ppoll()
- epoll_wait()、epoll_pwait()、epoll_pwait2()(Linuxでは、1つのepollファイルディスクリプタを受け取り、他の多くのファイルディスクリプタを待機します)
- epoll_ctl()(Linux用)
- kqueue()(BSDベースのシステム用)。
- sendfile()
- splice()、 tee()(Linux用)
- copy_file_range() (Linux用)
ファイルディスクリプタテーブルに対する操作
fcntl ()関数は、渡されたコマンド引数に応じて、ファイルディスクリプタに対してさまざまな操作を実行するために使用されます。ファイルディスクリプタに関連付けられた属性を取得および設定するためのコマンドには、F_GETFD、F_SETFD、F_GETFL、F_SETFLなどがあります。
- 近い()
- closefrom()(BSDおよびSolarisのみ。指定された数以上のすべてのファイルディスクリプタを削除します)
- close_range() (Linux用) [ 7 ]
- dup()(既存のファイルディスクリプタを複製し、利用可能なファイルディスクリプタの中で最小の番号であることを保証します)
- dup2 ()、 dup3()(必要に応じてfd1を閉じ、ファイルディスクリプタfd1が開いているファイルfd2を指すようにします)
- fcntl (F_DUPFD)
プロセス状態を変更する操作
- fchdir()(ディレクトリファイルディスクリプタに基づいてプロセスの現在の作業ディレクトリを設定します)
- mmap ()(ファイルの範囲をプロセスのアドレス空間にマッピングします)
ファイルロック
- 群れ()
- fcntl() (F_GETLK、F_SETLK、F_SETLKW)
- lockf()
ソケット
- 接続する()
- バインド()
- 聞く()
- accept()(着信接続用の新しいファイルディスクリプタを作成します)
- getsockname()
- getpeername()
- getsockopt()
- setsockopt()
- shutdown()(全二重接続の片側または両側をシャットダウンします)
その他
- ioctl()(単一のファイルディスクリプタに対する様々な操作の集合であり、多くの場合、デバイスに関連付けられている)
at接尾辞操作
一連の新しい操作が、多くの最新の Unix ライクなシステムや多数の C ライブラリに追加され、将来のPOSIXバージョンで標準化される予定です。[ 8 ]このat接尾辞は、関数がファイルディスクリプタを提供する追加の最初の引数を取ることを示し、そこから相対パスが解決されます。したがって、接尾辞のない形式は、at現在の作業ディレクトリに対応するファイルディスクリプタを渡すのと同等になります。これらの新しい操作の目的は、特定のクラスのTOCTOU攻撃から防御することです。
- openat()
- faccessat()
- fchmodat()
- fchownat()
- fstatat()
- futimesat()
- linkat()
- mkdirat()
- mknodat()
- readlinkat()
- renameat()
- symlinkat()
- unlinkat()
- mkfifoat()
- fdopendir()
ファイルディスクリプタを機能として利用する
Unix ファイルディスクリプタは、多くの点で機能として動作します。システムコールを使用して、Unix ドメインソケットsendmsg()を介してプロセス間で渡すことができます。ただし、実際に渡されるのは、可変状態 (ファイルオフセット、ファイルステータス、アクセスフラグ) を持つ「オープンファイル記述」への参照であることに注意してください。プログラムが同じオープンファイル記述へのアクセスを共有する場合、たとえばオフセットを変更したり、ブロッキングかノンブロッキングかを変更したりすることで、互いの使用を妨害できるため、これは機能としてのファイルディスクリプタの安全な使用を複雑にします。[ 9 ] [ 10 ]機能システムとして特別に設計されたオペレーティングシステムでは、機能自体に関連付けられた可変状態はほとんどありません。
Unixプロセスのファイル記述子テーブルはCリストの一例です。
参考文献
- ↑ The Open Group。「The Open Group Base Specifications Issue 8 IEEE Std 1003.1-2024」 。 2026年7月14日取得。
- ↑ The Open Group。「The Open Group Base Specifications Issue 7、IEEE Std 1003.1-2008、2016 Edition」 。 2017年9月21日取得。
- ↑ The Open Group. "The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008, 2016 Edition" . <stdio.h> . 2017-09-21に取得。
- 1 2 Bach, Maurice J. (1986). UNIXオペレーティングシステムの設計(第8版). Prentice-Hall . pp. 92–96 . ISBN 9780132017992。
- ↑ 「デバイス - 'll /Proc/Self/Fd/' ('ll /Dev/Fd' から) の出力は何を意味しますか?」
- ↑ The Open Group。「The Open Group Base Specifications Issue 7、IEEE Std 1003.1-2008、2018 Edition – creat」 。 2019年4月11日取得。
- ↑ Stephen Kitt、Michael Kerrisk。「close_range(2) — Linux マニュアル ページ」 。 2021年3月22日取得。
- ↑拡張APIセット、パート2。The Open Group。2006年10月。ISBN 1931624674。
- ↑ Brinkmann, Marcus (2009-02-04). "橋を架ける: ライブラリ API とファイルディスクリプタ?" . cap-talk . 2017-09-21に取得.
{{cite web}}: CS1メンテナンス: アーカイブサービスは非推奨になりました (リンク) - ↑ de Boyne Pollard, Jonathan (2007). "共有ファイルディスクリプタを非ブロッキングI/Oモードに設定しないでください" . 2017年9月21日取得。