プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

効率的なdirectry readingコードについて このエントリーをはてなブックマークに追加

Ulrich Drepper が自身のブログで、効率的なディレクトリ読み込みについてエントリを書いている。
しかし、改善案が思いっきり linux+glibc 依存なのでこれを実践できる人は少ないだろうな。と苦笑

元記事: http://udrepper.livejournal.com/18555.html

以下、抜粋


ダメなコード

DIR *dir = opendir(some_path);
struct dirent *d;
struct dirent d_mem;
while (readdir_r(d, &d_mem, &d) == 0) {
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s/somefile", some_path, d->d_name);
int fd = open(path, O_RDONLY);
if (fd != -1) {
... do something ...
close (fd);
}
}
closedir(dir);


オススメ
  DIR *dir = opendir(some_path);
int dfd = dirfd(dir);
struct dirent64 *d;
while ((d = readdir64(dir)) != NULL) {
if (d->d_type != DT_DIR && d->d_type != DT_UNKNOWN)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/somefile", d->d_name);
int fd = openat(dfd, path, O_RDONLY);
if (fd != -1) {
... do something ...
close (fd);
}
}
closedir(dir);


ポイント

  • readdir_r() は意味ないよ。これは複数のスレッドが同じディレクトリストリームを読むことを可能にする関数だが、dirがローカル変数になってるから絶対他スレッドと競合しない
  • readdir()ではなく、readdir64()を使え。2GB越えのファイルで泣きたくなければ
  • Linuxは、名前長制限は個々のファイル名open()等の引数文字列長にかかるのであって、絶対パスにはかからない(まあリンクとか有るからカーネルでチェックできんしね)。だからPATH_MAXを安易に使うな。some_pathがPATH_MAXに非常に近い文字列長だったら、どうなる?openat()を使うべし
  • そもそも some_pathを足してopenする事自体がracyでダメ。パスをたぐってる間に別プロセスがリンクを張り直したりできるよ。セキュリティーホールになるよ。openat()を使うべし
  • dirent64はd_typeフィールドがあるから、openしなくてもディレクトリかどうか分かるよ


追記: 元エントリへのリンクを忘れていたので貼る
追記2: 識者から、個々のファイル名という表現は誤解を招くというご指摘をいただいた。その通りなので修正
関連記事


linux | 【2009-09-21(Mon) 13:54:17】 | Trackback:(0) | Comments:(1)
コメント

ダメなコードの方のreaddir_rの第一引数はdではなくdirではないでしょうか?
2011-11-19 土 15:21:58 | URL | anonymous #- [ 編集]
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。