3

ディレクトリツリーをたどり、そこにあるファイルfindを呼び出してそのタイプを判断する動作の一部を模倣するプログラムを作成しています。lstatrealfindは、ユーザーがそのディレクトリで R または X アクセス権を持っていないファイルを無視します。この動作を再現できないようです。これを実行するlstatコードがaccess().

私の最初の考えは、おそらく2番目の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;
    }
4

1 に答える 1

4

lstat()戻ってはいけませんESPIPE(不正なシーク)。それを返しているのは別のシステムコールではないですか、またはerrno成功した後に変更されていない値lstat()ですか? (つまり、バグは実際には省略したエラー チェック コードにある可能性があります)。

access()とにかく、この方法で使用する意味はありません。競合状態が発生するだけで (access()呼び出しとopendir()/lstat()呼び出しの間でファイルのアクセス許可が変更される可能性があるため)、何も得られません。代わりにopendir()andの戻り値を確認するだけです。lstat()

void open_dir( char *dir, char *pattern, char type )
{
    DIR *d;
    struct dirent *de;

    if (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 ];
    struct stat buf;

    strcpy(fn, dir);
    strcat(fn, "/");
    strcat(fn, de->d_name);

    if (lstat(fn, &buf) == 0)
    {
        //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;
}

これは一般的に正しいパターンです。操作が機能するかどうかを確認してから操作を試行するのではなく、無条件に操作を試行してから、失敗した理由を確認します。

于 2012-02-27T02:27:42.703 に答える