find
の動作を模倣するプログラムを作成しており、ディレクトリツリーを参照して見つかったファイルでlstat
を呼び出してタイプを判別します。実際のfind
は、そのディレクトリにRまたはXアクセス権がないファイルは無視します。私はこの振る舞いを再現することはできません。私のコードは先に進んで、lstat
を呼び出し、これを実行するコードがブロックaccess()
をチェックしているにもかかわらず、不正なシークエラー(これは私が避けようとしているものです)を取得します。アクセス許可()にアクセス許可の問題などがありません
私が最初に考えたのは、おそらく二access()
呼び出しは、パスではなく、パス/ファイル名にする必要がありますということでしたが、それはどちらか動作していないようでした(と冗長それがとにかくないですか?)
どれ指導大いに感謝します。
私のコード(私は簡潔にするためキャッチエラーや他のものを切り出しています):
void open_dir(char *dir, char *pattern, char type)
{
DIR *d;
struct dirent *de;
if (access(dir, (R_OK | X_OK)) == 0)
{
d = opendir(dir);
while((de = readdir(d)))
examine_de(de, dir, pattern, type);
closedir(d);
}
}
void examine_de(struct dirent *de, char *dir, char *pattern, char type)
{
char fn[ _POSIX_PATH_MAX ];
strcpy(fn, dir);
strcat(fn, "/");
strcat(fn, de->d_name);
if (access(fn, (R_OK | X_OK)) == 0)
{
struct stat buf;
lstat(fn, &buf);
//check pattern matches, etc., printf fn if appropriate
if ((S_ISDIR(buf.st_mode)) &&
(strcmp(de->d_name, ".") != 0) &&
(strcmp(de->d_name, "..") != 0))
open_dir(fn, pattern, type);
}
return;
}
「アクセス」が役に立たないレースを指摘するため+1。 –
あなたはおそらくそれはお手上げのコメントだと思ったかもしれませんが、 'perr'の後に' errno = 0'を設定すると、 'readdir'のエラーチェックの場合に特に違いがあることがわかりました。エラーが発生した場合はディレクトリ*と*の末尾に移動する前に、私のコードが 'errno == 0 'をチェックしていました。しかし、私は確かに 'アクセス'についてのあなたの警告を心に持っていくでしょう - ありがとう! –
@SabrinaStar: 'readdir()'呼び出しの直前に 'errno = 0;'を設定する必要があります。ここで重要な点は 'errno'を設定した呼び出しが成功しないことです。 – caf