我正在编写一个程序,以模仿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;
}
答案 0 :(得分:4)
lstat()
永远不会返回ESPIPE
(非法搜寻)。您是否确定在成功errno
之后返回的是另一个系统调用,或者未更改lstat()
值? (换句话说,错误实际上可能在您已经省略的错误检查代码中。)
尽管如此,以这种方式使用access()
毫无意义 - 它只是引入了竞争条件(因为文件权限可能会在access()
调用和opendir()
之间发生变化/ lstat()
致电),并没有获得任何收益。只需检查opendir()
和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;
}
这通常是正确的模式 - 而不是检查操作是否可行然后尝试操作,而是无条件地尝试操作,然后检查它失败的原因。