1 /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
20 /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
21 optimizes away the pattern == NULL test below. */
22 # define _GL_ARG_NONNULL(params)
24 # include <libc-config.h>
32 #include <sys/types.h>
40 #if defined _WIN32 && ! defined __CYGWIN__
56 # define strdup(str) __strdup (str)
57 # define sysconf(id) __sysconf (id)
58 # define closedir(dir) __closedir (dir)
59 # define opendir(name) __opendir (name)
61 # define dirfd(str) __dirfd (str)
62 # define readdir(str) __readdir64 (str)
63 # define getpwnam_r(name, bufp, buf, len, res) \
64 __getpwnam_r (name, bufp, buf, len, res)
65 # define FLEXIBLE_ARRAY_MEMBER
67 # define struct_stat struct stat
69 # ifndef struct_stat64
70 # define struct_stat64 struct stat64
73 # define GLOB_LSTAT gl_lstat
75 # ifndef GLOB_FSTATAT64
76 # define GLOB_FSTATAT64 __fstatat64
78 # include <shlib-compat.h>
81 # define __getlogin_r(buf, len) getlogin_r (buf, len)
82 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
84 # define __alloca alloca
86 # define __readdir readdir
87 # define COMPILE_GLOB64
88 # define struct_stat struct stat
89 # define struct_stat64 struct stat
90 # define GLOB_LSTAT gl_lstat
91 # define GLOB_FSTATAT64 fstatat
96 #include <flexmember.h>
97 #include <glob_internal.h>
98 #include <scratch_buffer.h>
100 static const char *next_brace_sub (const char *begin
, int flags
) __THROWNL
;
102 /* The type of ((struct dirent *) 0)->d_type is 'unsigned char' on most
103 platforms, but 'unsigned int' in the mingw from mingw.org. */
104 typedef uint_fast32_t dirent_type
;
106 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
107 /* Any distinct values will do here.
108 Undef any existing macros out of the way. */
112 # define DT_UNKNOWN 0
117 /* A representation of a directory entry which does not depend on the
118 layout of struct dirent, or the size of ino_t. */
119 struct readdir_result
122 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
127 /* Initialize and return type member of struct readdir_result. */
129 readdir_result_type (struct readdir_result d
)
131 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
132 # define D_TYPE_TO_RESULT(source) (source)->d_type,
135 # define D_TYPE_TO_RESULT(source)
140 /* Construct an initializer for a struct readdir_result object from a
141 struct dirent *. No copy of the name is made. */
142 #define READDIR_RESULT_INITIALIZER(source) \
145 D_TYPE_TO_RESULT (source) \
148 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
149 type safety if an old interface version needs to be supported. */
151 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
154 /* Extract name and type from directory entry. No copy of the name is
155 made. If SOURCE is NULL, result name is NULL. Keep in sync with
156 convert_dirent64 below. */
157 static struct readdir_result
158 convert_dirent (const struct dirent
*source
)
162 struct readdir_result result
= { NULL
, };
165 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
169 #ifndef COMPILE_GLOB64
170 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
171 sync with convert_dirent above. */
172 static struct readdir_result
173 convert_dirent64 (const struct dirent64
*source
)
177 struct readdir_result result
= { NULL
, };
180 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
186 /* The results of opendir() in this file are not used with dirfd and fchdir,
187 and we do not leak fds to any single-threaded code that could use stdio,
188 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
189 FIXME - if the kernel ever adds support for multi-thread safety for
190 avoiding standard fds, then we should use opendir_safer. */
191 # ifdef GNULIB_defined_opendir
194 # ifdef GNULIB_defined_closedir
198 /* Just use malloc. */
199 # define __libc_use_alloca(n) false
200 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
201 # define extend_alloca_account(buf, len, newlen, avar) \
202 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
206 glob_lstat (glob_t
*pglob
, int flags
, const char *fullname
)
208 /* Use on glob-lstat-compat.c to provide a compat symbol which does not
209 use lstat / gl_lstat. */
215 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
216 ? pglob
->GLOB_LSTAT (fullname
, &ust
.st
)
217 : GLOB_FSTATAT64 (AT_FDCWD
, fullname
, &ust
.st64
,
218 AT_SYMLINK_NOFOLLOW
));
221 /* Set *R = A + B. Return true if the answer is mathematically
222 incorrect due to overflow; in this case, *R is the low order
223 bits of the correct answer. */
226 size_add_wrapv (size_t a
, size_t b
, size_t *r
)
228 #if 7 <= __GNUC__ && !defined __ICC
229 return __builtin_add_overflow (a
, b
, r
);
237 glob_use_alloca (size_t alloca_used
, size_t len
)
240 return (!size_add_wrapv (alloca_used
, len
, &size
)
241 && __libc_use_alloca (size
));
244 static int glob_in_dir (const char *pattern
, const char *directory
,
245 int flags
, int (*errfunc
) (const char *, int),
246 glob_t
*pglob
, size_t alloca_used
);
247 static int prefix_array (const char *prefix
, char **array
, size_t n
) __THROWNL
;
248 static int collated_compare (const void *, const void *) __THROWNL
;
251 /* Return true if FILENAME is a directory or a symbolic link to a directory.
252 Use FLAGS and PGLOB to resolve the filename. */
254 is_dir (char const *filename
, int flags
, glob_t
const *pglob
)
258 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
259 ? pglob
->gl_stat (filename
, &st
) == 0 && S_ISDIR (st
.st_mode
)
260 : (GLOB_FSTATAT64 (AT_FDCWD
, filename
, &st64
, 0) == 0
261 && S_ISDIR (st64
.st_mode
)));
264 /* Find the end of the sub-pattern in a brace expression. */
266 next_brace_sub (const char *cp
, int flags
)
270 if ((flags
& GLOB_NOESCAPE
) == 0 && *cp
== '\\')
278 if ((*cp
== '}' && depth
-- == 0) || (*cp
== ',' && depth
== 0))
285 return *cp
!= '\0' ? cp
: NULL
;
288 #ifndef GLOB_ATTRIBUTE
289 # define GLOB_ATTRIBUTE
292 /* Do glob searching for PATTERN, placing results in PGLOB.
293 The bits defined above may be set in FLAGS.
294 If a directory cannot be opened or read and ERRFUNC is not nil,
295 it is called with the pathname that caused the error, and the
296 'errno' value from the failing call; if it returns non-zero
297 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
298 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
299 Otherwise, 'glob' returns zero. */
302 __glob (const char *pattern
, int flags
, int (*errfunc
) (const char *, int),
305 const char *filename
;
306 char *dirname
= NULL
;
311 int dirname_modified
;
312 int malloc_dirname
= 0;
315 size_t alloca_used
= 0;
317 if (pattern
== NULL
|| pglob
== NULL
|| (flags
& ~__GLOB_FLAGS
) != 0)
319 __set_errno (EINVAL
);
323 /* POSIX requires all slashes to be matched. This means that with
324 a trailing slash we must match only directories. */
325 if (pattern
[0] && pattern
[strlen (pattern
) - 1] == '/')
326 flags
|= GLOB_ONLYDIR
;
328 if (!(flags
& GLOB_DOOFFS
))
329 /* Have to do this so 'globfree' knows where to start freeing. It
330 also makes all the code that uses gl_offs simpler. */
333 if (!(flags
& GLOB_APPEND
))
336 if (!(flags
& GLOB_DOOFFS
))
337 pglob
->gl_pathv
= NULL
;
342 if (pglob
->gl_offs
>= ~((size_t) 0) / sizeof (char *))
345 pglob
->gl_pathv
= (char **) malloc ((pglob
->gl_offs
+ 1)
347 if (pglob
->gl_pathv
== NULL
)
350 for (i
= 0; i
<= pglob
->gl_offs
; ++i
)
351 pglob
->gl_pathv
[i
] = NULL
;
355 if (flags
& GLOB_BRACE
)
359 if (flags
& GLOB_NOESCAPE
)
360 begin
= strchr (pattern
, '{');
372 if (*begin
== '\\' && begin
[1] != '\0')
374 else if (*begin
== '{')
383 /* Allocate working buffer large enough for our work. Note that
384 we have at least an opening and closing brace. */
392 size_t pattern_len
= strlen (pattern
) - 1;
393 int alloca_onealt
= glob_use_alloca (alloca_used
, pattern_len
);
395 onealt
= alloca_account (pattern_len
, alloca_used
);
398 onealt
= malloc (pattern_len
);
403 /* We know the prefix for all sub-patterns. */
404 alt_start
= mempcpy (onealt
, pattern
, begin
- pattern
);
406 /* Find the first sub-pattern and at the same time find the
407 rest after the closing brace. */
408 next
= next_brace_sub (begin
+ 1, flags
);
411 /* It is an invalid expression. */
413 if (__glibc_unlikely (!alloca_onealt
))
415 flags
&= ~GLOB_BRACE
;
419 /* Now find the end of the whole brace expression. */
423 rest
= next_brace_sub (rest
+ 1, flags
);
425 /* It is an illegal expression. */
428 /* Please note that we now can be sure the brace expression
430 rest_len
= strlen (++rest
) + 1;
432 /* We have a brace expression. BEGIN points to the opening {,
433 NEXT points past the terminator of the first element, and END
434 points past the final }. We will accumulate result names from
435 recursive runs for each brace alternative in the buffer using
437 firstc
= pglob
->gl_pathc
;
444 /* Construct the new glob expression. */
445 mempcpy (mempcpy (alt_start
, p
, next
- p
), rest
, rest_len
);
447 result
= __glob (onealt
,
448 ((flags
& ~(GLOB_NOCHECK
| GLOB_NOMAGIC
))
452 /* If we got an error, return it. */
453 if (result
&& result
!= GLOB_NOMATCH
)
455 if (__glibc_unlikely (!alloca_onealt
))
457 if (!(flags
& GLOB_APPEND
))
466 /* We saw the last entry. */
470 next
= next_brace_sub (p
, flags
);
471 assert (next
!= NULL
);
474 if (__glibc_unlikely (!alloca_onealt
))
477 if (pglob
->gl_pathc
!= firstc
)
478 /* We found some entries. */
480 else if (!(flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
486 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
488 /* Find the filename. */
489 filename
= strrchr (pattern
, '/');
491 #if defined __MSDOS__ || defined WINDOWS32
492 /* The case of "d:pattern". Since ':' is not allowed in
493 file names, we can safely assume that wherever it
494 happens in pattern, it signals the filename part. This
495 is so we could some day support patterns like "[a-z]:foo". */
496 if (filename
== NULL
)
497 filename
= strchr (pattern
, ':');
498 #endif /* __MSDOS__ || WINDOWS32 */
500 dirname_modified
= 0;
501 if (filename
== NULL
)
503 /* This can mean two things: a simple name or "~name". The latter
504 case is nothing but a notation for a directory. */
505 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && pattern
[0] == '~')
507 dirname
= (char *) pattern
;
508 dirlen
= strlen (pattern
);
510 /* Set FILENAME to NULL as a special flag. This is ugly but
511 other solutions would require much more code. We test for
512 this special case below. */
517 if (__glibc_unlikely (pattern
[0] == '\0'))
519 dirs
.gl_pathv
= NULL
;
524 dirname
= (char *) ".";
528 else if (filename
== pattern
529 || (filename
== pattern
+ 1 && pattern
[0] == '\\'
530 && (flags
& GLOB_NOESCAPE
) == 0))
532 /* "/pattern" or "\\/pattern". */
533 dirname
= (char *) "/";
540 dirlen
= filename
- pattern
;
541 #if defined __MSDOS__ || defined WINDOWS32
543 || (filename
> pattern
+ 1 && filename
[-1] == ':'))
548 drive_spec
= __alloca (dirlen
+ 1);
549 *((char *) mempcpy (drive_spec
, pattern
, dirlen
)) = '\0';
550 /* For now, disallow wildcards in the drive spec, to
551 prevent infinite recursion in glob. */
552 if (__glob_pattern_p (drive_spec
, !(flags
& GLOB_NOESCAPE
)))
554 /* If this is "d:pattern", we need to copy ':' to DIRNAME
555 as well. If it's "d:/pattern", don't remove the slash
556 from "d:/", since "d:" and "d:/" are not the same.*/
560 if (glob_use_alloca (alloca_used
, dirlen
+ 1))
561 newp
= alloca_account (dirlen
+ 1, alloca_used
);
564 newp
= malloc (dirlen
+ 1);
569 *((char *) mempcpy (newp
, pattern
, dirlen
)) = '\0';
573 #if defined __MSDOS__ || defined WINDOWS32
574 bool drive_root
= (dirlen
> 1
575 && (dirname
[dirlen
- 1] == ':'
576 || (dirlen
> 2 && dirname
[dirlen
- 2] == ':'
577 && dirname
[dirlen
- 1] == '/')));
579 bool drive_root
= false;
582 if (filename
[0] == '\0' && dirlen
> 1 && !drive_root
)
583 /* "pattern/". Expand "pattern", appending slashes. */
585 int orig_flags
= flags
;
586 if (!(flags
& GLOB_NOESCAPE
) && dirname
[dirlen
- 1] == '\\')
588 /* "pattern\\/". Remove the final backslash if it hasn't
590 char *p
= (char *) &dirname
[dirlen
- 1];
592 while (p
> dirname
&& p
[-1] == '\\') --p
;
593 if ((&dirname
[dirlen
] - p
) & 1)
595 *(char *) &dirname
[--dirlen
] = '\0';
596 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
599 int val
= __glob (dirname
, flags
| GLOB_MARK
, errfunc
, pglob
);
601 pglob
->gl_flags
= ((pglob
->gl_flags
& ~GLOB_MARK
)
602 | (flags
& GLOB_MARK
));
603 else if (val
== GLOB_NOMATCH
&& flags
!= orig_flags
)
605 /* Make sure globfree (&dirs); is a nop. */
606 dirs
.gl_pathv
= NULL
;
608 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
616 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && dirname
[0] == '~')
618 if (dirname
[1] == '\0' || dirname
[1] == '/'
619 || (!(flags
& GLOB_NOESCAPE
) && dirname
[1] == '\\'
620 && (dirname
[2] == '\0' || dirname
[2] == '/')))
622 /* Look up home directory. */
623 char *home_dir
= getenv ("HOME");
624 int malloc_home_dir
= 0;
625 if (home_dir
== NULL
|| home_dir
[0] == '\0')
628 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
629 preference to HOME, because the user can change HOME. */
630 const char *home_drive
= getenv ("HOMEDRIVE");
631 const char *home_path
= getenv ("HOMEPATH");
633 if (home_drive
!= NULL
&& home_path
!= NULL
)
635 size_t home_drive_len
= strlen (home_drive
);
636 size_t home_path_len
= strlen (home_path
);
637 char *mem
= alloca (home_drive_len
+ home_path_len
+ 1);
639 memcpy (mem
, home_drive
, home_drive_len
);
640 memcpy (mem
+ home_drive_len
, home_path
, home_path_len
+ 1);
644 home_dir
= "c:/users/default"; /* poor default */
649 struct scratch_buffer s
;
650 scratch_buffer_init (&s
);
654 err
= __getlogin_r (s
.data
, s
.length
);
657 # if defined HAVE_GETPWNAM_R || defined _LIBC
658 size_t ssize
= strlen (s
.data
) + 1;
659 char *sdata
= s
.data
;
660 err
= getpwnam_r (sdata
, &pwbuf
, sdata
+ ssize
,
661 s
.length
- ssize
, &p
);
663 p
= getpwnam (s
.data
);
670 if (!scratch_buffer_grow (&s
))
672 retval
= GLOB_NOSPACE
;
678 home_dir
= strdup (p
->pw_dir
);
681 scratch_buffer_free (&s
);
682 if (err
== 0 && home_dir
== NULL
)
684 retval
= GLOB_NOSPACE
;
687 #endif /* WINDOWS32 */
689 if (home_dir
== NULL
|| home_dir
[0] == '\0')
691 if (__glibc_unlikely (malloc_home_dir
))
693 if (flags
& GLOB_TILDE_CHECK
)
695 retval
= GLOB_NOMATCH
;
700 home_dir
= (char *) "~"; /* No luck. */
704 /* Now construct the full directory. */
705 if (dirname
[1] == '\0')
707 if (__glibc_unlikely (malloc_dirname
))
711 dirlen
= strlen (dirname
);
712 malloc_dirname
= malloc_home_dir
;
717 size_t home_len
= strlen (home_dir
);
718 int use_alloca
= glob_use_alloca (alloca_used
, home_len
+ dirlen
);
720 newp
= alloca_account (home_len
+ dirlen
, alloca_used
);
723 newp
= malloc (home_len
+ dirlen
);
726 if (__glibc_unlikely (malloc_home_dir
))
728 retval
= GLOB_NOSPACE
;
733 mempcpy (mempcpy (newp
, home_dir
, home_len
),
734 &dirname
[1], dirlen
);
736 if (__glibc_unlikely (malloc_dirname
))
740 dirlen
+= home_len
- 1;
741 malloc_dirname
= !use_alloca
;
743 if (__glibc_unlikely (malloc_home_dir
))
746 dirname_modified
= 1;
751 /* Recognize ~user as a shorthand for the specified user's home
753 char *end_name
= strchr (dirname
, '/');
755 int malloc_user_name
= 0;
756 char *unescape
= NULL
;
758 if (!(flags
& GLOB_NOESCAPE
))
760 if (end_name
== NULL
)
762 unescape
= strchr (dirname
, '\\');
764 end_name
= strchr (unescape
, '\0');
767 unescape
= memchr (dirname
, '\\', end_name
- dirname
);
769 if (end_name
== NULL
)
770 user_name
= dirname
+ 1;
774 if (glob_use_alloca (alloca_used
, end_name
- dirname
))
775 newp
= alloca_account (end_name
- dirname
, alloca_used
);
778 newp
= malloc (end_name
- dirname
);
781 retval
= GLOB_NOSPACE
;
784 malloc_user_name
= 1;
786 if (unescape
!= NULL
)
788 char *p
= mempcpy (newp
, dirname
+ 1,
789 unescape
- dirname
- 1);
791 while (q
!= end_name
)
795 if (q
+ 1 == end_name
)
797 /* "~fo\\o\\" unescape to user_name "foo\\",
798 but "~fo\\o\\/" unescape to user_name
800 if (filename
== NULL
)
811 *((char *) mempcpy (newp
, dirname
+ 1, end_name
- dirname
- 1))
816 /* Look up specific user's home directory. */
819 struct scratch_buffer pwtmpbuf
;
820 scratch_buffer_init (&pwtmpbuf
);
822 # if defined HAVE_GETPWNAM_R || defined _LIBC
825 while (getpwnam_r (user_name
, &pwbuf
,
826 pwtmpbuf
.data
, pwtmpbuf
.length
, &p
)
829 if (!scratch_buffer_grow (&pwtmpbuf
))
831 retval
= GLOB_NOSPACE
;
836 p
= getpwnam (user_name
);
839 if (__glibc_unlikely (malloc_user_name
))
842 /* If we found a home directory use this. */
845 size_t home_len
= strlen (p
->pw_dir
);
846 size_t rest_len
= end_name
== NULL
? 0 : strlen (end_name
);
847 /* dirname contains end_name; we can't free it now. */
849 (__glibc_unlikely (malloc_dirname
) ? dirname
: NULL
);
854 if (glob_use_alloca (alloca_used
, home_len
+ rest_len
+ 1))
855 dirname
= alloca_account (home_len
+ rest_len
+ 1,
859 dirname
= malloc (home_len
+ rest_len
+ 1);
863 scratch_buffer_free (&pwtmpbuf
);
864 retval
= GLOB_NOSPACE
;
869 d
= mempcpy (dirname
, p
->pw_dir
, home_len
);
870 if (end_name
!= NULL
)
871 d
= mempcpy (d
, end_name
, rest_len
);
876 dirlen
= home_len
+ rest_len
;
877 dirname_modified
= 1;
881 if (flags
& GLOB_TILDE_CHECK
)
883 /* We have to regard it as an error if we cannot find the
885 retval
= GLOB_NOMATCH
;
889 scratch_buffer_free (&pwtmpbuf
);
891 #else /* WINDOWS32 */
892 /* On native Windows, access to a user's home directory
893 (via GetUserProfileDirectory) or to a user's environment
894 variables (via ExpandEnvironmentStringsForUser) requires
895 the credentials of the user. Therefore we cannot support
896 the ~user syntax on this platform.
897 Handling ~user specially (and treat it like plain ~) if
898 user is getenv ("USERNAME") would not be a good idea,
899 since it would make people think that ~user is supported
901 if (flags
& GLOB_TILDE_CHECK
)
903 retval
= GLOB_NOMATCH
;
906 #endif /* WINDOWS32 */
910 /* Now test whether we looked for "~" or "~NAME". In this case we
911 can give the answer now. */
912 if (filename
== NULL
)
914 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
917 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
920 free (pglob
->gl_pathv
);
921 pglob
->gl_pathv
= NULL
;
923 retval
= GLOB_NOSPACE
;
927 new_gl_pathv
= realloc (pglob
->gl_pathv
,
928 (newcount
+ 2) * sizeof (char *));
929 if (new_gl_pathv
== NULL
)
931 pglob
->gl_pathv
= new_gl_pathv
;
933 if (flags
& GLOB_MARK
&& is_dir (dirname
, flags
, pglob
))
936 pglob
->gl_pathv
[newcount
] = malloc (dirlen
+ 2);
937 if (pglob
->gl_pathv
[newcount
] == NULL
)
939 p
= mempcpy (pglob
->gl_pathv
[newcount
], dirname
, dirlen
);
942 if (__glibc_unlikely (malloc_dirname
))
947 if (__glibc_unlikely (malloc_dirname
))
948 pglob
->gl_pathv
[newcount
] = dirname
;
951 pglob
->gl_pathv
[newcount
] = strdup (dirname
);
952 if (pglob
->gl_pathv
[newcount
] == NULL
)
956 pglob
->gl_pathv
[++newcount
] = NULL
;
958 pglob
->gl_flags
= flags
;
963 meta
= __glob_pattern_type (dirname
, !(flags
& GLOB_NOESCAPE
));
964 /* meta is 1 if correct glob pattern containing metacharacters.
965 If meta has bit (1 << 2) set, it means there was an unterminated
966 [ which we handle the same, using fnmatch. Broken unterminated
967 pattern bracket expressions ought to be rare enough that it is
968 not worth special casing them, fnmatch will do the right thing. */
969 if (meta
& (GLOBPAT_SPECIAL
| GLOBPAT_BRACKET
))
971 /* The directory name contains metacharacters, so we
972 have to glob for the directory, and then glob for
973 the pattern in each directory found. */
976 if (!(flags
& GLOB_NOESCAPE
) && dirlen
> 0 && dirname
[dirlen
- 1] == '\\')
978 /* "foo\\/bar". Remove the final backslash from dirname
979 if it has not been quoted. */
980 char *p
= (char *) &dirname
[dirlen
- 1];
982 while (p
> dirname
&& p
[-1] == '\\') --p
;
983 if ((&dirname
[dirlen
] - p
) & 1)
984 *(char *) &dirname
[--dirlen
] = '\0';
987 if (__glibc_unlikely ((flags
& GLOB_ALTDIRFUNC
) != 0))
989 /* Use the alternative access functions also in the recursive
991 dirs
.gl_opendir
= pglob
->gl_opendir
;
992 dirs
.gl_readdir
= pglob
->gl_readdir
;
993 dirs
.gl_closedir
= pglob
->gl_closedir
;
994 dirs
.gl_stat
= pglob
->gl_stat
;
995 dirs
.gl_lstat
= pglob
->gl_lstat
;
998 status
= __glob (dirname
,
999 ((flags
& (GLOB_ERR
| GLOB_NOESCAPE
| GLOB_ALTDIRFUNC
))
1000 | GLOB_NOSORT
| GLOB_ONLYDIR
),
1004 if ((flags
& GLOB_NOCHECK
) == 0 || status
!= GLOB_NOMATCH
)
1012 /* We have successfully globbed the preceding directory name.
1013 For each name we found, call glob_in_dir on it and FILENAME,
1014 appending the results to PGLOB. */
1015 for (i
= 0; i
< dirs
.gl_pathc
; ++i
)
1019 old_pathc
= pglob
->gl_pathc
;
1020 status
= glob_in_dir (filename
, dirs
.gl_pathv
[i
],
1021 ((flags
| GLOB_APPEND
)
1022 & ~(GLOB_NOCHECK
| GLOB_NOMAGIC
)),
1023 errfunc
, pglob
, alloca_used
);
1024 if (status
== GLOB_NOMATCH
)
1025 /* No matches in this directory. Try the next. */
1032 pglob
->gl_pathc
= 0;
1037 /* Stick the directory on the front of each name. */
1038 if (prefix_array (dirs
.gl_pathv
[i
],
1039 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1040 pglob
->gl_pathc
- old_pathc
))
1044 pglob
->gl_pathc
= 0;
1045 retval
= GLOB_NOSPACE
;
1050 flags
|= GLOB_MAGCHAR
;
1052 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1053 But if we have not found any matching entry and the GLOB_NOCHECK
1054 flag was set we must return the input pattern itself. */
1055 if (pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1059 if (flags
& GLOB_NOCHECK
)
1061 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
1062 char **new_gl_pathv
;
1064 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
1068 retval
= GLOB_NOSPACE
;
1072 new_gl_pathv
= realloc (pglob
->gl_pathv
,
1073 (newcount
+ 2) * sizeof (char *));
1074 if (new_gl_pathv
== NULL
)
1076 pglob
->gl_pathv
= new_gl_pathv
;
1078 pglob
->gl_pathv
[newcount
] = strdup (pattern
);
1079 if (pglob
->gl_pathv
[newcount
] == NULL
)
1083 pglob
->gl_pathc
= 0;
1084 retval
= GLOB_NOSPACE
;
1091 pglob
->gl_pathv
[newcount
] = NULL
;
1092 pglob
->gl_flags
= flags
;
1097 retval
= GLOB_NOMATCH
;
1106 size_t old_pathc
= pglob
->gl_pathc
;
1107 int orig_flags
= flags
;
1109 if (meta
& GLOBPAT_BACKSLASH
)
1111 char *p
= strchr (dirname
, '\\'), *q
;
1112 /* We need to unescape the dirname string. It is certainly
1113 allocated by alloca, as otherwise filename would be NULL
1114 or dirname wouldn't contain backslashes. */
1127 while (*p
++ != '\0');
1128 dirname_modified
= 1;
1130 if (dirname_modified
)
1131 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
1132 status
= glob_in_dir (filename
, dirname
, flags
, errfunc
, pglob
,
1136 if (status
== GLOB_NOMATCH
&& flags
!= orig_flags
1137 && pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1139 /* Make sure globfree (&dirs); is a nop. */
1140 dirs
.gl_pathv
= NULL
;
1150 /* Stick the directory on the front of each name. */
1151 if (prefix_array (dirname
,
1152 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1153 pglob
->gl_pathc
- old_pathc
))
1156 pglob
->gl_pathc
= 0;
1157 retval
= GLOB_NOSPACE
;
1163 if (flags
& GLOB_MARK
)
1165 /* Append slashes to directory names. */
1168 for (i
= oldcount
; i
< pglob
->gl_pathc
+ pglob
->gl_offs
; ++i
)
1169 if (is_dir (pglob
->gl_pathv
[i
], flags
, pglob
))
1171 size_t len
= strlen (pglob
->gl_pathv
[i
]) + 2;
1172 char *new = realloc (pglob
->gl_pathv
[i
], len
);
1176 pglob
->gl_pathc
= 0;
1177 retval
= GLOB_NOSPACE
;
1180 strcpy (&new[len
- 2], "/");
1181 pglob
->gl_pathv
[i
] = new;
1185 if (!(flags
& GLOB_NOSORT
))
1187 /* Sort the vector. */
1188 qsort (&pglob
->gl_pathv
[oldcount
],
1189 pglob
->gl_pathc
+ pglob
->gl_offs
- oldcount
,
1190 sizeof (char *), collated_compare
);
1194 if (__glibc_unlikely (malloc_dirname
))
1199 #if defined _LIBC && !defined __glob
1200 versioned_symbol (libc
, __glob
, glob
, GLIBC_2_27
);
1201 libc_hidden_ver (__glob
, glob
)
1205 /* Do a collated comparison of A and B. */
1207 collated_compare (const void *a
, const void *b
)
1209 char *const *ps1
= a
; char *s1
= *ps1
;
1210 char *const *ps2
= b
; char *s2
= *ps2
;
1218 return strcoll (s1
, s2
);
1222 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1223 elements in place. Return nonzero if out of memory, zero if successful.
1224 A slash is inserted between DIRNAME and each elt of ARRAY,
1225 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1227 prefix_array (const char *dirname
, char **array
, size_t n
)
1230 size_t dirlen
= strlen (dirname
);
1231 char dirsep_char
= '/';
1233 if (dirlen
== 1 && dirname
[0] == '/')
1234 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1235 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1238 #if defined __MSDOS__ || defined WINDOWS32
1241 if (dirname
[dirlen
- 1] == '/' && dirname
[dirlen
- 2] == ':')
1242 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1244 else if (dirname
[dirlen
- 1] == ':')
1246 /* DIRNAME is "d:". Use ':' instead of '/'. */
1253 for (i
= 0; i
< n
; ++i
)
1255 size_t eltlen
= strlen (array
[i
]) + 1;
1256 char *new = malloc (dirlen
+ 1 + eltlen
);
1265 char *endp
= mempcpy (new, dirname
, dirlen
);
1266 *endp
++ = dirsep_char
;
1267 mempcpy (endp
, array
[i
], eltlen
);
1276 /* Like 'glob', but PATTERN is a final pathname component,
1277 and matches are searched for in DIRECTORY.
1278 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1279 The GLOB_APPEND flag is assumed to be set (always appends). */
1281 glob_in_dir (const char *pattern
, const char *directory
, int flags
,
1282 int (*errfunc
) (const char *, int),
1283 glob_t
*pglob
, size_t alloca_used
)
1285 size_t dirlen
= strlen (directory
);
1286 void *stream
= NULL
;
1287 struct scratch_buffer s
;
1288 scratch_buffer_init (&s
);
1289 # define GLOBNAMES_MEMBERS(nnames) \
1290 struct globnames *next; size_t count; char *name[nnames];
1291 struct globnames
{ GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER
) };
1292 struct { GLOBNAMES_MEMBERS (64) } init_names_buf
;
1293 struct globnames
*init_names
= (struct globnames
*) &init_names_buf
;
1294 struct globnames
*names
= init_names
;
1295 struct globnames
*names_alloca
= init_names
;
1302 alloca_used
+= sizeof init_names_buf
;
1304 init_names
->next
= NULL
;
1305 init_names
->count
= ((sizeof init_names_buf
1306 - offsetof (struct globnames
, name
))
1307 / sizeof init_names
->name
[0]);
1309 meta
= __glob_pattern_type (pattern
, !(flags
& GLOB_NOESCAPE
));
1310 if (meta
== GLOBPAT_NONE
&& (flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
1312 /* We need not do any tests. The PATTERN contains no meta
1313 characters and we must not return an error therefore the
1314 result will always contain exactly one name. */
1315 flags
|= GLOB_NOCHECK
;
1317 else if (meta
== GLOBPAT_NONE
)
1319 size_t patlen
= strlen (pattern
);
1321 bool alloca_fullname
1322 = (! size_add_wrapv (dirlen
+ 1, patlen
+ 1, &fullsize
)
1323 && glob_use_alloca (alloca_used
, fullsize
));
1325 if (alloca_fullname
)
1326 fullname
= alloca_account (fullsize
, alloca_used
);
1329 fullname
= malloc (fullsize
);
1330 if (fullname
== NULL
)
1331 return GLOB_NOSPACE
;
1334 mempcpy (mempcpy (mempcpy (fullname
, directory
, dirlen
),
1336 pattern
, patlen
+ 1);
1337 if (glob_lstat (pglob
, flags
, fullname
) == 0
1338 || errno
== EOVERFLOW
)
1339 /* We found this file to be existing. Now tell the rest
1340 of the function to copy this name into the result. */
1341 flags
|= GLOB_NOCHECK
;
1343 if (__glibc_unlikely (!alloca_fullname
))
1348 stream
= (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1349 ? (*pglob
->gl_opendir
) (directory
)
1350 : opendir (directory
));
1353 if (errno
!= ENOTDIR
1354 && ((errfunc
!= NULL
&& (*errfunc
) (directory
, errno
))
1355 || (flags
& GLOB_ERR
)))
1356 return GLOB_ABORTED
;
1360 int dfd
= dirfd (stream
);
1361 int fnm_flags
= ((!(flags
& GLOB_PERIOD
) ? FNM_PERIOD
: 0)
1362 | ((flags
& GLOB_NOESCAPE
) ? FNM_NOESCAPE
: 0));
1363 flags
|= GLOB_MAGCHAR
;
1367 struct readdir_result d
;
1369 if (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0))
1370 d
= convert_dirent (GL_READDIR (pglob
, stream
));
1373 #ifdef COMPILE_GLOB64
1374 d
= convert_dirent (__readdir (stream
));
1376 d
= convert_dirent64 (__readdir64 (stream
));
1383 /* If we shall match only directories use the information
1384 provided by the dirent call if possible. */
1385 if (flags
& GLOB_ONLYDIR
)
1386 switch (readdir_result_type (d
))
1390 case DT_LNK
: case DT_UNKNOWN
:
1391 /* The filesystem was too lazy to give us a hint,
1392 so we have to do it the hard way. */
1393 if (__glibc_unlikely (dfd
< 0 || flags
& GLOB_ALTDIRFUNC
))
1395 size_t namelen
= strlen (d
.name
);
1396 size_t need
= dirlen
+ 1 + namelen
+ 1;
1398 && !scratch_buffer_set_array_size (&s
, need
, 1))
1400 char *p
= mempcpy (s
.data
, directory
, dirlen
);
1403 memcpy (p
, d
.name
, namelen
+ 1);
1404 if (! is_dir (s
.data
, flags
, pglob
))
1410 if (! (GLOB_FSTATAT64 (dfd
, d
.name
, &st64
, 0) == 0
1411 && S_ISDIR (st64
.st_mode
)))
1416 if (fnmatch (pattern
, d
.name
, fnm_flags
) == 0)
1418 if (cur
== names
->count
)
1420 struct globnames
*newnames
;
1421 size_t count
= names
->count
* 2;
1422 size_t nameoff
= offsetof (struct globnames
, name
);
1423 size_t size
= FLEXSIZEOF (struct globnames
, name
,
1424 count
* sizeof (char *));
1425 if ((SIZE_MAX
- nameoff
) / 2 / sizeof (char *)
1428 if (glob_use_alloca (alloca_used
, size
))
1429 newnames
= names_alloca
1430 = alloca_account (size
, alloca_used
);
1431 else if ((newnames
= malloc (size
))
1434 newnames
->count
= count
;
1435 newnames
->next
= names
;
1439 names
->name
[cur
] = strdup (d
.name
);
1440 if (names
->name
[cur
] == NULL
)
1444 if (SIZE_MAX
- pglob
->gl_offs
<= nfound
)
1451 if (nfound
== 0 && (flags
& GLOB_NOCHECK
))
1453 size_t len
= strlen (pattern
);
1455 names
->name
[cur
] = malloc (len
+ 1);
1456 if (names
->name
[cur
] == NULL
)
1458 *((char *) mempcpy (names
->name
[cur
++], pattern
, len
)) = '\0';
1461 result
= GLOB_NOMATCH
;
1464 char **new_gl_pathv
;
1467 if (SIZE_MAX
/ sizeof (char *) - pglob
->gl_pathc
1468 < pglob
->gl_offs
+ nfound
+ 1)
1472 = realloc (pglob
->gl_pathv
,
1473 (pglob
->gl_pathc
+ pglob
->gl_offs
+ nfound
+ 1)
1476 if (new_gl_pathv
== NULL
)
1481 struct globnames
*old
= names
;
1482 for (size_t i
= 0; i
< cur
; ++i
)
1483 free (names
->name
[i
]);
1484 names
= names
->next
;
1485 /* NB: we will not leak memory here if we exit without
1486 freeing the current block assigned to OLD. At least
1487 the very first block is always allocated on the stack
1488 and this is the block assigned to OLD here. */
1491 assert (old
== init_names
);
1495 if (old
== names_alloca
)
1496 names_alloca
= names
;
1500 result
= GLOB_NOSPACE
;
1506 struct globnames
*old
= names
;
1507 for (size_t i
= 0; i
< cur
; ++i
)
1508 new_gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
++]
1510 names
= names
->next
;
1511 /* NB: we will not leak memory here if we exit without
1512 freeing the current block assigned to OLD. At least
1513 the very first block is always allocated on the stack
1514 and this is the block assigned to OLD here. */
1517 assert (old
== init_names
);
1521 if (old
== names_alloca
)
1522 names_alloca
= names
;
1527 pglob
->gl_pathv
= new_gl_pathv
;
1529 pglob
->gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
] = NULL
;
1531 pglob
->gl_flags
= flags
;
1538 if (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
))
1539 (*pglob
->gl_closedir
) (stream
);
1545 scratch_buffer_free (&s
);