#include <dirent.h> struct dirent *readdir(DIR *dirp);
glibc の実装では dirent 構造体は以下のように定義されている。
struct dirent {
ino_t d_ino; /* inode 番号 */
off_t d_off; /* オフセットではない; 下記を参照 */
unsigned short d_reclen; /* このレコードの長さ */
unsigned char d_type; /* ファイル種別。全ファイルシステム */
でサポートされているわけではない */
char d_name[256]; /* ヌル終端されたファイル名 */
};
dirent 構造体のフィールドのうち POSIX.1 で要求されているのは、 d_name と d_ino だけである。他のフィールドは非標準であり、すべてのシステムで存在するわけではない。 詳細については、下記の「注意」を参照のこと。
dirent 構造体のフィールドは以下の通りである:
readdir() によって返されるデータは、それ以降の同じストリームに対する readdir() の呼び出しによって上書きされる可能性がある。
ディレクトリストリームの末尾に達した場合には、NULL が返され、 errno は変化しない。 エラーが発生した場合、NULL が返され、 errno が適切に設定される。エラーからストリームの末尾を区別するには、 readdir() を呼び出す前に errno を 0 に設定しておき、 NULL が返された場合に errno の値を確認すればよい。
インターフェース | 属性 | 値 |
readdir() | Thread safety | MT-Unsafe race:dirstream |
現在の POSIX.1 標準 (POSIX.1-2008) では、 readdir() がスレッドセーフであることは求められていない。しかしながら、最近の実装 (glibc による実装も含む) では、異なるディレクトリストリームに対する readdir() の同時並行の呼び出しはスレッドセーフである。複数のスレッドが同じディレクトリストリームから読み込みを行う必要がある場合も、非推奨の readdir_r(3) 関数を使用するよりも、外部同期を用いた readdir() を使う方が推奨される。 POSIX.1 の将来のバージョンでは、 readdir() は異なるディレクトリストリームに対して同時に使用された際にスレッドセーフであることが必須となる予定である。
連続する readdir() の呼び出しで読み込まれるファイル名の順序は、ファイルシステムの実装に依存する。名前が何らかの方法でソートされていることはありえない。
フィールド d_name と (XSI 拡張の) d_ino だけが POSIX.1 で規定されている。 d_type フィールドは、 Linux 以外では、おもに BSD 系のシステムでのみ利用可能である。残りのフィールドは多くのシステムに存在するが、全てのシステムに存在するわけではない。 glibc では、プログラムが POSIX.1 で定義されていないフィールドが 利用できるかをチェックすることができる。 チェックするには、マクロ _DIRENT_HAVE_D_NAMLEN, _DIRENT_HAVE_D_RECLEN, _DIRENT_HAVE_D_OFF, _DIRENT_HAVE_D_TYPE が定義されているかをテストすればよい。
警告: アプリケーションは、 d_name フィールドのサイズに依存すべきではない。 POSIX ではこのフィールドは char d_name[] (サイズ不定の文字配列) として規定しており、最大で終端のヌルバイト ('\0') の前に NAME_MAX 文字が入る。
POSIX.1 は、このフィールドを左辺値として使用すべきではないと明記している。また、 POSIX.1 では、 sizeof(d_name) の使用は間違いであり、代わりに strlen(d_name) を使用するように、との注記もある (いくつかのシステムでは、このフィールドは char d_name[1]! として定義されている)。このことは、 d_name を含むレコードのサイズを取得するために sizeof(struct dirent) を使用することも間違いであることを暗に示している。
多くのファイルシステムでは、
fpathconf(fd, _PC_NAME_MAX)
の呼び出しは値 255 を返すが、いくつかのファイルシステム (例えば CIFS や Windows SMB サーバーなど) では、(正しい動作なのだが) d_name で返されるヌル終端されたファイル名は実際にはこのサイズを超える場合がある点に注意すること。このような場合、 d_reclen フィールドは、上記の glibc dirent 構造体のサイズよりも大きな値となる。