1 /* Copyright (C) 1991-2021 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/>. */
21 #include <sys/types.h>
29 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
45 # define strdup(str) __strdup (str)
46 # define sysconf(id) __sysconf (id)
47 # define closedir(dir) __closedir (dir)
48 # define opendir(name) __opendir (name)
49 # define readdir(str) __readdir64 (str)
50 # define getpwnam_r(name, bufp, buf, len, res) \
51 __getpwnam_r (name, bufp, buf, len, res)
52 # define struct_stat64 struct stat64
53 # define FLEXIBLE_ARRAY_MEMBER
54 # include <shlib-compat.h>
57 # define __getlogin_r(buf, len) getlogin_r (buf, len)
58 # define __lstat64(fname, buf) lstat (fname, buf)
59 # define __stat64(fname, buf) stat (fname, buf)
60 # define struct_stat64 struct stat
62 # define __alloca alloca
64 # define __readdir readdir
65 # define COMPILE_GLOB64
70 #include <flexmember.h>
71 #include <glob_internal.h>
72 #include <scratch_buffer.h>
74 static const char *next_brace_sub (const char *begin
, int flags
) __THROWNL
;
76 typedef uint_fast8_t dirent_type
;
78 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
79 /* Any distinct values will do here.
80 Undef any existing macros out of the way. */
89 /* A representation of a directory entry which does not depend on the
90 layout of struct dirent, or the size of ino_t. */
94 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
99 /* Initialize and return type member of struct readdir_result. */
101 readdir_result_type (struct readdir_result d
)
103 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
104 # define D_TYPE_TO_RESULT(source) (source)->d_type,
107 # define D_TYPE_TO_RESULT(source)
112 /* Construct an initializer for a struct readdir_result object from a
113 struct dirent *. No copy of the name is made. */
114 #define READDIR_RESULT_INITIALIZER(source) \
117 D_TYPE_TO_RESULT (source) \
120 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
121 type safety if an old interface version needs to be supported. */
123 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
126 /* Extract name and type from directory entry. No copy of the name is
127 made. If SOURCE is NULL, result name is NULL. Keep in sync with
128 convert_dirent64 below. */
129 static struct readdir_result
130 convert_dirent (const struct dirent
*source
)
134 struct readdir_result result
= { NULL
, };
137 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
141 #ifndef COMPILE_GLOB64
142 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
143 sync with convert_dirent above. */
144 static struct readdir_result
145 convert_dirent64 (const struct dirent64
*source
)
149 struct readdir_result result
= { NULL
, };
152 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
158 /* The results of opendir() in this file are not used with dirfd and fchdir,
159 and we do not leak fds to any single-threaded code that could use stdio,
160 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
161 FIXME - if the kernel ever adds support for multi-thread safety for
162 avoiding standard fds, then we should use opendir_safer. */
163 # ifdef GNULIB_defined_opendir
166 # ifdef GNULIB_defined_closedir
170 /* Just use malloc. */
171 # define __libc_use_alloca(n) false
172 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
173 # define extend_alloca_account(buf, len, newlen, avar) \
174 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
178 glob_lstat (glob_t
*pglob
, int flags
, const char *fullname
)
180 /* Use on glob-lstat-compat.c to provide a compat symbol which does not
181 use lstat / gl_lstat. */
183 # define GL_LSTAT gl_stat
184 # define LSTAT64 __stat64
186 # define GL_LSTAT gl_lstat
187 # define LSTAT64 __lstat64
195 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
196 ? pglob
->GL_LSTAT (fullname
, &ust
.st
)
197 : LSTAT64 (fullname
, &ust
.st64
));
200 /* Set *R = A + B. Return true if the answer is mathematically
201 incorrect due to overflow; in this case, *R is the low order
202 bits of the correct answer. */
205 size_add_wrapv (size_t a
, size_t b
, size_t *r
)
207 #if 5 <= __GNUC__ && !defined __ICC
208 return __builtin_add_overflow (a
, b
, r
);
216 glob_use_alloca (size_t alloca_used
, size_t len
)
219 return (!size_add_wrapv (alloca_used
, len
, &size
)
220 && __libc_use_alloca (size
));
223 static int glob_in_dir (const char *pattern
, const char *directory
,
224 int flags
, int (*errfunc
) (const char *, int),
225 glob_t
*pglob
, size_t alloca_used
);
226 static int prefix_array (const char *prefix
, char **array
, size_t n
) __THROWNL
;
227 static int collated_compare (const void *, const void *) __THROWNL
;
230 /* Return true if FILENAME is a directory or a symbolic link to a directory.
231 Use FLAGS and PGLOB to resolve the filename. */
233 is_dir (char const *filename
, int flags
, glob_t
const *pglob
)
237 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
238 ? pglob
->gl_stat (filename
, &st
) == 0 && S_ISDIR (st
.st_mode
)
239 : __stat64 (filename
, &st64
) == 0 && S_ISDIR (st64
.st_mode
));
242 /* Find the end of the sub-pattern in a brace expression. */
244 next_brace_sub (const char *cp
, int flags
)
248 if ((flags
& GLOB_NOESCAPE
) == 0 && *cp
== '\\')
256 if ((*cp
== '}' && depth
-- == 0) || (*cp
== ',' && depth
== 0))
263 return *cp
!= '\0' ? cp
: NULL
;
266 #ifndef GLOB_ATTRIBUTE
267 # define GLOB_ATTRIBUTE
270 /* Do glob searching for PATTERN, placing results in PGLOB.
271 The bits defined above may be set in FLAGS.
272 If a directory cannot be opened or read and ERRFUNC is not nil,
273 it is called with the pathname that caused the error, and the
274 'errno' value from the failing call; if it returns non-zero
275 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
276 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
277 Otherwise, 'glob' returns zero. */
280 __glob (const char *pattern
, int flags
, int (*errfunc
) (const char *, int),
283 const char *filename
;
284 char *dirname
= NULL
;
289 int dirname_modified
;
290 int malloc_dirname
= 0;
293 size_t alloca_used
= 0;
295 if (pattern
== NULL
|| pglob
== NULL
|| (flags
& ~__GLOB_FLAGS
) != 0)
297 __set_errno (EINVAL
);
301 /* POSIX requires all slashes to be matched. This means that with
302 a trailing slash we must match only directories. */
303 if (pattern
[0] && pattern
[strlen (pattern
) - 1] == '/')
304 flags
|= GLOB_ONLYDIR
;
306 if (!(flags
& GLOB_DOOFFS
))
307 /* Have to do this so 'globfree' knows where to start freeing. It
308 also makes all the code that uses gl_offs simpler. */
311 if (!(flags
& GLOB_APPEND
))
314 if (!(flags
& GLOB_DOOFFS
))
315 pglob
->gl_pathv
= NULL
;
320 if (pglob
->gl_offs
>= ~((size_t) 0) / sizeof (char *))
323 pglob
->gl_pathv
= (char **) malloc ((pglob
->gl_offs
+ 1)
325 if (pglob
->gl_pathv
== NULL
)
328 for (i
= 0; i
<= pglob
->gl_offs
; ++i
)
329 pglob
->gl_pathv
[i
] = NULL
;
333 if (flags
& GLOB_BRACE
)
337 if (flags
& GLOB_NOESCAPE
)
338 begin
= strchr (pattern
, '{');
350 if (*begin
== '\\' && begin
[1] != '\0')
352 else if (*begin
== '{')
361 /* Allocate working buffer large enough for our work. Note that
362 we have at least an opening and closing brace. */
370 size_t pattern_len
= strlen (pattern
) - 1;
371 int alloca_onealt
= glob_use_alloca (alloca_used
, pattern_len
);
373 onealt
= alloca_account (pattern_len
, alloca_used
);
376 onealt
= malloc (pattern_len
);
381 /* We know the prefix for all sub-patterns. */
382 alt_start
= mempcpy (onealt
, pattern
, begin
- pattern
);
384 /* Find the first sub-pattern and at the same time find the
385 rest after the closing brace. */
386 next
= next_brace_sub (begin
+ 1, flags
);
389 /* It is an invalid expression. */
391 if (__glibc_unlikely (!alloca_onealt
))
393 flags
&= ~GLOB_BRACE
;
397 /* Now find the end of the whole brace expression. */
401 rest
= next_brace_sub (rest
+ 1, flags
);
403 /* It is an illegal expression. */
406 /* Please note that we now can be sure the brace expression
408 rest_len
= strlen (++rest
) + 1;
410 /* We have a brace expression. BEGIN points to the opening {,
411 NEXT points past the terminator of the first element, and END
412 points past the final }. We will accumulate result names from
413 recursive runs for each brace alternative in the buffer using
415 firstc
= pglob
->gl_pathc
;
422 /* Construct the new glob expression. */
423 mempcpy (mempcpy (alt_start
, p
, next
- p
), rest
, rest_len
);
425 result
= __glob (onealt
,
426 ((flags
& ~(GLOB_NOCHECK
| GLOB_NOMAGIC
))
430 /* If we got an error, return it. */
431 if (result
&& result
!= GLOB_NOMATCH
)
433 if (__glibc_unlikely (!alloca_onealt
))
435 if (!(flags
& GLOB_APPEND
))
444 /* We saw the last entry. */
448 next
= next_brace_sub (p
, flags
);
449 assert (next
!= NULL
);
452 if (__glibc_unlikely (!alloca_onealt
))
455 if (pglob
->gl_pathc
!= firstc
)
456 /* We found some entries. */
458 else if (!(flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
464 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
466 /* Find the filename. */
467 filename
= strrchr (pattern
, '/');
469 #if defined __MSDOS__ || defined WINDOWS32
470 /* The case of "d:pattern". Since ':' is not allowed in
471 file names, we can safely assume that wherever it
472 happens in pattern, it signals the filename part. This
473 is so we could some day support patterns like "[a-z]:foo". */
474 if (filename
== NULL
)
475 filename
= strchr (pattern
, ':');
476 #endif /* __MSDOS__ || WINDOWS32 */
478 dirname_modified
= 0;
479 if (filename
== NULL
)
481 /* This can mean two things: a simple name or "~name". The latter
482 case is nothing but a notation for a directory. */
483 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && pattern
[0] == '~')
485 dirname
= (char *) pattern
;
486 dirlen
= strlen (pattern
);
488 /* Set FILENAME to NULL as a special flag. This is ugly but
489 other solutions would require much more code. We test for
490 this special case below. */
495 if (__glibc_unlikely (pattern
[0] == '\0'))
497 dirs
.gl_pathv
= NULL
;
502 dirname
= (char *) ".";
506 else if (filename
== pattern
507 || (filename
== pattern
+ 1 && pattern
[0] == '\\'
508 && (flags
& GLOB_NOESCAPE
) == 0))
510 /* "/pattern" or "\\/pattern". */
511 dirname
= (char *) "/";
518 dirlen
= filename
- pattern
;
519 #if defined __MSDOS__ || defined WINDOWS32
521 || (filename
> pattern
+ 1 && filename
[-1] == ':'))
526 drive_spec
= __alloca (dirlen
+ 1);
527 *((char *) mempcpy (drive_spec
, pattern
, dirlen
)) = '\0';
528 /* For now, disallow wildcards in the drive spec, to
529 prevent infinite recursion in glob. */
530 if (__glob_pattern_p (drive_spec
, !(flags
& GLOB_NOESCAPE
)))
532 /* If this is "d:pattern", we need to copy ':' to DIRNAME
533 as well. If it's "d:/pattern", don't remove the slash
534 from "d:/", since "d:" and "d:/" are not the same.*/
538 if (glob_use_alloca (alloca_used
, dirlen
+ 1))
539 newp
= alloca_account (dirlen
+ 1, alloca_used
);
542 newp
= malloc (dirlen
+ 1);
547 *((char *) mempcpy (newp
, pattern
, dirlen
)) = '\0';
551 #if defined __MSDOS__ || defined WINDOWS32
552 bool drive_root
= (dirlen
> 1
553 && (dirname
[dirlen
- 1] == ':'
554 || (dirlen
> 2 && dirname
[dirlen
- 2] == ':'
555 && dirname
[dirlen
- 1] == '/')));
557 bool drive_root
= false;
560 if (filename
[0] == '\0' && dirlen
> 1 && !drive_root
)
561 /* "pattern/". Expand "pattern", appending slashes. */
563 int orig_flags
= flags
;
564 if (!(flags
& GLOB_NOESCAPE
) && dirname
[dirlen
- 1] == '\\')
566 /* "pattern\\/". Remove the final backslash if it hasn't
568 char *p
= (char *) &dirname
[dirlen
- 1];
570 while (p
> dirname
&& p
[-1] == '\\') --p
;
571 if ((&dirname
[dirlen
] - p
) & 1)
573 *(char *) &dirname
[--dirlen
] = '\0';
574 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
577 int val
= __glob (dirname
, flags
| GLOB_MARK
, errfunc
, pglob
);
579 pglob
->gl_flags
= ((pglob
->gl_flags
& ~GLOB_MARK
)
580 | (flags
& GLOB_MARK
));
581 else if (val
== GLOB_NOMATCH
&& flags
!= orig_flags
)
583 /* Make sure globfree (&dirs); is a nop. */
584 dirs
.gl_pathv
= NULL
;
586 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
594 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && dirname
[0] == '~')
596 if (dirname
[1] == '\0' || dirname
[1] == '/'
597 || (!(flags
& GLOB_NOESCAPE
) && dirname
[1] == '\\'
598 && (dirname
[2] == '\0' || dirname
[2] == '/')))
600 /* Look up home directory. */
601 char *home_dir
= getenv ("HOME");
602 int malloc_home_dir
= 0;
603 if (home_dir
== NULL
|| home_dir
[0] == '\0')
606 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
607 preference to HOME, because the user can change HOME. */
608 const char *home_drive
= getenv ("HOMEDRIVE");
609 const char *home_path
= getenv ("HOMEPATH");
611 if (home_drive
!= NULL
&& home_path
!= NULL
)
613 size_t home_drive_len
= strlen (home_drive
);
614 size_t home_path_len
= strlen (home_path
);
615 char *mem
= alloca (home_drive_len
+ home_path_len
+ 1);
617 memcpy (mem
, home_drive
, home_drive_len
);
618 memcpy (mem
+ home_drive_len
, home_path
, home_path_len
+ 1);
622 home_dir
= "c:/users/default"; /* poor default */
627 struct scratch_buffer s
;
628 scratch_buffer_init (&s
);
632 err
= __getlogin_r (s
.data
, s
.length
);
635 # if defined HAVE_GETPWNAM_R || defined _LIBC
636 size_t ssize
= strlen (s
.data
) + 1;
637 char *sdata
= s
.data
;
638 err
= getpwnam_r (sdata
, &pwbuf
, sdata
+ ssize
,
639 s
.length
- ssize
, &p
);
641 p
= getpwnam (s
.data
);
648 if (!scratch_buffer_grow (&s
))
650 retval
= GLOB_NOSPACE
;
656 home_dir
= strdup (p
->pw_dir
);
659 scratch_buffer_free (&s
);
660 if (err
== 0 && home_dir
== NULL
)
662 retval
= GLOB_NOSPACE
;
665 #endif /* WINDOWS32 */
667 if (home_dir
== NULL
|| home_dir
[0] == '\0')
669 if (__glibc_unlikely (malloc_home_dir
))
671 if (flags
& GLOB_TILDE_CHECK
)
673 retval
= GLOB_NOMATCH
;
678 home_dir
= (char *) "~"; /* No luck. */
682 /* Now construct the full directory. */
683 if (dirname
[1] == '\0')
685 if (__glibc_unlikely (malloc_dirname
))
689 dirlen
= strlen (dirname
);
690 malloc_dirname
= malloc_home_dir
;
695 size_t home_len
= strlen (home_dir
);
696 int use_alloca
= glob_use_alloca (alloca_used
, home_len
+ dirlen
);
698 newp
= alloca_account (home_len
+ dirlen
, alloca_used
);
701 newp
= malloc (home_len
+ dirlen
);
704 if (__glibc_unlikely (malloc_home_dir
))
706 retval
= GLOB_NOSPACE
;
711 mempcpy (mempcpy (newp
, home_dir
, home_len
),
712 &dirname
[1], dirlen
);
714 if (__glibc_unlikely (malloc_dirname
))
718 dirlen
+= home_len
- 1;
719 malloc_dirname
= !use_alloca
;
721 if (__glibc_unlikely (malloc_home_dir
))
724 dirname_modified
= 1;
729 char *end_name
= strchr (dirname
, '/');
731 int malloc_user_name
= 0;
732 char *unescape
= NULL
;
734 if (!(flags
& GLOB_NOESCAPE
))
736 if (end_name
== NULL
)
738 unescape
= strchr (dirname
, '\\');
740 end_name
= strchr (unescape
, '\0');
743 unescape
= memchr (dirname
, '\\', end_name
- dirname
);
745 if (end_name
== NULL
)
746 user_name
= dirname
+ 1;
750 if (glob_use_alloca (alloca_used
, end_name
- dirname
))
751 newp
= alloca_account (end_name
- dirname
, alloca_used
);
754 newp
= malloc (end_name
- dirname
);
757 retval
= GLOB_NOSPACE
;
760 malloc_user_name
= 1;
762 if (unescape
!= NULL
)
764 char *p
= mempcpy (newp
, dirname
+ 1,
765 unescape
- dirname
- 1);
767 while (q
!= end_name
)
771 if (q
+ 1 == end_name
)
773 /* "~fo\\o\\" unescape to user_name "foo\\",
774 but "~fo\\o\\/" unescape to user_name
776 if (filename
== NULL
)
787 *((char *) mempcpy (newp
, dirname
+ 1, end_name
- dirname
- 1))
792 /* Look up specific user's home directory. */
795 struct scratch_buffer pwtmpbuf
;
796 scratch_buffer_init (&pwtmpbuf
);
798 # if defined HAVE_GETPWNAM_R || defined _LIBC
801 while (getpwnam_r (user_name
, &pwbuf
,
802 pwtmpbuf
.data
, pwtmpbuf
.length
, &p
)
805 if (!scratch_buffer_grow (&pwtmpbuf
))
807 retval
= GLOB_NOSPACE
;
812 p
= getpwnam (user_name
);
815 if (__glibc_unlikely (malloc_user_name
))
818 /* If we found a home directory use this. */
821 size_t home_len
= strlen (p
->pw_dir
);
822 size_t rest_len
= end_name
== NULL
? 0 : strlen (end_name
);
824 bool use_alloca
= glob_use_alloca (alloca_used
,
825 home_len
+ rest_len
+ 1);
828 newp
= alloca_account (home_len
+ rest_len
+ 1, alloca_used
);
831 newp
= malloc (home_len
+ rest_len
+ 1);
834 scratch_buffer_free (&pwtmpbuf
);
835 retval
= GLOB_NOSPACE
;
839 d
= mempcpy (newp
, p
->pw_dir
, home_len
);
840 if (end_name
!= NULL
)
841 d
= mempcpy (d
, end_name
, rest_len
);
844 if (__glibc_unlikely (malloc_dirname
))
847 malloc_dirname
= !use_alloca
;
849 dirlen
= home_len
+ rest_len
;
850 dirname_modified
= 1;
854 if (flags
& GLOB_TILDE_CHECK
)
856 /* We have to regard it as an error if we cannot find the
858 retval
= GLOB_NOMATCH
;
862 scratch_buffer_free (&pwtmpbuf
);
864 #endif /* !WINDOWS32 */
868 /* Now test whether we looked for "~" or "~NAME". In this case we
869 can give the answer now. */
870 if (filename
== NULL
)
872 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
875 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
878 free (pglob
->gl_pathv
);
879 pglob
->gl_pathv
= NULL
;
881 retval
= GLOB_NOSPACE
;
885 new_gl_pathv
= realloc (pglob
->gl_pathv
,
886 (newcount
+ 2) * sizeof (char *));
887 if (new_gl_pathv
== NULL
)
889 pglob
->gl_pathv
= new_gl_pathv
;
891 if (flags
& GLOB_MARK
&& is_dir (dirname
, flags
, pglob
))
894 pglob
->gl_pathv
[newcount
] = malloc (dirlen
+ 2);
895 if (pglob
->gl_pathv
[newcount
] == NULL
)
897 p
= mempcpy (pglob
->gl_pathv
[newcount
], dirname
, dirlen
);
900 if (__glibc_unlikely (malloc_dirname
))
905 if (__glibc_unlikely (malloc_dirname
))
906 pglob
->gl_pathv
[newcount
] = dirname
;
909 pglob
->gl_pathv
[newcount
] = strdup (dirname
);
910 if (pglob
->gl_pathv
[newcount
] == NULL
)
914 pglob
->gl_pathv
[++newcount
] = NULL
;
916 pglob
->gl_flags
= flags
;
921 meta
= __glob_pattern_type (dirname
, !(flags
& GLOB_NOESCAPE
));
922 /* meta is 1 if correct glob pattern containing metacharacters.
923 If meta has bit (1 << 2) set, it means there was an unterminated
924 [ which we handle the same, using fnmatch. Broken unterminated
925 pattern bracket expressions ought to be rare enough that it is
926 not worth special casing them, fnmatch will do the right thing. */
927 if (meta
& (GLOBPAT_SPECIAL
| GLOBPAT_BRACKET
))
929 /* The directory name contains metacharacters, so we
930 have to glob for the directory, and then glob for
931 the pattern in each directory found. */
934 if (!(flags
& GLOB_NOESCAPE
) && dirlen
> 0 && dirname
[dirlen
- 1] == '\\')
936 /* "foo\\/bar". Remove the final backslash from dirname
937 if it has not been quoted. */
938 char *p
= (char *) &dirname
[dirlen
- 1];
940 while (p
> dirname
&& p
[-1] == '\\') --p
;
941 if ((&dirname
[dirlen
] - p
) & 1)
942 *(char *) &dirname
[--dirlen
] = '\0';
945 if (__glibc_unlikely ((flags
& GLOB_ALTDIRFUNC
) != 0))
947 /* Use the alternative access functions also in the recursive
949 dirs
.gl_opendir
= pglob
->gl_opendir
;
950 dirs
.gl_readdir
= pglob
->gl_readdir
;
951 dirs
.gl_closedir
= pglob
->gl_closedir
;
952 dirs
.gl_stat
= pglob
->gl_stat
;
953 dirs
.gl_lstat
= pglob
->gl_lstat
;
956 status
= __glob (dirname
,
957 ((flags
& (GLOB_ERR
| GLOB_NOESCAPE
| GLOB_ALTDIRFUNC
))
958 | GLOB_NOSORT
| GLOB_ONLYDIR
),
962 if ((flags
& GLOB_NOCHECK
) == 0 || status
!= GLOB_NOMATCH
)
970 /* We have successfully globbed the preceding directory name.
971 For each name we found, call glob_in_dir on it and FILENAME,
972 appending the results to PGLOB. */
973 for (i
= 0; i
< dirs
.gl_pathc
; ++i
)
977 old_pathc
= pglob
->gl_pathc
;
978 status
= glob_in_dir (filename
, dirs
.gl_pathv
[i
],
979 ((flags
| GLOB_APPEND
)
980 & ~(GLOB_NOCHECK
| GLOB_NOMAGIC
)),
981 errfunc
, pglob
, alloca_used
);
982 if (status
== GLOB_NOMATCH
)
983 /* No matches in this directory. Try the next. */
995 /* Stick the directory on the front of each name. */
996 if (prefix_array (dirs
.gl_pathv
[i
],
997 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
998 pglob
->gl_pathc
- old_pathc
))
1002 pglob
->gl_pathc
= 0;
1003 retval
= GLOB_NOSPACE
;
1008 flags
|= GLOB_MAGCHAR
;
1010 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1011 But if we have not found any matching entry and the GLOB_NOCHECK
1012 flag was set we must return the input pattern itself. */
1013 if (pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1017 if (flags
& GLOB_NOCHECK
)
1019 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
1020 char **new_gl_pathv
;
1022 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
1026 retval
= GLOB_NOSPACE
;
1030 new_gl_pathv
= realloc (pglob
->gl_pathv
,
1031 (newcount
+ 2) * sizeof (char *));
1032 if (new_gl_pathv
== NULL
)
1034 pglob
->gl_pathv
= new_gl_pathv
;
1036 pglob
->gl_pathv
[newcount
] = strdup (pattern
);
1037 if (pglob
->gl_pathv
[newcount
] == NULL
)
1041 pglob
->gl_pathc
= 0;
1042 retval
= GLOB_NOSPACE
;
1049 pglob
->gl_pathv
[newcount
] = NULL
;
1050 pglob
->gl_flags
= flags
;
1055 retval
= GLOB_NOMATCH
;
1064 size_t old_pathc
= pglob
->gl_pathc
;
1065 int orig_flags
= flags
;
1067 if (meta
& GLOBPAT_BACKSLASH
)
1069 char *p
= strchr (dirname
, '\\'), *q
;
1070 /* We need to unescape the dirname string. It is certainly
1071 allocated by alloca, as otherwise filename would be NULL
1072 or dirname wouldn't contain backslashes. */
1085 while (*p
++ != '\0');
1086 dirname_modified
= 1;
1088 if (dirname_modified
)
1089 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
1090 status
= glob_in_dir (filename
, dirname
, flags
, errfunc
, pglob
,
1094 if (status
== GLOB_NOMATCH
&& flags
!= orig_flags
1095 && pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1097 /* Make sure globfree (&dirs); is a nop. */
1098 dirs
.gl_pathv
= NULL
;
1108 /* Stick the directory on the front of each name. */
1109 if (prefix_array (dirname
,
1110 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1111 pglob
->gl_pathc
- old_pathc
))
1114 pglob
->gl_pathc
= 0;
1115 retval
= GLOB_NOSPACE
;
1121 if (flags
& GLOB_MARK
)
1123 /* Append slashes to directory names. */
1126 for (i
= oldcount
; i
< pglob
->gl_pathc
+ pglob
->gl_offs
; ++i
)
1127 if (is_dir (pglob
->gl_pathv
[i
], flags
, pglob
))
1129 size_t len
= strlen (pglob
->gl_pathv
[i
]) + 2;
1130 char *new = realloc (pglob
->gl_pathv
[i
], len
);
1134 pglob
->gl_pathc
= 0;
1135 retval
= GLOB_NOSPACE
;
1138 strcpy (&new[len
- 2], "/");
1139 pglob
->gl_pathv
[i
] = new;
1143 if (!(flags
& GLOB_NOSORT
))
1145 /* Sort the vector. */
1146 qsort (&pglob
->gl_pathv
[oldcount
],
1147 pglob
->gl_pathc
+ pglob
->gl_offs
- oldcount
,
1148 sizeof (char *), collated_compare
);
1152 if (__glibc_unlikely (malloc_dirname
))
1157 #if defined _LIBC && !defined __glob
1158 versioned_symbol (libc
, __glob
, glob
, GLIBC_2_27
);
1159 libc_hidden_ver (__glob
, glob
)
1163 /* Do a collated comparison of A and B. */
1165 collated_compare (const void *a
, const void *b
)
1167 char *const *ps1
= a
; char *s1
= *ps1
;
1168 char *const *ps2
= b
; char *s2
= *ps2
;
1176 return strcoll (s1
, s2
);
1180 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1181 elements in place. Return nonzero if out of memory, zero if successful.
1182 A slash is inserted between DIRNAME and each elt of ARRAY,
1183 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1185 prefix_array (const char *dirname
, char **array
, size_t n
)
1188 size_t dirlen
= strlen (dirname
);
1189 char dirsep_char
= '/';
1191 if (dirlen
== 1 && dirname
[0] == '/')
1192 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1193 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1196 #if defined __MSDOS__ || defined WINDOWS32
1199 if (dirname
[dirlen
- 1] == '/' && dirname
[dirlen
- 2] == ':')
1200 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1202 else if (dirname
[dirlen
- 1] == ':')
1204 /* DIRNAME is "d:". Use ':' instead of '/'. */
1211 for (i
= 0; i
< n
; ++i
)
1213 size_t eltlen
= strlen (array
[i
]) + 1;
1214 char *new = malloc (dirlen
+ 1 + eltlen
);
1223 char *endp
= mempcpy (new, dirname
, dirlen
);
1224 *endp
++ = dirsep_char
;
1225 mempcpy (endp
, array
[i
], eltlen
);
1234 /* Like 'glob', but PATTERN is a final pathname component,
1235 and matches are searched for in DIRECTORY.
1236 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1237 The GLOB_APPEND flag is assumed to be set (always appends). */
1239 glob_in_dir (const char *pattern
, const char *directory
, int flags
,
1240 int (*errfunc
) (const char *, int),
1241 glob_t
*pglob
, size_t alloca_used
)
1243 size_t dirlen
= strlen (directory
);
1244 void *stream
= NULL
;
1245 # define GLOBNAMES_MEMBERS(nnames) \
1246 struct globnames *next; size_t count; char *name[nnames];
1247 struct globnames
{ GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER
) };
1248 struct { GLOBNAMES_MEMBERS (64) } init_names_buf
;
1249 struct globnames
*init_names
= (struct globnames
*) &init_names_buf
;
1250 struct globnames
*names
= init_names
;
1251 struct globnames
*names_alloca
= init_names
;
1258 alloca_used
+= sizeof init_names_buf
;
1260 init_names
->next
= NULL
;
1261 init_names
->count
= ((sizeof init_names_buf
1262 - offsetof (struct globnames
, name
))
1263 / sizeof init_names
->name
[0]);
1265 meta
= __glob_pattern_type (pattern
, !(flags
& GLOB_NOESCAPE
));
1266 if (meta
== GLOBPAT_NONE
&& (flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
1268 /* We need not do any tests. The PATTERN contains no meta
1269 characters and we must not return an error therefore the
1270 result will always contain exactly one name. */
1271 flags
|= GLOB_NOCHECK
;
1273 else if (meta
== GLOBPAT_NONE
)
1275 size_t patlen
= strlen (pattern
);
1277 bool alloca_fullname
1278 = (! size_add_wrapv (dirlen
+ 1, patlen
+ 1, &fullsize
)
1279 && glob_use_alloca (alloca_used
, fullsize
));
1281 if (alloca_fullname
)
1282 fullname
= alloca_account (fullsize
, alloca_used
);
1285 fullname
= malloc (fullsize
);
1286 if (fullname
== NULL
)
1287 return GLOB_NOSPACE
;
1290 mempcpy (mempcpy (mempcpy (fullname
, directory
, dirlen
),
1292 pattern
, patlen
+ 1);
1293 if (glob_lstat (pglob
, flags
, fullname
) == 0
1294 || errno
== EOVERFLOW
)
1295 /* We found this file to be existing. Now tell the rest
1296 of the function to copy this name into the result. */
1297 flags
|= GLOB_NOCHECK
;
1299 if (__glibc_unlikely (!alloca_fullname
))
1304 stream
= (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1305 ? (*pglob
->gl_opendir
) (directory
)
1306 : opendir (directory
));
1309 if (errno
!= ENOTDIR
1310 && ((errfunc
!= NULL
&& (*errfunc
) (directory
, errno
))
1311 || (flags
& GLOB_ERR
)))
1312 return GLOB_ABORTED
;
1316 int fnm_flags
= ((!(flags
& GLOB_PERIOD
) ? FNM_PERIOD
: 0)
1317 | ((flags
& GLOB_NOESCAPE
) ? FNM_NOESCAPE
: 0));
1318 flags
|= GLOB_MAGCHAR
;
1322 struct readdir_result d
;
1324 if (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0))
1325 d
= convert_dirent (GL_READDIR (pglob
, stream
));
1328 #ifdef COMPILE_GLOB64
1329 d
= convert_dirent (__readdir (stream
));
1331 d
= convert_dirent64 (__readdir64 (stream
));
1338 /* If we shall match only directories use the information
1339 provided by the dirent call if possible. */
1340 if (flags
& GLOB_ONLYDIR
)
1341 switch (readdir_result_type (d
))
1343 case DT_DIR
: case DT_LNK
: case DT_UNKNOWN
: break;
1347 if (fnmatch (pattern
, d
.name
, fnm_flags
) == 0)
1349 if (cur
== names
->count
)
1351 struct globnames
*newnames
;
1352 size_t count
= names
->count
* 2;
1353 size_t nameoff
= offsetof (struct globnames
, name
);
1354 size_t size
= FLEXSIZEOF (struct globnames
, name
,
1355 count
* sizeof (char *));
1356 if ((SIZE_MAX
- nameoff
) / 2 / sizeof (char *)
1359 if (glob_use_alloca (alloca_used
, size
))
1360 newnames
= names_alloca
1361 = alloca_account (size
, alloca_used
);
1362 else if ((newnames
= malloc (size
))
1365 newnames
->count
= count
;
1366 newnames
->next
= names
;
1370 names
->name
[cur
] = strdup (d
.name
);
1371 if (names
->name
[cur
] == NULL
)
1375 if (SIZE_MAX
- pglob
->gl_offs
<= nfound
)
1382 if (nfound
== 0 && (flags
& GLOB_NOCHECK
))
1384 size_t len
= strlen (pattern
);
1386 names
->name
[cur
] = malloc (len
+ 1);
1387 if (names
->name
[cur
] == NULL
)
1389 *((char *) mempcpy (names
->name
[cur
++], pattern
, len
)) = '\0';
1392 result
= GLOB_NOMATCH
;
1395 char **new_gl_pathv
;
1398 if (SIZE_MAX
/ sizeof (char *) - pglob
->gl_pathc
1399 < pglob
->gl_offs
+ nfound
+ 1)
1403 = realloc (pglob
->gl_pathv
,
1404 (pglob
->gl_pathc
+ pglob
->gl_offs
+ nfound
+ 1)
1407 if (new_gl_pathv
== NULL
)
1412 struct globnames
*old
= names
;
1413 for (size_t i
= 0; i
< cur
; ++i
)
1414 free (names
->name
[i
]);
1415 names
= names
->next
;
1416 /* NB: we will not leak memory here if we exit without
1417 freeing the current block assigned to OLD. At least
1418 the very first block is always allocated on the stack
1419 and this is the block assigned to OLD here. */
1422 assert (old
== init_names
);
1426 if (old
== names_alloca
)
1427 names_alloca
= names
;
1431 result
= GLOB_NOSPACE
;
1437 struct globnames
*old
= names
;
1438 for (size_t i
= 0; i
< cur
; ++i
)
1439 new_gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
++]
1441 names
= names
->next
;
1442 /* NB: we will not leak memory here if we exit without
1443 freeing the current block assigned to OLD. At least
1444 the very first block is always allocated on the stack
1445 and this is the block assigned to OLD here. */
1448 assert (old
== init_names
);
1452 if (old
== names_alloca
)
1453 names_alloca
= names
;
1458 pglob
->gl_pathv
= new_gl_pathv
;
1460 pglob
->gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
] = NULL
;
1462 pglob
->gl_flags
= flags
;
1469 if (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
))
1470 (*pglob
->gl_closedir
) (stream
);