Carry over changes from 2.1 which increase the speed and fix some bugs.

This commit is contained in:
Ulrich Drepper 1998-08-12 12:30:23 +00:00
parent e7a4703700
commit 37c6743250

View File

@ -155,6 +155,12 @@ extern void abort (), exit ();
#endif /* Standard headers. */
#ifdef HAVE_GETLOGIN_R
extern int getlogin_r __P ((char *, size_t));
#else
extern char *getlogin __P ((void));
#endif
#ifndef ANSI_STRING
# ifndef bzero
@ -180,7 +186,6 @@ extern void bcopy ();
# define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
#endif
#ifndef __GNU_LIBRARY__
# ifdef __GNUC__
__inline
@ -239,6 +244,17 @@ extern char *alloca ();
# endif
#endif
#ifdef _LIBC
# undef strdup
# define strdup(str) __strdup (str)
# define sysconf(id) __sysconf (id)
# define closedir(dir) __closedir (dir)
# define opendir(name) __opendir (name)
# define readdir(str) __readdir (str)
# define getpwnam_r(name, bufp, buf, len, res) \
__getpwnam_r (name, bufp, buf, len, res)
#endif
#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
# undef size_t
# define size_t unsigned int
@ -246,21 +262,25 @@ extern char *alloca ();
/* Some system header files erroneously define these.
We want our own definitions from <fnmatch.h> to take precedence. */
#undef FNM_PATHNAME
#undef FNM_NOESCAPE
#undef FNM_PERIOD
#ifndef __GNU_LIBRARY__
# undef FNM_PATHNAME
# undef FNM_NOESCAPE
# undef FNM_PERIOD
#endif
#include <fnmatch.h>
/* Some system header files erroneously define these.
We want our own definitions from <glob.h> to take precedence. */
#undef GLOB_ERR
#undef GLOB_MARK
#undef GLOB_NOSORT
#undef GLOB_DOOFFS
#undef GLOB_NOCHECK
#undef GLOB_APPEND
#undef GLOB_NOESCAPE
#undef GLOB_PERIOD
#ifndef __GNU_LIBRARY__
# undef GLOB_ERR
# undef GLOB_MARK
# undef GLOB_NOSORT
# undef GLOB_DOOFFS
# undef GLOB_NOCHECK
# undef GLOB_APPEND
# undef GLOB_NOESCAPE
# undef GLOB_PERIOD
#endif
#include <glob.h>
static
@ -337,7 +357,7 @@ glob (pattern, flags, errfunc, pglob)
glob_t *pglob;
{
const char *filename;
char *dirname;
const char *dirname;
size_t dirlen;
int status;
int oldcount;
@ -477,43 +497,98 @@ glob (pattern, flags, errfunc, pglob)
/* Find the filename. */
filename = strrchr (pattern, '/');
#if defined __MSDOS__ || defined WINDOWS32
/* The case of "d:pattern". Since `:' is not allowed in
file names, we can safely assume that wherever it
happens in pattern, it signals the filename part. This
is so we could some day support patterns like "[a-z]:foo". */
if (filename == NULL)
filename = strchr (pattern, ':');
#endif /* __MSDOS__ || WINDOWS32 */
if (filename == NULL)
{
filename = pattern;
/* This can mean two things: a simple name or "~name". The later
case is nothing but a notation for a directory. */
if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
{
dirname = pattern;
dirlen = strlen (pattern);
/* Set FILENAME to NULL as a special flag. This is ugly but
other solutions would require much more code. We test for
this special case below. */
filename = NULL;
}
else
{
filename = pattern;
#ifdef _AMIGA
dirname = (char *) "";
dirname = "";
#else
dirname = (char *) ".";
dirname = ".";
#endif
dirlen = 0;
dirlen = 0;
}
}
else if (filename == pattern)
{
/* "/pattern". */
dirname = (char *) "/";
dirname = "/";
dirlen = 1;
++filename;
}
else
{
char *newp;
dirlen = filename - pattern;
dirname = (char *) __alloca (dirlen + 1);
#ifdef HAVE_MEMPCPY
*((char *) mempcpy (dirname, pattern, dirlen)) = '\0';
#else
memcpy (dirname, pattern, dirlen);
dirname[dirlen] = '\0';
#endif
++filename;
}
#if defined __MSDOS__ || defined WINDOWS32
if (*filename == ':'
|| (filename > pattern + 1 && filename[-1] == ':'))
{
char *drive_spec;
if (filename[0] == '\0' && dirlen > 1)
/* "pattern/". Expand "pattern", appending slashes. */
{
int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
if (val == 0)
pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK);
return val;
++dirlen;
drive_spec = (char *) __alloca (dirlen + 1);
#ifdef HAVE_MEMPCPY
*((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
#else
memcpy (drive_spec, pattern, dirlen);
drive_spec[dirlen] = '\0';
#endif
/* For now, disallow wildcards in the drive spec, to
prevent infinite recursion in glob. */
if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
return GLOB_NOMATCH;
/* If this is "d:pattern", we need to copy `:' to DIRNAME
as well. If it's "d:/pattern", don't remove the slash
from "d:/", since "d:" and "d:/" are not the same.*/
}
#endif
newp = (char *) __alloca (dirlen + 1);
#ifdef HAVE_MEMPCPY
*((char *) mempcpy (newp, pattern, dirlen)) = '\0';
#else
memcpy (newp, pattern, dirlen);
newp[dirlen] = '\0';
#endif
dirname = newp;
++filename;
if (filename[0] == '\0'
#if defined __MSDOS__ || defined WINDOWS32
&& dirname[dirlen - 1] != ':'
&& (dirlen < 3 || dirname[dirlen - 2] != ':'
|| dirname[dirlen - 1] != '/')
#endif
&& dirlen > 1)
/* "pattern/". Expand "pattern", appending slashes. */
{
int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
if (val == 0)
pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
| (flags & GLOB_MARK));
return val;
}
}
if (!(flags & GLOB_APPEND))
@ -525,12 +600,12 @@ glob (pattern, flags, errfunc, pglob)
oldcount = pglob->gl_pathc;
#ifndef VMS
if ((flags & GLOB_TILDE) && dirname[0] == '~')
if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
{
if (dirname[1] == '\0' || dirname[1] == '/')
{
/* Look up home directory. */
char *home_dir = getenv ("HOME");
const char *home_dir = getenv ("HOME");
# ifdef _AMIGA
if (home_dir == NULL || home_dir[0] == '\0')
home_dir = "SYS:";
@ -542,37 +617,38 @@ glob (pattern, flags, errfunc, pglob)
if (home_dir == NULL || home_dir[0] == '\0')
{
int success;
# if defined HAVE_GETLOGIN_R || defined _LIBC
extern int getlogin_r __P ((char *, size_t));
size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
char *name;
# if defined HAVE_GETLOGIN_R || defined _LIBC
size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
if (buflen == 0)
/* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
a moderate value. */
buflen = 16;
buflen = 20;
name = (char *) __alloca (buflen);
success = getlogin_r (name, buflen) >= 0;
# else
extern char *getlogin __P ((void));
char *name;
success = (name = getlogin ()) != NULL;
# endif
if (success)
{
struct passwd *p;
# if defined HAVE_GETPWNAM_R || defined _LIBC
size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
char *pwtmpbuf;
struct passwd pwbuf, *p;
struct passwd pwbuf;
if (pwbuflen == -1)
/* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
Try a moderate value. */
pwbuflen = 1024;
pwtmpbuf = (char *) __alloca (pwbuflen);
success = (__getpwnam_r (name, &pwbuf, pwtmpbuf,
pwbuflen, &p) >= 0);
success = (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
>= 0);
# else
struct passwd *p = getpwnam (name);
p = getpwnam (name);
success = p != NULL;
# endif
if (success)
@ -580,7 +656,10 @@ glob (pattern, flags, errfunc, pglob)
}
}
if (home_dir == NULL || home_dir[0] == '\0')
home_dir = (char *) "~"; /* No luck. */
if (flags & GLOB_TILDE_CHECK)
return GLOB_NOMATCH;
else
home_dir = "~"; /* No luck. */
# endif /* WINDOWS32 */
# endif
/* Now construct the full directory. */
@ -605,35 +684,45 @@ glob (pattern, flags, errfunc, pglob)
else
{
char *end_name = strchr (dirname, '/');
char *user_name;
char *home_dir;
const char *user_name;
const char *home_dir;
if (end_name == NULL)
user_name = dirname + 1;
else
{
user_name = (char *) __alloca (end_name - dirname);
char *newp;
newp = (char *) __alloca (end_name - dirname);
# ifdef HAVE_MEMPCPY
*((char *) mempcpy (user_name, dirname + 1, end_name - dirname))
*((char *) mempcpy (newp, dirname + 1, end_name - dirname))
= '\0';
# else
memcpy (user_name, dirname + 1, end_name - dirname);
user_name[end_name - dirname - 1] = '\0';
memcpy (newp, dirname + 1, end_name - dirname);
newp[end_name - dirname - 1] = '\0';
# endif
user_name = newp;
}
/* Look up specific user's home directory. */
{
struct passwd *p;
# if defined HAVE_GETPWNAM_R || defined _LIBC
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
char *pwtmpbuf = (char *) __alloca (buflen);
struct passwd pwbuf, *p;
if (__getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0)
char *pwtmpbuf;
struct passwd pwbuf;
if (buflen == -1)
/* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
moderate value. */
buflen = 1024;
pwtmpbuf = (char *) __alloca (buflen);
if (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0)
home_dir = p->pw_dir;
else
home_dir = NULL;
# else
struct passwd *p = getpwnam (user_name);
p = getpwnam (user_name);
if (p != NULL)
home_dir = p->pw_dir;
else
@ -657,11 +746,69 @@ glob (pattern, flags, errfunc, pglob)
# endif
dirname = newp;
}
else
if (flags & GLOB_TILDE_CHECK)
/* We have to regard it as an error if we cannot find the
home directory. */
return GLOB_NOMATCH;
}
# endif /* Not Amiga && not WINDOWS32. */
}
#endif /* Not VMS. */
/* Now test whether we looked for "~" or "~NAME". In this case we
can give the answer now. */
if (filename == NULL)
{
struct stat st;
/* Return the directory if we don't check for error or if it exists. */
if ((flags & GLOB_NOCHECK)
|| (((flags & GLOB_ALTDIRFUNC)
? (*pglob->gl_stat) (dirname, &st)
: __stat (dirname, &st)) == 0
&& S_ISDIR (st.st_mode)))
{
pglob->gl_pathv
= (char **) realloc (pglob->gl_pathv,
(pglob->gl_pathc +
((flags & GLOB_DOOFFS) ?
pglob->gl_offs : 0) +
1 + 1) *
sizeof (char *));
if (pglob->gl_pathv == NULL)
return GLOB_NOSPACE;
if (flags & GLOB_DOOFFS)
while (pglob->gl_pathc < pglob->gl_offs)
pglob->gl_pathv[pglob->gl_pathc++] = NULL;
#if defined HAVE_STRDUP || defined _LIBC
pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
#else
{
size_t len = strlen (dirname) + 1;
char *dircopy = malloc (len);
if (dircopy != NULL)
pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
len);
}
#endif
if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
{
free (pglob->gl_pathv);
return GLOB_NOSPACE;
}
pglob->gl_pathv[++pglob->gl_pathc] = NULL;
pglob->gl_flags = flags;
return 0;
}
/* Not found. */
return GLOB_NOMATCH;
}
if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
{
/* The directory name contains metacharacters, so we
@ -727,26 +874,29 @@ glob (pattern, flags, errfunc, pglob)
flags |= GLOB_MAGCHAR;
/* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
But if we have not found any matching entry and thie GLOB_NOCHECK
flag was set we must return the list consisting of the disrectory
names followed by the filename. */
if (pglob->gl_pathc == oldcount)
/* No matches. */
if (flags & GLOB_NOCHECK)
{
size_t len = strlen (pattern) + 1;
char *patcopy = (char *) malloc (len);
if (patcopy == NULL)
return GLOB_NOSPACE;
memcpy (patcopy, pattern, len);
size_t filename_len = strlen (filename) + 1;
char **new_pathv;
struct stat st;
/* This is an pessimistic guess about the size. */
pglob->gl_pathv
= (char **) realloc (pglob->gl_pathv,
(pglob->gl_pathc +
((flags & GLOB_DOOFFS) ?
pglob->gl_offs : 0) +
1 + 1) *
dirs.gl_pathc + 1) *
sizeof (char *));
if (pglob->gl_pathv == NULL)
{
free (patcopy);
globfree (&dirs);
return GLOB_NOSPACE;
}
@ -754,12 +904,55 @@ glob (pattern, flags, errfunc, pglob)
while (pglob->gl_pathc < pglob->gl_offs)
pglob->gl_pathv[pglob->gl_pathc++] = NULL;
pglob->gl_pathv[pglob->gl_pathc++] = patcopy;
for (i = 0; i < dirs.gl_pathc; ++i)
{
const char *dir = dirs.gl_pathv[i];
size_t dir_len = strlen (dir);
/* First check whether this really is a directory. */
if (((flags & GLOB_ALTDIRFUNC)
? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
|| !S_ISDIR (st.st_mode))
/* No directory, ignore this entry. */
continue;
pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
+ filename_len);
if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
{
globfree (&dirs);
globfree (pglob);
return GLOB_NOSPACE;
}
#ifdef HAVE_MEMPCPY
mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
dir, dir_len),
"/", 1),
filename, filename_len);
#else
memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
filename, filename_len);
#endif
++pglob->gl_pathc;
}
pglob->gl_pathv[pglob->gl_pathc] = NULL;
pglob->gl_flags = flags;
/* Now we know how large the gl_pathv vector must be. */
new_pathv = (char **) realloc (pglob->gl_pathv,
((pglob->gl_pathc + 1)
* sizeof (char *)));
if (new_pathv != NULL)
pglob->gl_pathv = new_pathv;
}
else
return GLOB_NOMATCH;
globfree (&dirs);
}
else
{
@ -791,10 +984,10 @@ glob (pattern, flags, errfunc, pglob)
int i;
struct stat st;
for (i = oldcount; i < pglob->gl_pathc; ++i)
if (((flags & GLOB_ALTDIRFUNC) ?
(*pglob->gl_stat) (pglob->gl_pathv[i], &st) :
__stat (pglob->gl_pathv[i], &st)) == 0 &&
S_ISDIR (st.st_mode))
if (((flags & GLOB_ALTDIRFUNC)
? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
: __stat (pglob->gl_pathv[i], &st)) == 0
&& S_ISDIR (st.st_mode))
{
size_t len = strlen (pglob->gl_pathv[i]) + 2;
char *new = realloc (pglob->gl_pathv[i], len);
@ -872,11 +1065,31 @@ prefix_array (dirname, array, n)
{
register size_t i;
size_t dirlen = strlen (dirname);
#if defined __MSDOS__ || defined WINDOWS32
int sep_char = '/';
# define DIRSEP_CHAR sep_char
#else
# define DIRSEP_CHAR '/'
#endif
if (dirlen == 1 && dirname[0] == '/')
/* DIRNAME is just "/", so normal prepending would get us "//foo".
We want "/foo" instead, so don't prepend any chars from DIRNAME. */
dirlen = 0;
#if defined __MSDOS__ || defined WINDOWS32
else if (dirlen > 1)
{
if (dirname[dirlen - 1] == '/')
/* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
--dirlen;
else if (dirname[dirlen - 1] == ':')
{
/* DIRNAME is "d:". Use `:' instead of `/'. */
--dirlen;
sep_char = ':';
}
}
#endif
for (i = 0; i < n; ++i)
{
@ -892,12 +1105,12 @@ prefix_array (dirname, array, n)
#ifdef HAVE_MEMPCPY
{
char *endp = (char *) mempcpy (new, dirname, dirlen);
*endp++ = '/';
*endp++ = DIRSEP_CHAR;
mempcpy (endp, array[i], eltlen);
}
#else
memcpy (new, dirname, dirlen);
new[dirlen] = '/';
new[dirlen] = DIRSEP_CHAR;
memcpy (&new[dirlen + 1], array[i], eltlen);
#endif
free ((__ptr_t) array[i]);
@ -959,7 +1172,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
int (*errfunc) __P ((const char *, int));
glob_t *pglob;
{
__ptr_t stream;
__ptr_t stream = NULL;
struct globlink
{
@ -971,92 +1184,127 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
int meta;
int save;
stream = ((flags & GLOB_ALTDIRFUNC) ?
(*pglob->gl_opendir) (directory) :
(__ptr_t) opendir (directory));
if (stream == NULL)
meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
if (meta == 0)
{
if ((errfunc != NULL && (*errfunc) (directory, errno)) ||
(flags & GLOB_ERR))
return GLOB_ABORTED;
if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
/* We need not do any tests. The PATTERN contains no meta
characters and we must not return an error therefore the
result will always contain exactly one name. */
flags |= GLOB_NOCHECK;
else
{
/* Since we use the normal file functions we can also use stat()
to verify the file is there. */
struct stat st;
size_t patlen = strlen (pattern);
size_t dirlen = strlen (directory);
char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
# ifdef HAVE_MEMPCPY
mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
"/", 1),
pattern, patlen + 1);
# else
memcpy (fullname, directory, dirlen);
fullname[dirlen] = '/';
memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
# endif
if (((flags & GLOB_ALTDIRFUNC)
? (*pglob->gl_stat) (fullname, &st)
: __stat (fullname, &st)) == 0)
/* We found this file to be existing. Now tell the rest
of the function to copy this name into the result. */
flags |= GLOB_NOCHECK;
}
nfound = 0;
meta = 0;
}
else if (pattern[0] == '\0')
{
/* This is a special case for matching directories like in
"*a/". */
names = (struct globlink *) __alloca (sizeof (struct globlink));
names->name = (char *) malloc (1);
if (names->name == NULL)
goto memory_error;
names->name[0] = '\0';
names->next = NULL;
nfound = 1;
meta = 0;
}
else
{
nfound = 0;
meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
if(meta)
flags |= GLOB_MAGCHAR;
while (1)
if (pattern[0] == '\0')
{
const char *name;
size_t len;
struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ?
(*pglob->gl_readdir) (stream) :
readdir ((DIR *) stream));
if (d == NULL)
break;
if (! REAL_DIR_ENTRY (d))
continue;
/* This is a special case for matching directories like in
"*a/". */
names = (struct globlink *) __alloca (sizeof (struct globlink));
names->name = (char *) malloc (1);
if (names->name == NULL)
goto memory_error;
names->name[0] = '\0';
names->next = NULL;
nfound = 1;
meta = 0;
}
else
{
stream = ((flags & GLOB_ALTDIRFUNC)
? (*pglob->gl_opendir) (directory)
: (__ptr_t) opendir (directory));
if (stream == NULL)
{
if ((errfunc != NULL && (*errfunc) (directory, errno))
|| (flags & GLOB_ERR))
return GLOB_ABORTED;
nfound = 0;
meta = 0;
}
else
{
int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
| ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
#if defined _AMIGA || defined VMS
| FNM_CASEFOLD
#endif
);
nfound = 0;
flags |= GLOB_MAGCHAR;
while (1)
{
const char *name;
size_t len;
struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
? (*pglob->gl_readdir) (stream)
: readdir ((DIR *) stream));
if (d == NULL)
break;
if (! REAL_DIR_ENTRY (d))
continue;
#ifdef HAVE_D_TYPE
/* If we shall match only directories use the information
provided by the dirent call if possible. */
if ((flags & GLOB_ONLYDIR)
&& d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
continue;
/* If we shall match only directories use the information
provided by the dirent call if possible. */
if ((flags & GLOB_ONLYDIR)
&& d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
continue;
#endif
name = d->d_name;
name = d->d_name;
if ((!meta && strcmp (pattern, name) == 0)
|| fnmatch (pattern, name,
(!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |
((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
#ifdef _AMIGA
| FNM_CASEFOLD
#endif
) == 0)
{
struct globlink *new
= (struct globlink *) __alloca (sizeof (struct globlink));
len = NAMLEN (d);
new->name = (char *) malloc (len + 1);
if (new->name == NULL)
goto memory_error;
if (fnmatch (pattern, name, fnm_flags) == 0)
{
struct globlink *new = (struct globlink *)
__alloca (sizeof (struct globlink));
len = NAMLEN (d);
new->name = (char *) malloc (len + 1);
if (new->name == NULL)
goto memory_error;
#ifdef HAVE_MEMPCPY
*((char *) mempcpy ((__ptr_t) new->name, name, len)) = '\0';
*((char *) mempcpy ((__ptr_t) new->name, name, len))
= '\0';
#else
memcpy ((__ptr_t) new->name, name, len);
new->name[len] = '\0';
memcpy ((__ptr_t) new->name, name, len);
new->name[len] = '\0';
#endif
new->next = names;
names = new;
++nfound;
if (!meta)
break;
new->next = names;
names = new;
++nfound;
}
}
}
}
}
if (nfound == 0 && (flags & GLOB_NOMAGIC) && !meta)
flags |= GLOB_NOCHECK;
if (nfound == 0 && (flags & GLOB_NOCHECK))
{
size_t len = strlen (pattern);
@ -1097,10 +1345,11 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
}
save = errno;
if (flags & GLOB_ALTDIRFUNC)
(*pglob->gl_closedir) (stream);
else
closedir ((DIR *) stream);
if (stream != NULL)
if (flags & GLOB_ALTDIRFUNC)
(*pglob->gl_closedir) (stream);
else
closedir ((DIR *) stream);
__set_errno (save);
return nfound == 0 ? GLOB_NOMATCH : 0;