4

コンテクスト:

このreaddir_r関数は、から次のエントリを読み取るために使用されますDIR*(もありreaddirますが、スレッドセーフではありません)。readdir_r出力を保持するためにユーザーが割り当てたバッファーへのポインターを取りますdirent。マンページは、このバッファに必要なサイズがシステムごとに異なる可能性があることを示しており、実行時に安全な長さを見つける方法の例を示しています。

len = offsetof(struct dirent, d_name) + pathconf(dirpath, _PC_NAME_MAX) + 1;

(警告:上記には競合状態があります。これは、を使用dirfdして開いたファイル記述子を取得し、の代わりにをDIR*使用することで回避できます)fpathconfpathconf

質問:

のマンページを見るとpathconf、次のように記載されています。

_PC_NAME_MAX は、プロセスが作成できるディレクトリパスまたはfd内のファイル名の最大長を返します。対応するマクロは_POSIX_NAME_MAXです。

ただし、メモのセクションには次のように記載されています。

nameが_PC_NAME_MAXに等しい場合に返される値よりも長い名前のファイルが、指定されたディレクトリに存在する可能性があります。

このメモは本当ですか?もしそうなら、readdir_rmanページのサンプルコードは正しくありませんか?

4

1 に答える 1

3

{NAME_MAX}のその解釈はPOSIXと一致しません。POSIXによると、実装では{NAME_MAX}より長い名前をエラーとして処理する必要がありd_name、{NAME_MAX}+1バイトのバッファーで十分です。

別の方法(POSIX.1-2008)は、scandir()スレッドセーフであり、呼び出し元からこの問題を抽象化するものを使用することです。残念ながら、POSIXには存在しないscandirat()か、どのバージョンにもありません。fscandir()

readdir()多くのシステムでは、返されたものへの最後のアクセスが発生する限りstruct dirent、次の呼び出しの前に使用することも安全ですreaddir()(これは構造の有効性に関する既存の要件に準拠しています)。POSIXがこれを許可しない理由はほとんどないと思います。readdir_r()非常に多くの追加コードが必要になるため、処理が遅くなり、複雑になります。

于 2013-04-06T23:10:33.157 に答える