summaryrefslogtreecommitdiff
path: root/posix
diff options
context:
space:
mode:
Diffstat (limited to 'posix')
-rw-r--r--posix/glob.c29
-rw-r--r--posix/glob.h5
2 files changed, 29 insertions, 5 deletions
diff --git a/posix/glob.c b/posix/glob.c
index 6a601ee15e..909b4f148c 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -114,6 +114,12 @@ extern int errno;
# define NAMLEN(d) _D_NAMLEN(d)
#endif
+/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
+ if the `d_type' member for `struct dirent' is available. */
+#ifdef _DIRENT_HAVE_D_TYPE
+# define HAVE_D_TYPE 1
+#endif
+
#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
/* Posix does not require that the d_ino field be present, and some
@@ -661,8 +667,8 @@ glob (pattern, flags, errfunc, pglob)
register int i;
status = glob (dirname,
- ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) |
- GLOB_NOSORT),
+ ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
+ | GLOB_NOSORT | GLOB_ONLYDIR),
errfunc, &dirs);
if (status != 0)
return status;
@@ -690,7 +696,8 @@ glob (pattern, flags, errfunc, pglob)
oldcount = pglob->gl_pathc;
status = glob_in_dir (filename, dirs.gl_pathv[i],
- (flags | GLOB_APPEND) & ~GLOB_NOCHECK,
+ ((flags | GLOB_APPEND)
+ & ~(GLOB_NOCHECK | GLOB_ERR)),
errfunc, pglob);
if (status == GLOB_NOMATCH)
/* No matches in this directory. Try the next. */
@@ -981,6 +988,14 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
if (! REAL_DIR_ENTRY (d))
continue;
+#ifdef HAVE_D_TYPE
+ /* If we shall match only directories use the information
+ provided by the dirent if possible. */
+ if ((flags & GLOB_ONLYDIR)
+ && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
+ continue;
+#endif
+
if (strcmp (pattern, d->d_name) == 0)
{
size_t len = NAMLEN (d);
@@ -1030,6 +1045,14 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
name = d->d_name;
+#ifdef HAVE_D_TYPE
+ /* If we shall match only directories use the information
+ provided by the dirent if possible. */
+ if ((flags & GLOB_ONLYDIR)
+ && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
+ continue;
+#endif
+
if (fnmatch (pattern, name,
(!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |
((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
diff --git a/posix/glob.h b/posix/glob.h
index 713117bd7e..a15d8ef92f 100644
--- a/posix/glob.h
+++ b/posix/glob.h
@@ -57,11 +57,12 @@ extern "C"
# define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions. */
# define GLOB_BRACE (1 << 10)/* Expand "{a,b}" to "a" "b". */
# define GLOB_NOMAGIC (1 << 11)/* If no magic chars, return the pattern. */
-# define GLOB_TILDE (1 <<12)/* Expand ~user and ~ to home directories. */
+# define GLOB_TILDE (1 << 12)/* Expand ~user and ~ to home directories. */
+# define GLOB_ONLYDIR (1 << 13)/* Match only directories. */
# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \
GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE| \
- GLOB_NOMAGIC|GLOB_TILDE)
+ GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR)
#else
# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \