1 /* Copyright (C) 1991-2019 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 General Public
6 License as published by the Free Software Foundation; either
7 version 3 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 General Public License for more details.
14 You should have received a copy of the GNU 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)
31 #include <sys/types.h>
39 #if defined _WIN32 && ! defined __CYGWIN__
55 # define strdup(str) __strdup (str)
56 # define sysconf(id) __sysconf (id)
57 # define closedir(dir) __closedir (dir)
58 # define opendir(name) __opendir (name)
59 # define readdir(str) __readdir64 (str)
60 # define getpwnam_r(name, bufp, buf, len, res) \
61 __getpwnam_r (name, bufp, buf, len, res)
63 # define __lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
66 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
68 # define struct_stat64 struct stat64
69 # define FLEXIBLE_ARRAY_MEMBER
70 # include <shlib-compat.h>
73 # define __getlogin_r(buf, len) getlogin_r (buf, len)
74 # define __lstat64(fname, buf) lstat (fname, buf)
75 # define __stat64(fname, buf) stat (fname, buf)
76 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
77 # define struct_stat64 struct stat
79 # define __alloca alloca
81 # define __readdir readdir
82 # define COMPILE_GLOB64
87 #include <flexmember.h>
88 #include <glob_internal.h>
89 #include <scratch_buffer.h>
91 static const char *next_brace_sub (const char *begin
, int flags
) __THROWNL
;
93 /* The type of ((struct dirent *) 0)->d_type is 'unsigned char' on most
94 platforms, but 'unsigned int' in the mingw from mingw.org. */
95 typedef uint_fast32_t dirent_type
;
97 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
98 /* Any distinct values will do here.
99 Undef any existing macros out of the way. */
103 # define DT_UNKNOWN 0
108 /* A representation of a directory entry which does not depend on the
109 layout of struct dirent, or the size of ino_t. */
110 struct readdir_result
113 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
118 /* Initialize and return type member of struct readdir_result. */
120 readdir_result_type (struct readdir_result d
)
122 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
123 # define D_TYPE_TO_RESULT(source) (source)->d_type,
126 # define D_TYPE_TO_RESULT(source)
131 /* Construct an initializer for a struct readdir_result object from a
132 struct dirent *. No copy of the name is made. */
133 #define READDIR_RESULT_INITIALIZER(source) \
136 D_TYPE_TO_RESULT (source) \
139 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
140 type safety if an old interface version needs to be supported. */
142 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
145 /* Extract name and type from directory entry. No copy of the name is
146 made. If SOURCE is NULL, result name is NULL. Keep in sync with
147 convert_dirent64 below. */
148 static struct readdir_result
149 convert_dirent (const struct dirent
*source
)
153 struct readdir_result result
= { NULL
, };
156 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
160 #ifndef COMPILE_GLOB64
161 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
162 sync with convert_dirent above. */
163 static struct readdir_result
164 convert_dirent64 (const struct dirent64
*source
)
168 struct readdir_result result
= { NULL
, };
171 struct readdir_result result
= READDIR_RESULT_INITIALIZER (source
);
177 /* The results of opendir() in this file are not used with dirfd and fchdir,
178 and we do not leak fds to any single-threaded code that could use stdio,
179 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
180 FIXME - if the kernel ever adds support for multi-thread safety for
181 avoiding standard fds, then we should use opendir_safer. */
182 # ifdef GNULIB_defined_opendir
185 # ifdef GNULIB_defined_closedir
189 /* Just use malloc. */
190 # define __libc_use_alloca(n) false
191 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
192 # define extend_alloca_account(buf, len, newlen, avar) \
193 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
197 glob_lstat (glob_t
*pglob
, int flags
, const char *fullname
)
199 /* Use on glob-lstat-compat.c to provide a compat symbol which does not
200 use lstat / gl_lstat. */
202 # define GL_LSTAT gl_stat
203 # define LSTAT64 __stat64
205 # define GL_LSTAT gl_lstat
206 # define LSTAT64 __lstat64
214 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
215 ? pglob
->GL_LSTAT (fullname
, &ust
.st
)
216 : LSTAT64 (fullname
, &ust
.st64
));
219 /* Set *R = A + B. Return true if the answer is mathematically
220 incorrect due to overflow; in this case, *R is the low order
221 bits of the correct answer. */
224 size_add_wrapv (size_t a
, size_t b
, size_t *r
)
226 #if 5 <= __GNUC__ && !defined __ICC
227 return __builtin_add_overflow (a
, b
, r
);
235 glob_use_alloca (size_t alloca_used
, size_t len
)
238 return (!size_add_wrapv (alloca_used
, len
, &size
)
239 && __libc_use_alloca (size
));
242 static int glob_in_dir (const char *pattern
, const char *directory
,
243 int flags
, int (*errfunc
) (const char *, int),
244 glob_t
*pglob
, size_t alloca_used
);
245 static int prefix_array (const char *prefix
, char **array
, size_t n
) __THROWNL
;
246 static int collated_compare (const void *, const void *) __THROWNL
;
249 /* Return true if FILENAME is a directory or a symbolic link to a directory.
250 Use FLAGS and PGLOB to resolve the filename. */
252 is_dir (char const *filename
, int flags
, glob_t
const *pglob
)
256 return (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
)
257 ? pglob
->gl_stat (filename
, &st
) == 0 && S_ISDIR (st
.st_mode
)
258 : __stat64 (filename
, &st64
) == 0 && S_ISDIR (st64
.st_mode
));
261 /* Find the end of the sub-pattern in a brace expression. */
263 next_brace_sub (const char *cp
, int flags
)
267 if ((flags
& GLOB_NOESCAPE
) == 0 && *cp
== '\\')
275 if ((*cp
== '}' && depth
-- == 0) || (*cp
== ',' && depth
== 0))
282 return *cp
!= '\0' ? cp
: NULL
;
285 #ifndef GLOB_ATTRIBUTE
286 # define GLOB_ATTRIBUTE
289 /* Do glob searching for PATTERN, placing results in PGLOB.
290 The bits defined above may be set in FLAGS.
291 If a directory cannot be opened or read and ERRFUNC is not nil,
292 it is called with the pathname that caused the error, and the
293 'errno' value from the failing call; if it returns non-zero
294 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
295 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
296 Otherwise, 'glob' returns zero. */
299 __glob (const char *pattern
, int flags
, int (*errfunc
) (const char *, int),
302 const char *filename
;
303 char *dirname
= NULL
;
308 int dirname_modified
;
309 int malloc_dirname
= 0;
312 size_t alloca_used
= 0;
314 if (pattern
== NULL
|| pglob
== NULL
|| (flags
& ~__GLOB_FLAGS
) != 0)
316 __set_errno (EINVAL
);
320 /* POSIX requires all slashes to be matched. This means that with
321 a trailing slash we must match only directories. */
322 if (pattern
[0] && pattern
[strlen (pattern
) - 1] == '/')
323 flags
|= GLOB_ONLYDIR
;
325 if (!(flags
& GLOB_DOOFFS
))
326 /* Have to do this so 'globfree' knows where to start freeing. It
327 also makes all the code that uses gl_offs simpler. */
330 if (!(flags
& GLOB_APPEND
))
333 if (!(flags
& GLOB_DOOFFS
))
334 pglob
->gl_pathv
= NULL
;
339 if (pglob
->gl_offs
>= ~((size_t) 0) / sizeof (char *))
342 pglob
->gl_pathv
= (char **) malloc ((pglob
->gl_offs
+ 1)
344 if (pglob
->gl_pathv
== NULL
)
347 for (i
= 0; i
<= pglob
->gl_offs
; ++i
)
348 pglob
->gl_pathv
[i
] = NULL
;
352 if (flags
& GLOB_BRACE
)
356 if (flags
& GLOB_NOESCAPE
)
357 begin
= strchr (pattern
, '{');
369 if (*begin
== '\\' && begin
[1] != '\0')
371 else if (*begin
== '{')
380 /* Allocate working buffer large enough for our work. Note that
381 we have at least an opening and closing brace. */
389 size_t pattern_len
= strlen (pattern
) - 1;
390 int alloca_onealt
= glob_use_alloca (alloca_used
, pattern_len
);
392 onealt
= alloca_account (pattern_len
, alloca_used
);
395 onealt
= malloc (pattern_len
);
400 /* We know the prefix for all sub-patterns. */
401 alt_start
= mempcpy (onealt
, pattern
, begin
- pattern
);
403 /* Find the first sub-pattern and at the same time find the
404 rest after the closing brace. */
405 next
= next_brace_sub (begin
+ 1, flags
);
408 /* It is an invalid expression. */
410 if (__glibc_unlikely (!alloca_onealt
))
412 flags
&= ~GLOB_BRACE
;
416 /* Now find the end of the whole brace expression. */
420 rest
= next_brace_sub (rest
+ 1, flags
);
422 /* It is an illegal expression. */
425 /* Please note that we now can be sure the brace expression
427 rest_len
= strlen (++rest
) + 1;
429 /* We have a brace expression. BEGIN points to the opening {,
430 NEXT points past the terminator of the first element, and END
431 points past the final }. We will accumulate result names from
432 recursive runs for each brace alternative in the buffer using
434 firstc
= pglob
->gl_pathc
;
441 /* Construct the new glob expression. */
442 mempcpy (mempcpy (alt_start
, p
, next
- p
), rest
, rest_len
);
444 result
= __glob (onealt
,
445 ((flags
& ~(GLOB_NOCHECK
| GLOB_NOMAGIC
))
449 /* If we got an error, return it. */
450 if (result
&& result
!= GLOB_NOMATCH
)
452 if (__glibc_unlikely (!alloca_onealt
))
454 if (!(flags
& GLOB_APPEND
))
463 /* We saw the last entry. */
467 next
= next_brace_sub (p
, flags
);
468 assert (next
!= NULL
);
471 if (__glibc_unlikely (!alloca_onealt
))
474 if (pglob
->gl_pathc
!= firstc
)
475 /* We found some entries. */
477 else if (!(flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
483 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
485 /* Find the filename. */
486 filename
= strrchr (pattern
, '/');
488 #if defined __MSDOS__ || defined WINDOWS32
489 /* The case of "d:pattern". Since ':' is not allowed in
490 file names, we can safely assume that wherever it
491 happens in pattern, it signals the filename part. This
492 is so we could some day support patterns like "[a-z]:foo". */
493 if (filename
== NULL
)
494 filename
= strchr (pattern
, ':');
495 #endif /* __MSDOS__ || WINDOWS32 */
497 dirname_modified
= 0;
498 if (filename
== NULL
)
500 /* This can mean two things: a simple name or "~name". The latter
501 case is nothing but a notation for a directory. */
502 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && pattern
[0] == '~')
504 dirname
= (char *) pattern
;
505 dirlen
= strlen (pattern
);
507 /* Set FILENAME to NULL as a special flag. This is ugly but
508 other solutions would require much more code. We test for
509 this special case below. */
514 if (__glibc_unlikely (pattern
[0] == '\0'))
516 dirs
.gl_pathv
= NULL
;
521 dirname
= (char *) ".";
525 else if (filename
== pattern
526 || (filename
== pattern
+ 1 && pattern
[0] == '\\'
527 && (flags
& GLOB_NOESCAPE
) == 0))
529 /* "/pattern" or "\\/pattern". */
530 dirname
= (char *) "/";
537 dirlen
= filename
- pattern
;
538 #if defined __MSDOS__ || defined WINDOWS32
540 || (filename
> pattern
+ 1 && filename
[-1] == ':'))
545 drive_spec
= __alloca (dirlen
+ 1);
546 *((char *) mempcpy (drive_spec
, pattern
, dirlen
)) = '\0';
547 /* For now, disallow wildcards in the drive spec, to
548 prevent infinite recursion in glob. */
549 if (__glob_pattern_p (drive_spec
, !(flags
& GLOB_NOESCAPE
)))
551 /* If this is "d:pattern", we need to copy ':' to DIRNAME
552 as well. If it's "d:/pattern", don't remove the slash
553 from "d:/", since "d:" and "d:/" are not the same.*/
557 if (glob_use_alloca (alloca_used
, dirlen
+ 1))
558 newp
= alloca_account (dirlen
+ 1, alloca_used
);
561 newp
= malloc (dirlen
+ 1);
566 *((char *) mempcpy (newp
, pattern
, dirlen
)) = '\0';
570 #if defined __MSDOS__ || defined WINDOWS32
571 bool drive_root
= (dirlen
> 1
572 && (dirname
[dirlen
- 1] == ':'
573 || (dirlen
> 2 && dirname
[dirlen
- 2] == ':'
574 && dirname
[dirlen
- 1] == '/')));
576 bool drive_root
= false;
579 if (filename
[0] == '\0' && dirlen
> 1 && !drive_root
)
580 /* "pattern/". Expand "pattern", appending slashes. */
582 int orig_flags
= flags
;
583 if (!(flags
& GLOB_NOESCAPE
) && dirname
[dirlen
- 1] == '\\')
585 /* "pattern\\/". Remove the final backslash if it hasn't
587 char *p
= (char *) &dirname
[dirlen
- 1];
589 while (p
> dirname
&& p
[-1] == '\\') --p
;
590 if ((&dirname
[dirlen
] - p
) & 1)
592 *(char *) &dirname
[--dirlen
] = '\0';
593 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
596 int val
= __glob (dirname
, flags
| GLOB_MARK
, errfunc
, pglob
);
598 pglob
->gl_flags
= ((pglob
->gl_flags
& ~GLOB_MARK
)
599 | (flags
& GLOB_MARK
));
600 else if (val
== GLOB_NOMATCH
&& flags
!= orig_flags
)
602 /* Make sure globfree (&dirs); is a nop. */
603 dirs
.gl_pathv
= NULL
;
605 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
613 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && dirname
[0] == '~')
615 if (dirname
[1] == '\0' || dirname
[1] == '/'
616 || (!(flags
& GLOB_NOESCAPE
) && dirname
[1] == '\\'
617 && (dirname
[2] == '\0' || dirname
[2] == '/')))
619 /* Look up home directory. */
620 char *home_dir
= getenv ("HOME");
621 int malloc_home_dir
= 0;
622 if (home_dir
== NULL
|| home_dir
[0] == '\0')
625 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
626 preference to HOME, because the user can change HOME. */
627 const char *home_drive
= getenv ("HOMEDRIVE");
628 const char *home_path
= getenv ("HOMEPATH");
630 if (home_drive
!= NULL
&& home_path
!= NULL
)
632 size_t home_drive_len
= strlen (home_drive
);
633 size_t home_path_len
= strlen (home_path
);
634 char *mem
= alloca (home_drive_len
+ home_path_len
+ 1);
636 memcpy (mem
, home_drive
, home_drive_len
);
637 memcpy (mem
+ home_drive_len
, home_path
, home_path_len
+ 1);
641 home_dir
= "c:/users/default"; /* poor default */
646 struct scratch_buffer s
;
647 scratch_buffer_init (&s
);
651 err
= __getlogin_r (s
.data
, s
.length
);
654 # if defined HAVE_GETPWNAM_R || defined _LIBC
655 size_t ssize
= strlen (s
.data
) + 1;
656 char *sdata
= s
.data
;
657 err
= getpwnam_r (sdata
, &pwbuf
, sdata
+ ssize
,
658 s
.length
- ssize
, &p
);
660 p
= getpwnam (s
.data
);
667 if (!scratch_buffer_grow (&s
))
669 retval
= GLOB_NOSPACE
;
675 home_dir
= strdup (p
->pw_dir
);
678 scratch_buffer_free (&s
);
679 if (err
== 0 && home_dir
== NULL
)
681 retval
= GLOB_NOSPACE
;
684 #endif /* WINDOWS32 */
686 if (home_dir
== NULL
|| home_dir
[0] == '\0')
688 if (__glibc_unlikely (malloc_home_dir
))
690 if (flags
& GLOB_TILDE_CHECK
)
692 retval
= GLOB_NOMATCH
;
697 home_dir
= (char *) "~"; /* No luck. */
701 /* Now construct the full directory. */
702 if (dirname
[1] == '\0')
704 if (__glibc_unlikely (malloc_dirname
))
708 dirlen
= strlen (dirname
);
709 malloc_dirname
= malloc_home_dir
;
714 size_t home_len
= strlen (home_dir
);
715 int use_alloca
= glob_use_alloca (alloca_used
, home_len
+ dirlen
);
717 newp
= alloca_account (home_len
+ dirlen
, alloca_used
);
720 newp
= malloc (home_len
+ dirlen
);
723 if (__glibc_unlikely (malloc_home_dir
))
725 retval
= GLOB_NOSPACE
;
730 mempcpy (mempcpy (newp
, home_dir
, home_len
),
731 &dirname
[1], dirlen
);
733 if (__glibc_unlikely (malloc_dirname
))
737 dirlen
+= home_len
- 1;
738 malloc_dirname
= !use_alloca
;
740 if (__glibc_unlikely (malloc_home_dir
))
743 dirname_modified
= 1;
748 char *end_name
= strchr (dirname
, '/');
750 int malloc_user_name
= 0;
751 char *unescape
= NULL
;
753 if (!(flags
& GLOB_NOESCAPE
))
755 if (end_name
== NULL
)
757 unescape
= strchr (dirname
, '\\');
759 end_name
= strchr (unescape
, '\0');
762 unescape
= memchr (dirname
, '\\', end_name
- dirname
);
764 if (end_name
== NULL
)
765 user_name
= dirname
+ 1;
769 if (glob_use_alloca (alloca_used
, end_name
- dirname
))
770 newp
= alloca_account (end_name
- dirname
, alloca_used
);
773 newp
= malloc (end_name
- dirname
);
776 retval
= GLOB_NOSPACE
;
779 malloc_user_name
= 1;
781 if (unescape
!= NULL
)
783 char *p
= mempcpy (newp
, dirname
+ 1,
784 unescape
- dirname
- 1);
786 while (q
!= end_name
)
790 if (q
+ 1 == end_name
)
792 /* "~fo\\o\\" unescape to user_name "foo\\",
793 but "~fo\\o\\/" unescape to user_name
795 if (filename
== NULL
)
806 *((char *) mempcpy (newp
, dirname
+ 1, end_name
- dirname
- 1))
811 /* Look up specific user's home directory. */
814 struct scratch_buffer pwtmpbuf
;
815 scratch_buffer_init (&pwtmpbuf
);
817 # if defined HAVE_GETPWNAM_R || defined _LIBC
820 while (getpwnam_r (user_name
, &pwbuf
,
821 pwtmpbuf
.data
, pwtmpbuf
.length
, &p
)
824 if (!scratch_buffer_grow (&pwtmpbuf
))
826 retval
= GLOB_NOSPACE
;
831 p
= getpwnam (user_name
);
834 if (__glibc_unlikely (malloc_user_name
))
837 /* If we found a home directory use this. */
840 size_t home_len
= strlen (p
->pw_dir
);
841 size_t rest_len
= end_name
== NULL
? 0 : strlen (end_name
);
844 if (__glibc_unlikely (malloc_dirname
))
848 if (glob_use_alloca (alloca_used
, home_len
+ rest_len
+ 1))
849 dirname
= alloca_account (home_len
+ rest_len
+ 1,
853 dirname
= malloc (home_len
+ rest_len
+ 1);
856 scratch_buffer_free (&pwtmpbuf
);
857 retval
= GLOB_NOSPACE
;
862 d
= mempcpy (dirname
, p
->pw_dir
, home_len
);
863 if (end_name
!= NULL
)
864 d
= mempcpy (d
, end_name
, rest_len
);
867 dirlen
= home_len
+ rest_len
;
868 dirname_modified
= 1;
872 if (flags
& GLOB_TILDE_CHECK
)
874 /* We have to regard it as an error if we cannot find the
876 retval
= GLOB_NOMATCH
;
880 scratch_buffer_free (&pwtmpbuf
);
882 #endif /* !WINDOWS32 */
886 /* Now test whether we looked for "~" or "~NAME". In this case we
887 can give the answer now. */
888 if (filename
== NULL
)
890 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
893 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
896 free (pglob
->gl_pathv
);
897 pglob
->gl_pathv
= NULL
;
899 retval
= GLOB_NOSPACE
;
903 new_gl_pathv
= realloc (pglob
->gl_pathv
,
904 (newcount
+ 2) * sizeof (char *));
905 if (new_gl_pathv
== NULL
)
907 pglob
->gl_pathv
= new_gl_pathv
;
909 if (flags
& GLOB_MARK
&& is_dir (dirname
, flags
, pglob
))
912 pglob
->gl_pathv
[newcount
] = malloc (dirlen
+ 2);
913 if (pglob
->gl_pathv
[newcount
] == NULL
)
915 p
= mempcpy (pglob
->gl_pathv
[newcount
], dirname
, dirlen
);
918 if (__glibc_unlikely (malloc_dirname
))
923 if (__glibc_unlikely (malloc_dirname
))
924 pglob
->gl_pathv
[newcount
] = dirname
;
927 pglob
->gl_pathv
[newcount
] = strdup (dirname
);
928 if (pglob
->gl_pathv
[newcount
] == NULL
)
932 pglob
->gl_pathv
[++newcount
] = NULL
;
934 pglob
->gl_flags
= flags
;
939 meta
= __glob_pattern_type (dirname
, !(flags
& GLOB_NOESCAPE
));
940 /* meta is 1 if correct glob pattern containing metacharacters.
941 If meta has bit (1 << 2) set, it means there was an unterminated
942 [ which we handle the same, using fnmatch. Broken unterminated
943 pattern bracket expressions ought to be rare enough that it is
944 not worth special casing them, fnmatch will do the right thing. */
945 if (meta
& (GLOBPAT_SPECIAL
| GLOBPAT_BRACKET
))
947 /* The directory name contains metacharacters, so we
948 have to glob for the directory, and then glob for
949 the pattern in each directory found. */
952 if (!(flags
& GLOB_NOESCAPE
) && dirlen
> 0 && dirname
[dirlen
- 1] == '\\')
954 /* "foo\\/bar". Remove the final backslash from dirname
955 if it has not been quoted. */
956 char *p
= (char *) &dirname
[dirlen
- 1];
958 while (p
> dirname
&& p
[-1] == '\\') --p
;
959 if ((&dirname
[dirlen
] - p
) & 1)
960 *(char *) &dirname
[--dirlen
] = '\0';
963 if (__glibc_unlikely ((flags
& GLOB_ALTDIRFUNC
) != 0))
965 /* Use the alternative access functions also in the recursive
967 dirs
.gl_opendir
= pglob
->gl_opendir
;
968 dirs
.gl_readdir
= pglob
->gl_readdir
;
969 dirs
.gl_closedir
= pglob
->gl_closedir
;
970 dirs
.gl_stat
= pglob
->gl_stat
;
971 dirs
.gl_lstat
= pglob
->gl_lstat
;
974 status
= __glob (dirname
,
975 ((flags
& (GLOB_ERR
| GLOB_NOESCAPE
| GLOB_ALTDIRFUNC
))
976 | GLOB_NOSORT
| GLOB_ONLYDIR
),
980 if ((flags
& GLOB_NOCHECK
) == 0 || status
!= GLOB_NOMATCH
)
988 /* We have successfully globbed the preceding directory name.
989 For each name we found, call glob_in_dir on it and FILENAME,
990 appending the results to PGLOB. */
991 for (i
= 0; i
< dirs
.gl_pathc
; ++i
)
995 old_pathc
= pglob
->gl_pathc
;
996 status
= glob_in_dir (filename
, dirs
.gl_pathv
[i
],
997 ((flags
| GLOB_APPEND
)
998 & ~(GLOB_NOCHECK
| GLOB_NOMAGIC
)),
999 errfunc
, pglob
, alloca_used
);
1000 if (status
== GLOB_NOMATCH
)
1001 /* No matches in this directory. Try the next. */
1008 pglob
->gl_pathc
= 0;
1013 /* Stick the directory on the front of each name. */
1014 if (prefix_array (dirs
.gl_pathv
[i
],
1015 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1016 pglob
->gl_pathc
- old_pathc
))
1020 pglob
->gl_pathc
= 0;
1021 retval
= GLOB_NOSPACE
;
1026 flags
|= GLOB_MAGCHAR
;
1028 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1029 But if we have not found any matching entry and the GLOB_NOCHECK
1030 flag was set we must return the input pattern itself. */
1031 if (pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1035 if (flags
& GLOB_NOCHECK
)
1037 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
1038 char **new_gl_pathv
;
1040 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
1044 retval
= GLOB_NOSPACE
;
1048 new_gl_pathv
= realloc (pglob
->gl_pathv
,
1049 (newcount
+ 2) * sizeof (char *));
1050 if (new_gl_pathv
== NULL
)
1052 pglob
->gl_pathv
= new_gl_pathv
;
1054 pglob
->gl_pathv
[newcount
] = strdup (pattern
);
1055 if (pglob
->gl_pathv
[newcount
] == NULL
)
1059 pglob
->gl_pathc
= 0;
1060 retval
= GLOB_NOSPACE
;
1067 pglob
->gl_pathv
[newcount
] = NULL
;
1068 pglob
->gl_flags
= flags
;
1073 retval
= GLOB_NOMATCH
;
1082 size_t old_pathc
= pglob
->gl_pathc
;
1083 int orig_flags
= flags
;
1085 if (meta
& GLOBPAT_BACKSLASH
)
1087 char *p
= strchr (dirname
, '\\'), *q
;
1088 /* We need to unescape the dirname string. It is certainly
1089 allocated by alloca, as otherwise filename would be NULL
1090 or dirname wouldn't contain backslashes. */
1103 while (*p
++ != '\0');
1104 dirname_modified
= 1;
1106 if (dirname_modified
)
1107 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
1108 status
= glob_in_dir (filename
, dirname
, flags
, errfunc
, pglob
,
1112 if (status
== GLOB_NOMATCH
&& flags
!= orig_flags
1113 && pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1115 /* Make sure globfree (&dirs); is a nop. */
1116 dirs
.gl_pathv
= NULL
;
1126 /* Stick the directory on the front of each name. */
1127 if (prefix_array (dirname
,
1128 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1129 pglob
->gl_pathc
- old_pathc
))
1132 pglob
->gl_pathc
= 0;
1133 retval
= GLOB_NOSPACE
;
1139 if (flags
& GLOB_MARK
)
1141 /* Append slashes to directory names. */
1144 for (i
= oldcount
; i
< pglob
->gl_pathc
+ pglob
->gl_offs
; ++i
)
1145 if (is_dir (pglob
->gl_pathv
[i
], flags
, pglob
))
1147 size_t len
= strlen (pglob
->gl_pathv
[i
]) + 2;
1148 char *new = realloc (pglob
->gl_pathv
[i
], len
);
1152 pglob
->gl_pathc
= 0;
1153 retval
= GLOB_NOSPACE
;
1156 strcpy (&new[len
- 2], "/");
1157 pglob
->gl_pathv
[i
] = new;
1161 if (!(flags
& GLOB_NOSORT
))
1163 /* Sort the vector. */
1164 qsort (&pglob
->gl_pathv
[oldcount
],
1165 pglob
->gl_pathc
+ pglob
->gl_offs
- oldcount
,
1166 sizeof (char *), collated_compare
);
1170 if (__glibc_unlikely (malloc_dirname
))
1175 #if defined _LIBC && !defined __glob
1176 versioned_symbol (libc
, __glob
, glob
, GLIBC_2_27
);
1177 libc_hidden_ver (__glob
, glob
)
1181 /* Do a collated comparison of A and B. */
1183 collated_compare (const void *a
, const void *b
)
1185 char *const *ps1
= a
; char *s1
= *ps1
;
1186 char *const *ps2
= b
; char *s2
= *ps2
;
1194 return strcoll (s1
, s2
);
1198 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1199 elements in place. Return nonzero if out of memory, zero if successful.
1200 A slash is inserted between DIRNAME and each elt of ARRAY,
1201 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1203 prefix_array (const char *dirname
, char **array
, size_t n
)
1206 size_t dirlen
= strlen (dirname
);
1207 char dirsep_char
= '/';
1209 if (dirlen
== 1 && dirname
[0] == '/')
1210 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1211 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1214 #if defined __MSDOS__ || defined WINDOWS32
1217 if (dirname
[dirlen
- 1] == '/' && dirname
[dirlen
- 2] == ':')
1218 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1220 else if (dirname
[dirlen
- 1] == ':')
1222 /* DIRNAME is "d:". Use ':' instead of '/'. */
1229 for (i
= 0; i
< n
; ++i
)
1231 size_t eltlen
= strlen (array
[i
]) + 1;
1232 char *new = malloc (dirlen
+ 1 + eltlen
);
1241 char *endp
= mempcpy (new, dirname
, dirlen
);
1242 *endp
++ = dirsep_char
;
1243 mempcpy (endp
, array
[i
], eltlen
);
1252 /* Like 'glob', but PATTERN is a final pathname component,
1253 and matches are searched for in DIRECTORY.
1254 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1255 The GLOB_APPEND flag is assumed to be set (always appends). */
1257 glob_in_dir (const char *pattern
, const char *directory
, int flags
,
1258 int (*errfunc
) (const char *, int),
1259 glob_t
*pglob
, size_t alloca_used
)
1261 size_t dirlen
= strlen (directory
);
1262 void *stream
= NULL
;
1263 # define GLOBNAMES_MEMBERS(nnames) \
1264 struct globnames *next; size_t count; char *name[nnames];
1265 struct globnames
{ GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER
) };
1266 struct { GLOBNAMES_MEMBERS (64) } init_names_buf
;
1267 struct globnames
*init_names
= (struct globnames
*) &init_names_buf
;
1268 struct globnames
*names
= init_names
;
1269 struct globnames
*names_alloca
= init_names
;
1276 alloca_used
+= sizeof init_names_buf
;
1278 init_names
->next
= NULL
;
1279 init_names
->count
= ((sizeof init_names_buf
1280 - offsetof (struct globnames
, name
))
1281 / sizeof init_names
->name
[0]);
1283 meta
= __glob_pattern_type (pattern
, !(flags
& GLOB_NOESCAPE
));
1284 if (meta
== GLOBPAT_NONE
&& (flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
1286 /* We need not do any tests. The PATTERN contains no meta
1287 characters and we must not return an error therefore the
1288 result will always contain exactly one name. */
1289 flags
|= GLOB_NOCHECK
;
1291 else if (meta
== GLOBPAT_NONE
)
1293 size_t patlen
= strlen (pattern
);
1295 bool alloca_fullname
1296 = (! size_add_wrapv (dirlen
+ 1, patlen
+ 1, &fullsize
)
1297 && glob_use_alloca (alloca_used
, fullsize
));
1299 if (alloca_fullname
)
1300 fullname
= alloca_account (fullsize
, alloca_used
);
1303 fullname
= malloc (fullsize
);
1304 if (fullname
== NULL
)
1305 return GLOB_NOSPACE
;
1308 mempcpy (mempcpy (mempcpy (fullname
, directory
, dirlen
),
1310 pattern
, patlen
+ 1);
1311 if (glob_lstat (pglob
, flags
, fullname
) == 0
1312 || errno
== EOVERFLOW
)
1313 /* We found this file to be existing. Now tell the rest
1314 of the function to copy this name into the result. */
1315 flags
|= GLOB_NOCHECK
;
1317 if (__glibc_unlikely (!alloca_fullname
))
1322 stream
= (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1323 ? (*pglob
->gl_opendir
) (directory
)
1324 : opendir (directory
));
1327 if (errno
!= ENOTDIR
1328 && ((errfunc
!= NULL
&& (*errfunc
) (directory
, errno
))
1329 || (flags
& GLOB_ERR
)))
1330 return GLOB_ABORTED
;
1334 int fnm_flags
= ((!(flags
& GLOB_PERIOD
) ? FNM_PERIOD
: 0)
1335 | ((flags
& GLOB_NOESCAPE
) ? FNM_NOESCAPE
: 0));
1336 flags
|= GLOB_MAGCHAR
;
1340 struct readdir_result d
;
1342 if (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0))
1343 d
= convert_dirent (GL_READDIR (pglob
, stream
));
1346 #ifdef COMPILE_GLOB64
1347 d
= convert_dirent (__readdir (stream
));
1349 d
= convert_dirent64 (__readdir64 (stream
));
1356 /* If we shall match only directories use the information
1357 provided by the dirent call if possible. */
1358 if (flags
& GLOB_ONLYDIR
)
1359 switch (readdir_result_type (d
))
1361 case DT_DIR
: case DT_LNK
: case DT_UNKNOWN
: break;
1365 if (fnmatch (pattern
, d
.name
, fnm_flags
) == 0)
1367 if (cur
== names
->count
)
1369 struct globnames
*newnames
;
1370 size_t count
= names
->count
* 2;
1371 size_t nameoff
= offsetof (struct globnames
, name
);
1372 size_t size
= FLEXSIZEOF (struct globnames
, name
,
1373 count
* sizeof (char *));
1374 if ((SIZE_MAX
- nameoff
) / 2 / sizeof (char *)
1377 if (glob_use_alloca (alloca_used
, size
))
1378 newnames
= names_alloca
1379 = alloca_account (size
, alloca_used
);
1380 else if ((newnames
= malloc (size
))
1383 newnames
->count
= count
;
1384 newnames
->next
= names
;
1388 names
->name
[cur
] = strdup (d
.name
);
1389 if (names
->name
[cur
] == NULL
)
1393 if (SIZE_MAX
- pglob
->gl_offs
<= nfound
)
1400 if (nfound
== 0 && (flags
& GLOB_NOCHECK
))
1402 size_t len
= strlen (pattern
);
1404 names
->name
[cur
] = malloc (len
+ 1);
1405 if (names
->name
[cur
] == NULL
)
1407 *((char *) mempcpy (names
->name
[cur
++], pattern
, len
)) = '\0';
1410 result
= GLOB_NOMATCH
;
1413 char **new_gl_pathv
;
1416 if (SIZE_MAX
/ sizeof (char *) - pglob
->gl_pathc
1417 < pglob
->gl_offs
+ nfound
+ 1)
1421 = realloc (pglob
->gl_pathv
,
1422 (pglob
->gl_pathc
+ pglob
->gl_offs
+ nfound
+ 1)
1425 if (new_gl_pathv
== NULL
)
1430 struct globnames
*old
= names
;
1431 for (size_t i
= 0; i
< cur
; ++i
)
1432 free (names
->name
[i
]);
1433 names
= names
->next
;
1434 /* NB: we will not leak memory here if we exit without
1435 freeing the current block assigned to OLD. At least
1436 the very first block is always allocated on the stack
1437 and this is the block assigned to OLD here. */
1440 assert (old
== init_names
);
1444 if (old
== names_alloca
)
1445 names_alloca
= names
;
1449 result
= GLOB_NOSPACE
;
1455 struct globnames
*old
= names
;
1456 for (size_t i
= 0; i
< cur
; ++i
)
1457 new_gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
++]
1459 names
= names
->next
;
1460 /* NB: we will not leak memory here if we exit without
1461 freeing the current block assigned to OLD. At least
1462 the very first block is always allocated on the stack
1463 and this is the block assigned to OLD here. */
1466 assert (old
== init_names
);
1470 if (old
== names_alloca
)
1471 names_alloca
= names
;
1476 pglob
->gl_pathv
= new_gl_pathv
;
1478 pglob
->gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
] = NULL
;
1480 pglob
->gl_flags
= flags
;
1487 if (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
))
1488 (*pglob
->gl_closedir
) (stream
);
This page took 0.086421 seconds and 5 git commands to generate.