3

我正在编写一个程序来模拟find遍历目录树并调用lstat它在那里找到的文件以确定它们的类型的一些行为。realfind将忽略用户在该目录中没有 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;
    }
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 回答