tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
glob(3) GLOB_PERIOD bug?
It looks to me as though there's a bug in glob(3)'s GLOB_PERIOD. When
matching the pattern "../?" without GLOB_PERIOD, I get what I would
expect: a list of directories sibling to . which have single-character
names, or GLOB_NOMATCH if there are none. But with GLOB_PERIOD, I
always get GLOB_NOMATCH. (Test program below, after my signature.)
4.0.1 gets this case right. Looking at diffs between the two, I see
some code in glob2() reading
if ((!anymeta) ||
((pglob->gl_flags & GLOB_PERIOD) &&
(diff >= 1 && pend[-1] == DOT) &&
(diff >= 2 && (pend[-2] == SLASH || pend[-2] == DOT)) &&
(diff < 3 || pend[-3] == SLASH))) {
which was just
if (!anymeta) {
in 4.0.1. Reverting this one tidbit makes my test case work (../.
shows up in the results in addition, which is exactly what I would
expect).
This code looks very odd to me; I'm having trouble figuring out what it
does. It appears to say "if GLOB_PERIOD is set and the component is .
or .., pretend we had no metacharacters" - but if the component is . or
.., then we _do_ have no metacharacters. But my understanding of it is
clearly flawed, because removing it changes things, and my
understanding says that it shouldn't.
Furthermore, for GLOB_PERIOD to control anything which cares about more
than whether the component in question begins with a dot strikes me as
dubious, and this code is clearly special-casing more than that.
But someone must have had some kind of intent when making that change,
so I'm impelled to ask: what's the point of it? What case does it get
righter than the other version?
/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mouse%rodents-montreal.org@localhost
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Here's that test program:
#include <glob.h>
#include <stdio.h>
#include <errno.h>
#include <strings.h>
static int err(const char *s, int e)
{
printf("err: path=%s err=%d (%s)\n",s,e,strerror(e));
return(0);
}
static void trywith(int f)
{
int rv;
glob_t g;
int i;
rv = glob("../?",f,&err,&g);
switch (rv)
{ case GLOB_ABORTED:
printf(" GLOB_ABORTED\n");
break;
case GLOB_NOMATCH:
printf(" GLOB_NOMATCH\n");
break;
case GLOB_NOSPACE:
printf(" GLOB_NOSPACE\n");
break;
default:
printf(" rv = %d?\n",rv);
break;
case 0:
printf(" pathc=%d matchc=%d\n",(int)g.gl_pathc,(int)g.gl_matchc);
for (i=0;i<g.gl_pathc;i++)
{ printf(" [%d] %s\n",i,g.gl_pathv[i]);
}
break;
}
}
int main(void);
int main(void)
{
printf("flags = 0:\n");
trywith(0);
printf("flags = GLOB_PERIOD:\n");
trywith(GLOB_PERIOD);
return(0);
}
Home |
Main Index |
Thread Index |
Old Index