1 /* Copyright (C) 1991-2020 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)
53 # define __lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
56 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
58 # define struct_stat64 struct stat64
59 # define FLEXIBLE_ARRAY_MEMBER
60 # include <shlib-compat.h>
63 # define __getlogin_r(buf, len) getlogin_r (buf, len)
64 # define __lstat64(fname, buf) lstat (fname, buf)
65 # define __stat64(fname, buf) stat (fname, buf)
66 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
67 # define struct_stat64 struct stat
69 # define __alloca alloca
71 # define __readdir readdir
72 # define COMPILE_GLOB64
77 #include <flexmember.h>
78 #include <glob_internal.h>
79 #include <scratch_buffer.h>
81 static const char *next_brace_sub (const char *begin
, int flags
) __THROWNL
;
83 typedef uint_fast8_t dirent_type
;
85 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
86 /* Any distinct values will do here.
87 Undef any existing macros out of the way. */
96 /* A representation of a directory entry which does not depend on the
97 layout of struct dirent, or the size of ino_t. */
101 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
106 /* Initialize and return type member of struct readdir_result. */
108 readdir_result_type (struct readdir_result d
)
110 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
111 # define D_TYPE_TO_RESULT(source) (source)->d_type,
114 # define D_TYPE_TO_RESULT(source)
119 /* Construct an initializer for a struct readdir_result object from a
120 struct dirent *. No copy of the name is made. */
121 #define READDIR_RESULT_INITIALIZER(source) \
124 D_TYPE_TO_RESULT (source) \
127 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
128 type safety if an old interface version needs to be supported. */
130 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
133 /* Extract name and type from directory entry. No copy of the name is
134 made. If SOURCE is NULL, result name is NULL. Keep in sync with
135 convert_dirent64 below. */
136 static struct readdir_result
137 convert_dirent (const struct dirent
*source
)
141 struct readdir_result result
= { NULL
, };
144 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
148 #ifndef COMPILE_GLOB64
149 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
150 sync with convert_dirent above. */
151 static struct readdir_result
152 convert_dirent64 (const struct dirent64
*source
)
156 struct readdir_result result
= { NULL
, };
159 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
165 /* The results of opendir() in this file are not used with dirfd and fchdir,
166 and we do not leak fds to any single-threaded code that could use stdio,
167 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
168 FIXME - if the kernel ever adds support for multi-thread safety for
169 avoiding standard fds, then we should use opendir_safer. */
170 # ifdef GNULIB_defined_opendir
173 # ifdef GNULIB_defined_closedir
177 /* Just use malloc. */
178 # define __libc_use_alloca(n) false
179 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
180 # define extend_alloca_account(buf, len, newlen, avar) \
181 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
185 glob_lstat (glob_t
*pglob
, int flags
, const char *fullname
)
187 /* Use on glob-lstat-compat.c to provide a compat symbol which does not
188 use lstat / gl_lstat. */
190 # define GL_LSTAT gl_stat
191 # define LSTAT64 __stat64
193 # define GL_LSTAT gl_lstat
194 # define LSTAT64 __lstat64
202 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
203 ? pglob
->GL_LSTAT (fullname
, &ust
.st
)
204 : LSTAT64 (fullname
, &ust
.st64
));
207 /* Set *R = A + B. Return true if the answer is mathematically
208 incorrect due to overflow; in this case, *R is the low order
209 bits of the correct answer. */
212 size_add_wrapv (size_t a
, size_t b
, size_t *r
)
214 #if 5 <= __GNUC__ && !defined __ICC
215 return __builtin_add_overflow (a
, b
, r
);
223 glob_use_alloca (size_t alloca_used
, size_t len
)
226 return (!size_add_wrapv (alloca_used
, len
, &size
)
227 && __libc_use_alloca (size
));
230 static int glob_in_dir (const char *pattern
, const char *directory
,
231 int flags
, int (*errfunc
) (const char *, int),
232 glob_t
*pglob
, size_t alloca_used
);
233 static int prefix_array (const char *prefix
, char **array
, size_t n
) __THROWNL
;
234 static int collated_compare (const void *, const void *) __THROWNL
;
237 /* Return true if FILENAME is a directory or a symbolic link to a directory.
238 Use FLAGS and PGLOB to resolve the filename. */
240 is_dir (char const *filename
, int flags
, glob_t
const *pglob
)
244 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
245 ? pglob
->gl_stat (filename
, &st
) == 0 && S_ISDIR (st
.st_mode
)
246 : __stat64 (filename
, &st64
) == 0 && S_ISDIR (st64
.st_mode
));
249 /* Find the end of the sub-pattern in a brace expression. */
251 next_brace_sub (const char *cp
, int flags
)
255 if ((flags
& GLOB_NOESCAPE
) == 0 && *cp
== '\\')
263 if ((*cp
== '}' && depth
-- == 0) || (*cp
== ',' && depth
== 0))
270 return *cp
!= '\0' ? cp
: NULL
;
273 #ifndef GLOB_ATTRIBUTE
274 # define GLOB_ATTRIBUTE
277 /* Do glob searching for PATTERN, placing results in PGLOB.
278 The bits defined above may be set in FLAGS.
279 If a directory cannot be opened or read and ERRFUNC is not nil,
280 it is called with the pathname that caused the error, and the
281 'errno' value from the failing call; if it returns non-zero
282 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
283 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
284 Otherwise, 'glob' returns zero. */
287 __glob (const char *pattern
, int flags
, int (*errfunc
) (const char *, int),
290 const char *filename
;
291 char *dirname
= NULL
;
296 int dirname_modified
;
297 int malloc_dirname
= 0;
300 size_t alloca_used
= 0;
302 if (pattern
== NULL
|| pglob
== NULL
|| (flags
& ~__GLOB_FLAGS
) != 0)
304 __set_errno (EINVAL
);
308 /* POSIX requires all slashes to be matched. This means that with
309 a trailing slash we must match only directories. */
310 if (pattern
[0] && pattern
[strlen (pattern
) - 1] == '/')
311 flags
|= GLOB_ONLYDIR
;
313 if (!(flags
& GLOB_DOOFFS
))
314 /* Have to do this so 'globfree' knows where to start freeing. It
315 also makes all the code that uses gl_offs simpler. */
318 if (!(flags
& GLOB_APPEND
))
321 if (!(flags
& GLOB_DOOFFS
))
322 pglob
->gl_pathv
= NULL
;
327 if (pglob
->gl_offs
>= ~((size_t) 0) / sizeof (char *))
330 pglob
->gl_pathv
= (char **) malloc ((pglob
->gl_offs
+ 1)
332 if (pglob
->gl_pathv
== NULL
)
335 for (i
= 0; i
<= pglob
->gl_offs
; ++i
)
336 pglob
->gl_pathv
[i
] = NULL
;
340 if (flags
& GLOB_BRACE
)
344 if (flags
& GLOB_NOESCAPE
)
345 begin
= strchr (pattern
, '{');
357 if (*begin
== '\\' && begin
[1] != '\0')
359 else if (*begin
== '{')
368 /* Allocate working buffer large enough for our work. Note that
369 we have at least an opening and closing brace. */
377 size_t pattern_len
= strlen (pattern
) - 1;
378 int alloca_onealt
= glob_use_alloca (alloca_used
, pattern_len
);
380 onealt
= alloca_account (pattern_len
, alloca_used
);
383 onealt
= malloc (pattern_len
);
388 /* We know the prefix for all sub-patterns. */
389 alt_start
= mempcpy (onealt
, pattern
, begin
- pattern
);
391 /* Find the first sub-pattern and at the same time find the
392 rest after the closing brace. */
393 next
= next_brace_sub (begin
+ 1, flags
);
396 /* It is an invalid expression. */
398 if (__glibc_unlikely (!alloca_onealt
))
400 flags
&= ~GLOB_BRACE
;
404 /* Now find the end of the whole brace expression. */
408 rest
= next_brace_sub (rest
+ 1, flags
);
410 /* It is an illegal expression. */
413 /* Please note that we now can be sure the brace expression
415 rest_len
= strlen (++rest
) + 1;
417 /* We have a brace expression. BEGIN points to the opening {,
418 NEXT points past the terminator of the first element, and END
419 points past the final }. We will accumulate result names from
420 recursive runs for each brace alternative in the buffer using
422 firstc
= pglob
->gl_pathc
;
429 /* Construct the new glob expression. */
430 mempcpy (mempcpy (alt_start
, p
, next
- p
), rest
, rest_len
);
432 result
= __glob (onealt
,
433 ((flags
& ~(GLOB_NOCHECK
| GLOB_NOMAGIC
))
437 /* If we got an error, return it. */
438 if (result
&& result
!= GLOB_NOMATCH
)
440 if (__glibc_unlikely (!alloca_onealt
))
442 if (!(flags
& GLOB_APPEND
))
451 /* We saw the last entry. */
455 next
= next_brace_sub (p
, flags
);
456 assert (next
!= NULL
);
459 if (__glibc_unlikely (!alloca_onealt
))
462 if (pglob
->gl_pathc
!= firstc
)
463 /* We found some entries. */
465 else if (!(flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
471 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
473 /* Find the filename. */
474 filename
= strrchr (pattern
, '/');
476 #if defined __MSDOS__ || defined WINDOWS32
477 /* The case of "d:pattern". Since ':' is not allowed in
478 file names, we can safely assume that wherever it
479 happens in pattern, it signals the filename part. This
480 is so we could some day support patterns like "[a-z]:foo". */
481 if (filename
== NULL
)
482 filename
= strchr (pattern
, ':');
483 #endif /* __MSDOS__ || WINDOWS32 */
485 dirname_modified
= 0;
486 if (filename
== NULL
)
488 /* This can mean two things: a simple name or "~name". The latter
489 case is nothing but a notation for a directory. */
490 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && pattern
[0] == '~')
492 dirname
= (char *) pattern
;
493 dirlen
= strlen (pattern
);
495 /* Set FILENAME to NULL as a special flag. This is ugly but
496 other solutions would require much more code. We test for
497 this special case below. */
502 if (__glibc_unlikely (pattern
[0] == '\0'))
504 dirs
.gl_pathv
= NULL
;
509 dirname
= (char *) ".";
513 else if (filename
== pattern
514 || (filename
== pattern
+ 1 && pattern
[0] == '\\'
515 && (flags
& GLOB_NOESCAPE
) == 0))
517 /* "/pattern" or "\\/pattern". */
518 dirname
= (char *) "/";
525 dirlen
= filename
- pattern
;
526 #if defined __MSDOS__ || defined WINDOWS32
528 || (filename
> pattern
+ 1 && filename
[-1] == ':'))
533 drive_spec
= __alloca (dirlen
+ 1);
534 *((char *) mempcpy (drive_spec
, pattern
, dirlen
)) = '\0';
535 /* For now, disallow wildcards in the drive spec, to
536 prevent infinite recursion in glob. */
537 if (__glob_pattern_p (drive_spec
, !(flags
& GLOB_NOESCAPE
)))
539 /* If this is "d:pattern", we need to copy ':' to DIRNAME
540 as well. If it's "d:/pattern", don't remove the slash
541 from "d:/", since "d:" and "d:/" are not the same.*/
545 if (glob_use_alloca (alloca_used
, dirlen
+ 1))
546 newp
= alloca_account (dirlen
+ 1, alloca_used
);
549 newp
= malloc (dirlen
+ 1);
554 *((char *) mempcpy (newp
, pattern
, dirlen
)) = '\0';
558 #if defined __MSDOS__ || defined WINDOWS32
559 bool drive_root
= (dirlen
> 1
560 && (dirname
[dirlen
- 1] == ':'
561 || (dirlen
> 2 && dirname
[dirlen
- 2] == ':'
562 && dirname
[dirlen
- 1] == '/')));
564 bool drive_root
= false;
567 if (filename
[0] == '\0' && dirlen
> 1 && !drive_root
)
568 /* "pattern/". Expand "pattern", appending slashes. */
570 int orig_flags
= flags
;
571 if (!(flags
& GLOB_NOESCAPE
) && dirname
[dirlen
- 1] == '\\')
573 /* "pattern\\/". Remove the final backslash if it hasn't
575 char *p
= (char *) &dirname
[dirlen
- 1];
577 while (p
> dirname
&& p
[-1] == '\\') --p
;
578 if ((&dirname
[dirlen
] - p
) & 1)
580 *(char *) &dirname
[--dirlen
] = '\0';
581 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
584 int val
= __glob (dirname
, flags
| GLOB_MARK
, errfunc
, pglob
);
586 pglob
->gl_flags
= ((pglob
->gl_flags
& ~GLOB_MARK
)
587 | (flags
& GLOB_MARK
));
588 else if (val
== GLOB_NOMATCH
&& flags
!= orig_flags
)
590 /* Make sure globfree (&dirs); is a nop. */
591 dirs
.gl_pathv
= NULL
;
593 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
601 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && dirname
[0] == '~')
603 if (dirname
[1] == '\0' || dirname
[1] == '/'
604 || (!(flags
& GLOB_NOESCAPE
) && dirname
[1] == '\\'
605 && (dirname
[2] == '\0' || dirname
[2] == '/')))
607 /* Look up home directory. */
608 char *home_dir
= getenv ("HOME");
609 int malloc_home_dir
= 0;
610 if (home_dir
== NULL
|| home_dir
[0] == '\0')
613 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
614 preference to HOME, because the user can change HOME. */
615 const char *home_drive
= getenv ("HOMEDRIVE");
616 const char *home_path
= getenv ("HOMEPATH");
618 if (home_drive
!= NULL
&& home_path
!= NULL
)
620 size_t home_drive_len
= strlen (home_drive
);
621 size_t home_path_len
= strlen (home_path
);
622 char *mem
= alloca (home_drive_len
+ home_path_len
+ 1);
624 memcpy (mem
, home_drive
, home_drive_len
);
625 memcpy (mem
+ home_drive_len
, home_path
, home_path_len
+ 1);
629 home_dir
= "c:/users/default"; /* poor default */
634 struct scratch_buffer s
;
635 scratch_buffer_init (&s
);
639 err
= __getlogin_r (s
.data
, s
.length
);
642 # if defined HAVE_GETPWNAM_R || defined _LIBC
643 size_t ssize
= strlen (s
.data
) + 1;
644 char *sdata
= s
.data
;
645 err
= getpwnam_r (sdata
, &pwbuf
, sdata
+ ssize
,
646 s
.length
- ssize
, &p
);
648 p
= getpwnam (s
.data
);
655 if (!scratch_buffer_grow (&s
))
657 retval
= GLOB_NOSPACE
;
663 home_dir
= strdup (p
->pw_dir
);
666 scratch_buffer_free (&s
);
667 if (err
== 0 && home_dir
== NULL
)
669 retval
= GLOB_NOSPACE
;
672 #endif /* WINDOWS32 */
674 if (home_dir
== NULL
|| home_dir
[0] == '\0')
676 if (__glibc_unlikely (malloc_home_dir
))
678 if (flags
& GLOB_TILDE_CHECK
)
680 retval
= GLOB_NOMATCH
;
685 home_dir
= (char *) "~"; /* No luck. */
689 /* Now construct the full directory. */
690 if (dirname
[1] == '\0')
692 if (__glibc_unlikely (malloc_dirname
))
696 dirlen
= strlen (dirname
);
697 malloc_dirname
= malloc_home_dir
;
702 size_t home_len
= strlen (home_dir
);
703 int use_alloca
= glob_use_alloca (alloca_used
, home_len
+ dirlen
);
705 newp
= alloca_account (home_len
+ dirlen
, alloca_used
);
708 newp
= malloc (home_len
+ dirlen
);
711 if (__glibc_unlikely (malloc_home_dir
))
713 retval
= GLOB_NOSPACE
;
718 mempcpy (mempcpy (newp
, home_dir
, home_len
),
719 &dirname
[1], dirlen
);
721 if (__glibc_unlikely (malloc_dirname
))
725 dirlen
+= home_len
- 1;
726 malloc_dirname
= !use_alloca
;
728 if (__glibc_unlikely (malloc_home_dir
))
731 dirname_modified
= 1;
736 char *end_name
= strchr (dirname
, '/');
738 int malloc_user_name
= 0;
739 char *unescape
= NULL
;
741 if (!(flags
& GLOB_NOESCAPE
))
743 if (end_name
== NULL
)
745 unescape
= strchr (dirname
, '\\');
747 end_name
= strchr (unescape
, '\0');
750 unescape
= memchr (dirname
, '\\', end_name
- dirname
);
752 if (end_name
== NULL
)
753 user_name
= dirname
+ 1;
757 if (glob_use_alloca (alloca_used
, end_name
- dirname
))
758 newp
= alloca_account (end_name
- dirname
, alloca_used
);
761 newp
= malloc (end_name
- dirname
);
764 retval
= GLOB_NOSPACE
;
767 malloc_user_name
= 1;
769 if (unescape
!= NULL
)
771 char *p
= mempcpy (newp
, dirname
+ 1,
772 unescape
- dirname
- 1);
774 while (q
!= end_name
)
778 if (q
+ 1 == end_name
)
780 /* "~fo\\o\\" unescape to user_name "foo\\",
781 but "~fo\\o\\/" unescape to user_name
783 if (filename
== NULL
)
794 *((char *) mempcpy (newp
, dirname
+ 1, end_name
- dirname
- 1))
799 /* Look up specific user's home directory. */
802 struct scratch_buffer pwtmpbuf
;
803 scratch_buffer_init (&pwtmpbuf
);
805 # if defined HAVE_GETPWNAM_R || defined _LIBC
808 while (getpwnam_r (user_name
, &pwbuf
,
809 pwtmpbuf
.data
, pwtmpbuf
.length
, &p
)
812 if (!scratch_buffer_grow (&pwtmpbuf
))
814 retval
= GLOB_NOSPACE
;
819 p
= getpwnam (user_name
);
822 if (__glibc_unlikely (malloc_user_name
))
825 /* If we found a home directory use this. */
828 size_t home_len
= strlen (p
->pw_dir
);
829 size_t rest_len
= end_name
== NULL
? 0 : strlen (end_name
);
831 bool use_alloca
= glob_use_alloca (alloca_used
,
832 home_len
+ rest_len
+ 1);
835 newp
= alloca_account (home_len
+ rest_len
+ 1, alloca_used
);
838 newp
= malloc (home_len
+ rest_len
+ 1);
841 scratch_buffer_free (&pwtmpbuf
);
842 retval
= GLOB_NOSPACE
;
846 d
= mempcpy (newp
, p
->pw_dir
, home_len
);
847 if (end_name
!= NULL
)
848 d
= mempcpy (d
, end_name
, rest_len
);
851 if (__glibc_unlikely (malloc_dirname
))
854 malloc_dirname
= !use_alloca
;
856 dirlen
= home_len
+ rest_len
;
857 dirname_modified
= 1;
861 if (flags
& GLOB_TILDE_CHECK
)
863 /* We have to regard it as an error if we cannot find the
865 retval
= GLOB_NOMATCH
;
869 scratch_buffer_free (&pwtmpbuf
);
871 #endif /* !WINDOWS32 */
875 /* Now test whether we looked for "~" or "~NAME". In this case we
876 can give the answer now. */
877 if (filename
== NULL
)
879 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
882 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
885 free (pglob
->gl_pathv
);
886 pglob
->gl_pathv
= NULL
;
888 retval
= GLOB_NOSPACE
;
892 new_gl_pathv
= realloc (pglob
->gl_pathv
,
893 (newcount
+ 2) * sizeof (char *));
894 if (new_gl_pathv
== NULL
)
896 pglob
->gl_pathv
= new_gl_pathv
;
898 if (flags
& GLOB_MARK
&& is_dir (dirname
, flags
, pglob
))
901 pglob
->gl_pathv
[newcount
] = malloc (dirlen
+ 2);
902 if (pglob
->gl_pathv
[newcount
] == NULL
)
904 p
= mempcpy (pglob
->gl_pathv
[newcount
], dirname
, dirlen
);
907 if (__glibc_unlikely (malloc_dirname
))
912 if (__glibc_unlikely (malloc_dirname
))
913 pglob
->gl_pathv
[newcount
] = dirname
;
916 pglob
->gl_pathv
[newcount
] = strdup (dirname
);
917 if (pglob
->gl_pathv
[newcount
] == NULL
)
921 pglob
->gl_pathv
[++newcount
] = NULL
;
923 pglob
->gl_flags
= flags
;
928 meta
= __glob_pattern_type (dirname
, !(flags
& GLOB_NOESCAPE
));
929 /* meta is 1 if correct glob pattern containing metacharacters.
930 If meta has bit (1 << 2) set, it means there was an unterminated
931 [ which we handle the same, using fnmatch. Broken unterminated
932 pattern bracket expressions ought to be rare enough that it is
933 not worth special casing them, fnmatch will do the right thing. */
934 if (meta
& (GLOBPAT_SPECIAL
| GLOBPAT_BRACKET
))
936 /* The directory name contains metacharacters, so we
937 have to glob for the directory, and then glob for
938 the pattern in each directory found. */
941 if (!(flags
& GLOB_NOESCAPE
) && dirlen
> 0 && dirname
[dirlen
- 1] == '\\')
943 /* "foo\\/bar". Remove the final backslash from dirname
944 if it has not been quoted. */
945 char *p
= (char *) &dirname
[dirlen
- 1];
947 while (p
> dirname
&& p
[-1] == '\\') --p
;
948 if ((&dirname
[dirlen
] - p
) & 1)
949 *(char *) &dirname
[--dirlen
] = '\0';
952 if (__glibc_unlikely ((flags
& GLOB_ALTDIRFUNC
) != 0))
954 /* Use the alternative access functions also in the recursive
956 dirs
.gl_opendir
= pglob
->gl_opendir
;
957 dirs
.gl_readdir
= pglob
->gl_readdir
;
958 dirs
.gl_closedir
= pglob
->gl_closedir
;
959 dirs
.gl_stat
= pglob
->gl_stat
;
960 dirs
.gl_lstat
= pglob
->gl_lstat
;
963 status
= __glob (dirname
,
964 ((flags
& (GLOB_ERR
| GLOB_NOESCAPE
| GLOB_ALTDIRFUNC
))
965 | GLOB_NOSORT
| GLOB_ONLYDIR
),
969 if ((flags
& GLOB_NOCHECK
) == 0 || status
!= GLOB_NOMATCH
)
977 /* We have successfully globbed the preceding directory name.
978 For each name we found, call glob_in_dir on it and FILENAME,
979 appending the results to PGLOB. */
980 for (i
= 0; i
< dirs
.gl_pathc
; ++i
)
984 old_pathc
= pglob
->gl_pathc
;
985 status
= glob_in_dir (filename
, dirs
.gl_pathv
[i
],
986 ((flags
| GLOB_APPEND
)
987 & ~(GLOB_NOCHECK
| GLOB_NOMAGIC
)),
988 errfunc
, pglob
, alloca_used
);
989 if (status
== GLOB_NOMATCH
)
990 /* No matches in this directory. Try the next. */
1002 /* Stick the directory on the front of each name. */
1003 if (prefix_array (dirs
.gl_pathv
[i
],
1004 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1005 pglob
->gl_pathc
- old_pathc
))
1009 pglob
->gl_pathc
= 0;
1010 retval
= GLOB_NOSPACE
;
1015 flags
|= GLOB_MAGCHAR
;
1017 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1018 But if we have not found any matching entry and the GLOB_NOCHECK
1019 flag was set we must return the input pattern itself. */
1020 if (pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1024 if (flags
& GLOB_NOCHECK
)
1026 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
1027 char **new_gl_pathv
;
1029 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
1033 retval
= GLOB_NOSPACE
;
1037 new_gl_pathv
= realloc (pglob
->gl_pathv
,
1038 (newcount
+ 2) * sizeof (char *));
1039 if (new_gl_pathv
== NULL
)
1041 pglob
->gl_pathv
= new_gl_pathv
;
1043 pglob
->gl_pathv
[newcount
] = strdup (pattern
);
1044 if (pglob
->gl_pathv
[newcount
] == NULL
)
1048 pglob
->gl_pathc
= 0;
1049 retval
= GLOB_NOSPACE
;
1056 pglob
->gl_pathv
[newcount
] = NULL
;
1057 pglob
->gl_flags
= flags
;
1062 retval
= GLOB_NOMATCH
;
1071 size_t old_pathc
= pglob
->gl_pathc
;
1072 int orig_flags
= flags
;
1074 if (meta
& GLOBPAT_BACKSLASH
)
1076 char *p
= strchr (dirname
, '\\'), *q
;
1077 /* We need to unescape the dirname string. It is certainly
1078 allocated by alloca, as otherwise filename would be NULL
1079 or dirname wouldn't contain backslashes. */
1092 while (*p
++ != '\0');
1093 dirname_modified
= 1;
1095 if (dirname_modified
)
1096 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
1097 status
= glob_in_dir (filename
, dirname
, flags
, errfunc
, pglob
,
1101 if (status
== GLOB_NOMATCH
&& flags
!= orig_flags
1102 && pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1104 /* Make sure globfree (&dirs); is a nop. */
1105 dirs
.gl_pathv
= NULL
;
1115 /* Stick the directory on the front of each name. */
1116 if (prefix_array (dirname
,
1117 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1118 pglob
->gl_pathc
- old_pathc
))
1121 pglob
->gl_pathc
= 0;
1122 retval
= GLOB_NOSPACE
;
1128 if (flags
& GLOB_MARK
)
1130 /* Append slashes to directory names. */
1133 for (i
= oldcount
; i
< pglob
->gl_pathc
+ pglob
->gl_offs
; ++i
)
1134 if (is_dir (pglob
->gl_pathv
[i
], flags
, pglob
))
1136 size_t len
= strlen (pglob
->gl_pathv
[i
]) + 2;
1137 char *new = realloc (pglob
->gl_pathv
[i
], len
);
1141 pglob
->gl_pathc
= 0;
1142 retval
= GLOB_NOSPACE
;
1145 strcpy (&new[len
- 2], "/");
1146 pglob
->gl_pathv
[i
] = new;
1150 if (!(flags
& GLOB_NOSORT
))
1152 /* Sort the vector. */
1153 qsort (&pglob
->gl_pathv
[oldcount
],
1154 pglob
->gl_pathc
+ pglob
->gl_offs
- oldcount
,
1155 sizeof (char *), collated_compare
);
1159 if (__glibc_unlikely (malloc_dirname
))
1164 #if defined _LIBC && !defined __glob
1165 versioned_symbol (libc
, __glob
, glob
, GLIBC_2_27
);
1166 libc_hidden_ver (__glob
, glob
)
1170 /* Do a collated comparison of A and B. */
1172 collated_compare (const void *a
, const void *b
)
1174 char *const *ps1
= a
; char *s1
= *ps1
;
1175 char *const *ps2
= b
; char *s2
= *ps2
;
1183 return strcoll (s1
, s2
);
1187 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1188 elements in place. Return nonzero if out of memory, zero if successful.
1189 A slash is inserted between DIRNAME and each elt of ARRAY,
1190 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1192 prefix_array (const char *dirname
, char **array
, size_t n
)
1195 size_t dirlen
= strlen (dirname
);
1196 char dirsep_char
= '/';
1198 if (dirlen
== 1 && dirname
[0] == '/')
1199 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1200 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1203 #if defined __MSDOS__ || defined WINDOWS32
1206 if (dirname
[dirlen
- 1] == '/' && dirname
[dirlen
- 2] == ':')
1207 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1209 else if (dirname
[dirlen
- 1] == ':')
1211 /* DIRNAME is "d:". Use ':' instead of '/'. */
1218 for (i
= 0; i
< n
; ++i
)
1220 size_t eltlen
= strlen (array
[i
]) + 1;
1221 char *new = malloc (dirlen
+ 1 + eltlen
);
1230 char *endp
= mempcpy (new, dirname
, dirlen
);
1231 *endp
++ = dirsep_char
;
1232 mempcpy (endp
, array
[i
], eltlen
);
1241 /* Like 'glob', but PATTERN is a final pathname component,
1242 and matches are searched for in DIRECTORY.
1243 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1244 The GLOB_APPEND flag is assumed to be set (always appends). */
1246 glob_in_dir (const char *pattern
, const char *directory
, int flags
,
1247 int (*errfunc
) (const char *, int),
1248 glob_t
*pglob
, size_t alloca_used
)
1250 size_t dirlen
= strlen (directory
);
1251 void *stream
= NULL
;
1252 # define GLOBNAMES_MEMBERS(nnames) \
1253 struct globnames *next; size_t count; char *name[nnames];
1254 struct globnames
{ GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER
) };
1255 struct { GLOBNAMES_MEMBERS (64) } init_names_buf
;
1256 struct globnames
*init_names
= (struct globnames
*) &init_names_buf
;
1257 struct globnames
*names
= init_names
;
1258 struct globnames
*names_alloca
= init_names
;
1265 alloca_used
+= sizeof init_names_buf
;
1267 init_names
->next
= NULL
;
1268 init_names
->count
= ((sizeof init_names_buf
1269 - offsetof (struct globnames
, name
))
1270 / sizeof init_names
->name
[0]);
1272 meta
= __glob_pattern_type (pattern
, !(flags
& GLOB_NOESCAPE
));
1273 if (meta
== GLOBPAT_NONE
&& (flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
1275 /* We need not do any tests. The PATTERN contains no meta
1276 characters and we must not return an error therefore the
1277 result will always contain exactly one name. */
1278 flags
|= GLOB_NOCHECK
;
1280 else if (meta
== GLOBPAT_NONE
)
1282 size_t patlen
= strlen (pattern
);
1284 bool alloca_fullname
1285 = (! size_add_wrapv (dirlen
+ 1, patlen
+ 1, &fullsize
)
1286 && glob_use_alloca (alloca_used
, fullsize
));
1288 if (alloca_fullname
)
1289 fullname
= alloca_account (fullsize
, alloca_used
);
1292 fullname
= malloc (fullsize
);
1293 if (fullname
== NULL
)
1294 return GLOB_NOSPACE
;
1297 mempcpy (mempcpy (mempcpy (fullname
, directory
, dirlen
),
1299 pattern
, patlen
+ 1);
1300 if (glob_lstat (pglob
, flags
, fullname
) == 0
1301 || errno
== EOVERFLOW
)
1302 /* We found this file to be existing. Now tell the rest
1303 of the function to copy this name into the result. */
1304 flags
|= GLOB_NOCHECK
;
1306 if (__glibc_unlikely (!alloca_fullname
))
1311 stream
= (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1312 ? (*pglob
->gl_opendir
) (directory
)
1313 : opendir (directory
));
1316 if (errno
!= ENOTDIR
1317 && ((errfunc
!= NULL
&& (*errfunc
) (directory
, errno
))
1318 || (flags
& GLOB_ERR
)))
1319 return GLOB_ABORTED
;
1323 int fnm_flags
= ((!(flags
& GLOB_PERIOD
) ? FNM_PERIOD
: 0)
1324 | ((flags
& GLOB_NOESCAPE
) ? FNM_NOESCAPE
: 0));
1325 flags
|= GLOB_MAGCHAR
;
1329 struct readdir_result d
;
1331 if (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0))
1332 d
= convert_dirent (GL_READDIR (pglob
, stream
));
1335 #ifdef COMPILE_GLOB64
1336 d
= convert_dirent (__readdir (stream
));
1338 d
= convert_dirent64 (__readdir64 (stream
));
1345 /* If we shall match only directories use the information
1346 provided by the dirent call if possible. */
1347 if (flags
& GLOB_ONLYDIR
)
1348 switch (readdir_result_type (d
))
1350 case DT_DIR
: case DT_LNK
: case DT_UNKNOWN
: break;
1354 if (fnmatch (pattern
, d
.name
, fnm_flags
) == 0)
1356 if (cur
== names
->count
)
1358 struct globnames
*newnames
;
1359 size_t count
= names
->count
* 2;
1360 size_t nameoff
= offsetof (struct globnames
, name
);
1361 size_t size
= FLEXSIZEOF (struct globnames
, name
,
1362 count
* sizeof (char *));
1363 if ((SIZE_MAX
- nameoff
) / 2 / sizeof (char *)
1366 if (glob_use_alloca (alloca_used
, size
))
1367 newnames
= names_alloca
1368 = alloca_account (size
, alloca_used
);
1369 else if ((newnames
= malloc (size
))
1372 newnames
->count
= count
;
1373 newnames
->next
= names
;
1377 names
->name
[cur
] = strdup (d
.name
);
1378 if (names
->name
[cur
] == NULL
)
1382 if (SIZE_MAX
- pglob
->gl_offs
<= nfound
)
1389 if (nfound
== 0 && (flags
& GLOB_NOCHECK
))
1391 size_t len
= strlen (pattern
);
1393 names
->name
[cur
] = malloc (len
+ 1);
1394 if (names
->name
[cur
] == NULL
)
1396 *((char *) mempcpy (names
->name
[cur
++], pattern
, len
)) = '\0';
1399 result
= GLOB_NOMATCH
;
1402 char **new_gl_pathv
;
1405 if (SIZE_MAX
/ sizeof (char *) - pglob
->gl_pathc
1406 < pglob
->gl_offs
+ nfound
+ 1)
1410 = realloc (pglob
->gl_pathv
,
1411 (pglob
->gl_pathc
+ pglob
->gl_offs
+ nfound
+ 1)
1414 if (new_gl_pathv
== NULL
)
1419 struct globnames
*old
= names
;
1420 for (size_t i
= 0; i
< cur
; ++i
)
1421 free (names
->name
[i
]);
1422 names
= names
->next
;
1423 /* NB: we will not leak memory here if we exit without
1424 freeing the current block assigned to OLD. At least
1425 the very first block is always allocated on the stack
1426 and this is the block assigned to OLD here. */
1429 assert (old
== init_names
);
1433 if (old
== names_alloca
)
1434 names_alloca
= names
;
1438 result
= GLOB_NOSPACE
;
1444 struct globnames
*old
= names
;
1445 for (size_t i
= 0; i
< cur
; ++i
)
1446 new_gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
++]
1448 names
= names
->next
;
1449 /* NB: we will not leak memory here if we exit without
1450 freeing the current block assigned to OLD. At least
1451 the very first block is always allocated on the stack
1452 and this is the block assigned to OLD here. */
1455 assert (old
== init_names
);
1459 if (old
== names_alloca
)
1460 names_alloca
= names
;
1465 pglob
->gl_pathv
= new_gl_pathv
;
1467 pglob
->gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
] = NULL
;
1469 pglob
->gl_flags
= flags
;
1476 if (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
))
1477 (*pglob
->gl_closedir
) (stream
);