scandir()函数扫描目录dir,调用 每个目录条目上的select()为“int(* filter)(const struct dirent *)” 如何将模式值作为参数传递给过滤器中使用的fnmatch(const char * pattern,const char * string,int flags)函数?
这是我的示例代码
int my_selectgrf(const struct dirent *namelist)
{
int r = 0;
char my_pattern[] = "*.grf";
r = fnmatch(my_pattern, namelist->d_name, FNM_PERIOD);
return (r==0)?1:0;
}
scandir("/pub/data/grf", &namelist, my_selectgrf, alphasort);
我的目标是能够使用my_pattern作为输入参数。
答案 0 :(得分:5)
简短的回答:你做不到。这是一个非常糟糕的API,直到最近2008年(基于glibc中的糟糕设计)将这样的东西添加到POSIX中是完全可耻的。这种API没有办法参数化或传递上下文应该已经废除了20多年。
据说,有一些解决方法:
方法1:使用全局变量,如果您的代码需要是线程安全的,请确保只有一个线程可以通过锁定一次使用具有给定扫描功能的scandir
。这当然序列化用法,如果你真的想要从多个线程调用该函数,这可能是不可接受的。
方法2:使用线程本地存储,GCC __thread
关键字(或GCC _Thread_local
关键字,GCC遗憾地仍然不接受)或POSIX pthread_setspecific
和系列。这很干净,但遗憾的是它可能不正确;如果scandir
的实现在内部使用多个线程,则该参数可能无法在某些调用回扫描函数时可用。目前,我不相信有scandir
的多线程实现。
现在,更好的解决方案:
Ditch scandir
并使用适当的API编写自己的函数来执行相同的操作。不过,它只有几行。