如何在scandir中参数化select函数

scandir()函数扫描目录dir,在每个目录条目上调用select()为“int(* filter)(const struct dirent *)”如何将模式值作为参数传递给fnmatch(const char * pattern,const char * string,int flags)filter中使用的函数?

这是我的示例代码

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作为输入参数。

简短的回答:你做不到。 这是一个非常糟糕的API,直到2008年(基于glibc中的糟糕设计)将这样的东西添加到POSIX中是完全可耻的。 这种API没有办法参数化或传递上下文应该已经废除了20多年前。

话虽如此,有一些解决方法:

方法1:使用全局变量,如果您的代码需要是线程安全的,请确保只有一个线程可以通过锁定一次使用具有给定扫描function的scandir 。 这当然是序列化使用,如果您真的想要从多个线程调用该函数,这可能是不可接受的。

方法2:使用线程本地存储,GCC __thread关键字(或GCC遗憾地仍然不接受的C11 _Thread_local关键字)或POSIX pthread_setspecific和family。 这很干净,但遗憾的是它可能不正确; 如果scandir的实现内部使用多个线程,则在某些调用回扫描函数时该参数可能无法使用。 目前,我不相信有scandirmultithreading实现。

现在,更好的解决方案:

沟通scandir并使用适当的API编写自己的函数来做同样的事情。 反正它只有几行。