我也在想同样的问题 - "lstat的目的是什么?它会影响glob()的返回结果吗?"
在bsd_glob.c中的glob2()函数内,我注意到有一个g_stat调用,需要设置GLOB_MARK标志,我还注意到在此之前有一个g_lstat调用,它没有被标记检查保护。这两个调用都在一个if分支内,用于处理模式结束的情况。
如果我在perl-5.12.4/ext/File-Glob/bsd_glob.c的glob2函数中移除这两行代码...
- if (g_lstat(pathbuf, &sb, pglob))
- return(0);
唯一不通过的Perl测试(make test)是在ext/File-Glob/t/basic.t内的第五个测试,出现了以下错误:
not ok 5
t/basic.t中的第五个测试是
@a = bsd_glob("asdfasdf", 0);
SKIP: {
skip $^O, 1 if $^O eq 'MSWin32' || $^O eq 'NetWare';
is_deeply(\@a, []);
}
如果我用以下内容替换掉被删除的2行代码:
+ if (!((pglob->gl_flags & GLOB_NOCHECK) ||
+ ((pglob->gl_flags & GLOB_NOMAGIC) &&
+ !(pglob->gl_flags & GLOB_MAGCHAR)))){
+ if (g_lstat(pathbuf, &sb, pglob))
+ return(0);
+ }
我在使用linux x86_64 (RHEL6.3 2.6.32-358.11.1.el6.x86_64)和以下命令时,没有看到perl-5.12.4的"make test"失败:
strace -fe trace=lstat perl -e 'use File::Glob q{:glob};
print scalar bsd_glob(q{/var/log/*},GLOB_NOCHECK)'
我不再看到每个目录中的文件的lstat调用。
我的意思并不是说perl测试glob(File-Glob)是全面的(它们不是),或者这样的更改不会破坏现有行为(这似乎很可能)。就我所知,具有此(g_l)stat调用的代码存在于1990年的original-bsd / lib / libc / gen / glob.c中,已经有24年了。
另请参阅:
- “精通Perl”的第6章“Perl基准测试”,作者Brian D Foy,Randal L. Schwartz,其中包含一个比较使用glob()和opendir()的代码部分。
- 来自Dick Dunn的1991年comp.unix.wizards“未来Globs(名为“UNIX mindset ...”)”
- Usenet新闻组mod.sources Guido van Rossum在1986年7月发布了“Globbing”库例程(glob) - 我没有在该代码中看到“stat”的参考。