1 /* Copyright (C) 1991-2017 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 <http://www.gnu.org/licenses/>. */
25 #include <sys/types.h>
33 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
43 # define __set_errno(val) errno = (val)
53 # define strdup(str) __strdup (str)
54 # define sysconf(id) __sysconf (id)
55 # define closedir(dir) __closedir (dir)
56 # define opendir(name) __opendir (name)
57 # define readdir(str) __readdir64 (str)
58 # define getpwnam_r(name, bufp, buf, len, res) \
59 __getpwnam_r (name, bufp, buf, len, res)
61 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
63 # define struct_stat64 struct stat64
64 # define FLEXIBLE_ARRAY_MEMBER
66 # define __getlogin_r(buf, len) getlogin_r (buf, len)
67 # define __stat64(fname, buf) stat (fname, buf)
68 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
69 # define struct_stat64 struct stat
71 # define __alloca alloca
73 # define __readdir readdir
74 # define COMPILE_GLOB64
79 #include <flexmember.h>
80 #include <glob_internal.h>
82 #ifdef _SC_GETPW_R_SIZE_MAX
83 # define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX)
85 # define GETPW_R_SIZE_MAX() (-1)
87 #ifdef _SC_LOGIN_NAME_MAX
88 # define GET_LOGIN_NAME_MAX() sysconf (_SC_LOGIN_NAME_MAX)
90 # define GET_LOGIN_NAME_MAX() (-1)
93 static const char *next_brace_sub (const char *begin
, int flags
) __THROWNL
;
95 typedef uint_fast8_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)
196 /* Set *R = A + B. Return true if the answer is mathematically
197 incorrect due to overflow; in this case, *R is the low order
198 bits of the correct answer. */
201 size_add_wrapv (size_t a
, size_t b
, size_t *r
)
203 #if 5 <= __GNUC__ && !defined __ICC
204 return __builtin_add_overflow (a
, b
, r
);
212 glob_use_alloca (size_t alloca_used
, size_t len
)
215 return (!size_add_wrapv (alloca_used
, len
, &size
)
216 && __libc_use_alloca (size
));
219 static int glob_in_dir (const char *pattern
, const char *directory
,
220 int flags
, int (*errfunc
) (const char *, int),
221 glob_t
*pglob
, size_t alloca_used
);
222 extern int __glob_pattern_type (const char *pattern
, int quote
)
225 static int prefix_array (const char *prefix
, char **array
, size_t n
) __THROWNL
;
226 static int collated_compare (const void *, const void *) __THROWNL
;
229 /* Find the end of the sub-pattern in a brace expression. */
231 next_brace_sub (const char *cp
, int flags
)
235 if ((flags
& GLOB_NOESCAPE
) == 0 && *cp
== '\\')
243 if ((*cp
== '}' && depth
-- == 0) || (*cp
== ',' && depth
== 0))
250 return *cp
!= '\0' ? cp
: NULL
;
254 /* Do glob searching for PATTERN, placing results in PGLOB.
255 The bits defined above may be set in FLAGS.
256 If a directory cannot be opened or read and ERRFUNC is not nil,
257 it is called with the pathname that caused the error, and the
258 'errno' value from the failing call; if it returns non-zero
259 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
260 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
261 Otherwise, 'glob' returns zero. */
263 #ifdef GLOB_ATTRIBUTE
266 glob (const char *pattern
, int flags
, int (*errfunc
) (const char *, int),
269 const char *filename
;
270 char *dirname
= NULL
;
275 int dirname_modified
;
276 int malloc_dirname
= 0;
279 size_t alloca_used
= 0;
281 if (pattern
== NULL
|| pglob
== NULL
|| (flags
& ~__GLOB_FLAGS
) != 0)
283 __set_errno (EINVAL
);
287 /* POSIX requires all slashes to be matched. This means that with
288 a trailing slash we must match only directories. */
289 if (pattern
[0] && pattern
[strlen (pattern
) - 1] == '/')
290 flags
|= GLOB_ONLYDIR
;
292 if (!(flags
& GLOB_DOOFFS
))
293 /* Have to do this so 'globfree' knows where to start freeing. It
294 also makes all the code that uses gl_offs simpler. */
297 if (!(flags
& GLOB_APPEND
))
300 if (!(flags
& GLOB_DOOFFS
))
301 pglob
->gl_pathv
= NULL
;
306 if (pglob
->gl_offs
>= ~((size_t) 0) / sizeof (char *))
309 pglob
->gl_pathv
= (char **) malloc ((pglob
->gl_offs
+ 1)
311 if (pglob
->gl_pathv
== NULL
)
314 for (i
= 0; i
<= pglob
->gl_offs
; ++i
)
315 pglob
->gl_pathv
[i
] = NULL
;
319 if (flags
& GLOB_BRACE
)
323 if (flags
& GLOB_NOESCAPE
)
324 begin
= strchr (pattern
, '{');
336 if (*begin
== '\\' && begin
[1] != '\0')
338 else if (*begin
== '{')
347 /* Allocate working buffer large enough for our work. Note that
348 we have at least an opening and closing brace. */
356 size_t pattern_len
= strlen (pattern
) - 1;
357 int alloca_onealt
= glob_use_alloca (alloca_used
, pattern_len
);
359 onealt
= alloca_account (pattern_len
, alloca_used
);
362 onealt
= malloc (pattern_len
);
367 /* We know the prefix for all sub-patterns. */
368 alt_start
= mempcpy (onealt
, pattern
, begin
- pattern
);
370 /* Find the first sub-pattern and at the same time find the
371 rest after the closing brace. */
372 next
= next_brace_sub (begin
+ 1, flags
);
375 /* It is an invalid expression. */
377 if (__glibc_unlikely (!alloca_onealt
))
379 flags
&= ~GLOB_BRACE
;
383 /* Now find the end of the whole brace expression. */
387 rest
= next_brace_sub (rest
+ 1, flags
);
389 /* It is an illegal expression. */
392 /* Please note that we now can be sure the brace expression
394 rest_len
= strlen (++rest
) + 1;
396 /* We have a brace expression. BEGIN points to the opening {,
397 NEXT points past the terminator of the first element, and END
398 points past the final }. We will accumulate result names from
399 recursive runs for each brace alternative in the buffer using
401 firstc
= pglob
->gl_pathc
;
408 /* Construct the new glob expression. */
409 mempcpy (mempcpy (alt_start
, p
, next
- p
), rest
, rest_len
);
411 result
= glob (onealt
,
412 ((flags
& ~(GLOB_NOCHECK
| GLOB_NOMAGIC
))
413 | GLOB_APPEND
), errfunc
, pglob
);
415 /* If we got an error, return it. */
416 if (result
&& result
!= GLOB_NOMATCH
)
418 if (__glibc_unlikely (!alloca_onealt
))
420 if (!(flags
& GLOB_APPEND
))
429 /* We saw the last entry. */
433 next
= next_brace_sub (p
, flags
);
434 assert (next
!= NULL
);
437 if (__glibc_unlikely (!alloca_onealt
))
440 if (pglob
->gl_pathc
!= firstc
)
441 /* We found some entries. */
443 else if (!(flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
449 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
451 /* Find the filename. */
452 filename
= strrchr (pattern
, '/');
454 #if defined __MSDOS__ || defined WINDOWS32
455 /* The case of "d:pattern". Since ':' is not allowed in
456 file names, we can safely assume that wherever it
457 happens in pattern, it signals the filename part. This
458 is so we could some day support patterns like "[a-z]:foo". */
459 if (filename
== NULL
)
460 filename
= strchr (pattern
, ':');
461 #endif /* __MSDOS__ || WINDOWS32 */
463 dirname_modified
= 0;
464 if (filename
== NULL
)
466 /* This can mean two things: a simple name or "~name". The latter
467 case is nothing but a notation for a directory. */
468 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && pattern
[0] == '~')
470 dirname
= (char *) pattern
;
471 dirlen
= strlen (pattern
);
473 /* Set FILENAME to NULL as a special flag. This is ugly but
474 other solutions would require much more code. We test for
475 this special case below. */
480 if (__glibc_unlikely (pattern
[0] == '\0'))
482 dirs
.gl_pathv
= NULL
;
487 dirname
= (char *) ".";
491 else if (filename
== pattern
492 || (filename
== pattern
+ 1 && pattern
[0] == '\\'
493 && (flags
& GLOB_NOESCAPE
) == 0))
495 /* "/pattern" or "\\/pattern". */
496 dirname
= (char *) "/";
503 dirlen
= filename
- pattern
;
504 #if defined __MSDOS__ || defined WINDOWS32
506 || (filename
> pattern
+ 1 && filename
[-1] == ':'))
511 drive_spec
= __alloca (dirlen
+ 1);
512 *((char *) mempcpy (drive_spec
, pattern
, dirlen
)) = '\0';
513 /* For now, disallow wildcards in the drive spec, to
514 prevent infinite recursion in glob. */
515 if (__glob_pattern_p (drive_spec
, !(flags
& GLOB_NOESCAPE
)))
517 /* If this is "d:pattern", we need to copy ':' to DIRNAME
518 as well. If it's "d:/pattern", don't remove the slash
519 from "d:/", since "d:" and "d:/" are not the same.*/
523 if (glob_use_alloca (alloca_used
, dirlen
+ 1))
524 newp
= alloca_account (dirlen
+ 1, alloca_used
);
527 newp
= malloc (dirlen
+ 1);
532 *((char *) mempcpy (newp
, pattern
, dirlen
)) = '\0';
536 #if defined __MSDOS__ || defined WINDOWS32
537 bool drive_root
= (dirlen
> 1
538 && (dirname
[dirlen
- 1] == ':'
539 || (dirlen
> 2 && dirname
[dirlen
- 2] == ':'
540 && dirname
[dirlen
- 1] == '/')));
542 bool drive_root
= false;
545 if (filename
[0] == '\0' && dirlen
> 1 && !drive_root
)
546 /* "pattern/". Expand "pattern", appending slashes. */
548 int orig_flags
= flags
;
549 if (!(flags
& GLOB_NOESCAPE
) && dirname
[dirlen
- 1] == '\\')
551 /* "pattern\\/". Remove the final backslash if it hasn't
553 char *p
= (char *) &dirname
[dirlen
- 1];
555 while (p
> dirname
&& p
[-1] == '\\') --p
;
556 if ((&dirname
[dirlen
] - p
) & 1)
558 *(char *) &dirname
[--dirlen
] = '\0';
559 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
562 int val
= glob (dirname
, flags
| GLOB_MARK
, errfunc
, pglob
);
564 pglob
->gl_flags
= ((pglob
->gl_flags
& ~GLOB_MARK
)
565 | (flags
& GLOB_MARK
));
566 else if (val
== GLOB_NOMATCH
&& flags
!= orig_flags
)
568 /* Make sure globfree (&dirs); is a nop. */
569 dirs
.gl_pathv
= NULL
;
571 oldcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
579 if ((flags
& (GLOB_TILDE
|GLOB_TILDE_CHECK
)) && dirname
[0] == '~')
581 if (dirname
[1] == '\0' || dirname
[1] == '/'
582 || (!(flags
& GLOB_NOESCAPE
) && dirname
[1] == '\\'
583 && (dirname
[2] == '\0' || dirname
[2] == '/')))
585 /* Look up home directory. */
586 char *home_dir
= getenv ("HOME");
587 int malloc_home_dir
= 0;
588 if (home_dir
== NULL
|| home_dir
[0] == '\0')
591 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
592 preference to HOME, because the user can change HOME. */
593 const char *home_drive
= getenv ("HOMEDRIVE");
594 const char *home_path
= getenv ("HOMEPATH");
596 if (home_drive
!= NULL
&& home_path
!= NULL
)
598 size_t home_drive_len
= strlen (home_drive
);
599 size_t home_path_len
= strlen (home_path
);
600 char *mem
= alloca (home_drive_len
+ home_path_len
+ 1);
602 memcpy (mem
, home_drive
, home_drive_len
);
603 memcpy (mem
+ home_drive_len
, home_path
, home_path_len
+ 1);
607 home_dir
= "c:/users/default"; /* poor default */
612 size_t buflen
= GET_LOGIN_NAME_MAX () + 1;
615 /* 'sysconf' does not support _SC_LOGIN_NAME_MAX. Try
618 if (glob_use_alloca (alloca_used
, buflen
))
619 name
= alloca_account (buflen
, alloca_used
);
622 name
= malloc (buflen
);
625 retval
= GLOB_NOSPACE
;
631 success
= __getlogin_r (name
, buflen
) == 0;
635 char *malloc_pwtmpbuf
= NULL
;
637 # if defined HAVE_GETPWNAM_R || defined _LIBC
638 long int pwbuflenmax
= GETPW_R_SIZE_MAX ();
639 size_t pwbuflen
= pwbuflenmax
;
644 if (! (0 < pwbuflenmax
&& pwbuflenmax
<= SIZE_MAX
))
645 /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.
646 Try a moderate value. */
649 if (glob_use_alloca (alloca_used
, pwbuflen
))
650 pwtmpbuf
= alloca_account (pwbuflen
, alloca_used
);
653 pwtmpbuf
= malloc (pwbuflen
);
654 if (pwtmpbuf
== NULL
)
656 if (__glibc_unlikely (malloc_name
))
658 retval
= GLOB_NOSPACE
;
661 malloc_pwtmpbuf
= pwtmpbuf
;
664 while (getpwnam_r (name
, &pwbuf
, pwtmpbuf
, pwbuflen
, &p
)
674 v
= size_add_wrapv (pwbuflen
, pwbuflen
, &newlen
);
675 if (!v
&& malloc_pwtmpbuf
== NULL
676 && glob_use_alloca (alloca_used
, newlen
))
677 pwtmpbuf
= extend_alloca_account (pwtmpbuf
, pwbuflen
,
678 newlen
, alloca_used
);
681 char *newp
= (v
? NULL
682 : realloc (malloc_pwtmpbuf
, newlen
));
685 free (malloc_pwtmpbuf
);
686 if (__glibc_unlikely (malloc_name
))
688 retval
= GLOB_NOSPACE
;
691 malloc_pwtmpbuf
= pwtmpbuf
= newp
;
699 if (__glibc_unlikely (malloc_name
))
703 if (malloc_pwtmpbuf
== NULL
)
704 home_dir
= p
->pw_dir
;
707 size_t home_dir_len
= strlen (p
->pw_dir
) + 1;
708 if (glob_use_alloca (alloca_used
, home_dir_len
))
709 home_dir
= alloca_account (home_dir_len
,
713 home_dir
= malloc (home_dir_len
);
714 if (home_dir
== NULL
)
717 retval
= GLOB_NOSPACE
;
722 memcpy (home_dir
, p
->pw_dir
, home_dir_len
);
725 free (malloc_pwtmpbuf
);
729 if (__glibc_unlikely (malloc_name
))
732 #endif /* WINDOWS32 */
734 if (home_dir
== NULL
|| home_dir
[0] == '\0')
736 if (__glibc_unlikely (malloc_home_dir
))
738 if (flags
& GLOB_TILDE_CHECK
)
740 retval
= GLOB_NOMATCH
;
745 home_dir
= (char *) "~"; /* No luck. */
749 /* Now construct the full directory. */
750 if (dirname
[1] == '\0')
752 if (__glibc_unlikely (malloc_dirname
))
756 dirlen
= strlen (dirname
);
757 malloc_dirname
= malloc_home_dir
;
762 size_t home_len
= strlen (home_dir
);
763 int use_alloca
= glob_use_alloca (alloca_used
, home_len
+ dirlen
);
765 newp
= alloca_account (home_len
+ dirlen
, alloca_used
);
768 newp
= malloc (home_len
+ dirlen
);
771 if (__glibc_unlikely (malloc_home_dir
))
773 retval
= GLOB_NOSPACE
;
778 mempcpy (mempcpy (newp
, home_dir
, home_len
),
779 &dirname
[1], dirlen
);
781 if (__glibc_unlikely (malloc_dirname
))
785 dirlen
+= home_len
- 1;
786 malloc_dirname
= !use_alloca
;
788 if (__glibc_unlikely (malloc_home_dir
))
791 dirname_modified
= 1;
796 char *end_name
= strchr (dirname
, '/');
798 int malloc_user_name
= 0;
799 char *unescape
= NULL
;
801 if (!(flags
& GLOB_NOESCAPE
))
803 if (end_name
== NULL
)
805 unescape
= strchr (dirname
, '\\');
807 end_name
= strchr (unescape
, '\0');
810 unescape
= memchr (dirname
, '\\', end_name
- dirname
);
812 if (end_name
== NULL
)
813 user_name
= dirname
+ 1;
817 if (glob_use_alloca (alloca_used
, end_name
- dirname
))
818 newp
= alloca_account (end_name
- dirname
, alloca_used
);
821 newp
= malloc (end_name
- dirname
);
824 retval
= GLOB_NOSPACE
;
827 malloc_user_name
= 1;
829 if (unescape
!= NULL
)
831 char *p
= mempcpy (newp
, dirname
+ 1,
832 unescape
- dirname
- 1);
840 /* "~fo\\o\\" unescape to user_name "foo\\",
841 but "~fo\\o\\/" unescape to user_name
843 if (filename
== NULL
)
854 *((char *) mempcpy (newp
, dirname
+ 1, end_name
- dirname
))
859 /* Look up specific user's home directory. */
862 char *malloc_pwtmpbuf
= NULL
;
863 # if defined HAVE_GETPWNAM_R || defined _LIBC
864 long int buflenmax
= GETPW_R_SIZE_MAX ();
865 size_t buflen
= buflenmax
;
871 if (! (0 <= buflenmax
&& buflenmax
<= SIZE_MAX
))
872 /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
876 if (glob_use_alloca (alloca_used
, buflen
))
877 pwtmpbuf
= alloca_account (buflen
, alloca_used
);
880 pwtmpbuf
= malloc (buflen
);
881 if (pwtmpbuf
== NULL
)
884 if (__glibc_unlikely (malloc_user_name
))
886 retval
= GLOB_NOSPACE
;
889 malloc_pwtmpbuf
= pwtmpbuf
;
892 while (getpwnam_r (user_name
, &pwbuf
, pwtmpbuf
, buflen
, &p
) != 0)
901 v
= size_add_wrapv (buflen
, buflen
, &newlen
);
902 if (!v
&& malloc_pwtmpbuf
== NULL
903 && glob_use_alloca (alloca_used
, newlen
))
904 pwtmpbuf
= extend_alloca_account (pwtmpbuf
, buflen
,
905 newlen
, alloca_used
);
908 char *newp
= v
? NULL
: realloc (malloc_pwtmpbuf
, newlen
);
911 free (malloc_pwtmpbuf
);
914 malloc_pwtmpbuf
= pwtmpbuf
= newp
;
919 p
= getpwnam (user_name
);
922 if (__glibc_unlikely (malloc_user_name
))
925 /* If we found a home directory use this. */
928 size_t home_len
= strlen (p
->pw_dir
);
929 size_t rest_len
= end_name
== NULL
? 0 : strlen (end_name
);
931 if (__glibc_unlikely (malloc_dirname
))
935 if (glob_use_alloca (alloca_used
, home_len
+ rest_len
+ 1))
936 dirname
= alloca_account (home_len
+ rest_len
+ 1,
940 dirname
= malloc (home_len
+ rest_len
+ 1);
943 free (malloc_pwtmpbuf
);
944 retval
= GLOB_NOSPACE
;
949 *((char *) mempcpy (mempcpy (dirname
, p
->pw_dir
, home_len
),
950 end_name
, rest_len
)) = '\0';
952 dirlen
= home_len
+ rest_len
;
953 dirname_modified
= 1;
955 free (malloc_pwtmpbuf
);
959 free (malloc_pwtmpbuf
);
961 if (flags
& GLOB_TILDE_CHECK
)
963 /* We have to regard it as an error if we cannot find the
965 retval
= GLOB_NOMATCH
;
970 #endif /* !WINDOWS32 */
974 /* Now test whether we looked for "~" or "~NAME". In this case we
975 can give the answer now. */
976 if (filename
== NULL
)
981 /* Return the directory if we don't check for error or if it exists. */
982 if ((flags
& GLOB_NOCHECK
)
983 || (((__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0))
984 ? ((*pglob
->gl_stat
) (dirname
, &st
) == 0
985 && S_ISDIR (st
.st_mode
))
986 : (__stat64 (dirname
, &st64
) == 0 && S_ISDIR (st64
.st_mode
)))))
988 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
991 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
994 free (pglob
->gl_pathv
);
995 pglob
->gl_pathv
= NULL
;
997 retval
= GLOB_NOSPACE
;
1001 new_gl_pathv
= realloc (pglob
->gl_pathv
,
1002 (newcount
+ 2) * sizeof (char *));
1003 if (new_gl_pathv
== NULL
)
1005 pglob
->gl_pathv
= new_gl_pathv
;
1007 if (flags
& GLOB_MARK
)
1010 pglob
->gl_pathv
[newcount
] = malloc (dirlen
+ 2);
1011 if (pglob
->gl_pathv
[newcount
] == NULL
)
1013 p
= mempcpy (pglob
->gl_pathv
[newcount
], dirname
, dirlen
);
1016 if (__glibc_unlikely (malloc_dirname
))
1021 if (__glibc_unlikely (malloc_dirname
))
1022 pglob
->gl_pathv
[newcount
] = dirname
;
1025 pglob
->gl_pathv
[newcount
] = strdup (dirname
);
1026 if (pglob
->gl_pathv
[newcount
] == NULL
)
1030 pglob
->gl_pathv
[++newcount
] = NULL
;
1032 pglob
->gl_flags
= flags
;
1038 retval
= GLOB_NOMATCH
;
1042 meta
= __glob_pattern_type (dirname
, !(flags
& GLOB_NOESCAPE
));
1043 /* meta is 1 if correct glob pattern containing metacharacters.
1044 If meta has bit (1 << 2) set, it means there was an unterminated
1045 [ which we handle the same, using fnmatch. Broken unterminated
1046 pattern bracket expressions ought to be rare enough that it is
1047 not worth special casing them, fnmatch will do the right thing. */
1050 /* The directory name contains metacharacters, so we
1051 have to glob for the directory, and then glob for
1052 the pattern in each directory found. */
1055 if (!(flags
& GLOB_NOESCAPE
) && dirlen
> 0 && dirname
[dirlen
- 1] == '\\')
1057 /* "foo\\/bar". Remove the final backslash from dirname
1058 if it has not been quoted. */
1059 char *p
= (char *) &dirname
[dirlen
- 1];
1061 while (p
> dirname
&& p
[-1] == '\\') --p
;
1062 if ((&dirname
[dirlen
] - p
) & 1)
1063 *(char *) &dirname
[--dirlen
] = '\0';
1066 if (__glibc_unlikely ((flags
& GLOB_ALTDIRFUNC
) != 0))
1068 /* Use the alternative access functions also in the recursive
1070 dirs
.gl_opendir
= pglob
->gl_opendir
;
1071 dirs
.gl_readdir
= pglob
->gl_readdir
;
1072 dirs
.gl_closedir
= pglob
->gl_closedir
;
1073 dirs
.gl_stat
= pglob
->gl_stat
;
1074 dirs
.gl_lstat
= pglob
->gl_lstat
;
1077 status
= glob (dirname
,
1078 ((flags
& (GLOB_ERR
| GLOB_NOESCAPE
1080 | GLOB_NOSORT
| GLOB_ONLYDIR
),
1084 if ((flags
& GLOB_NOCHECK
) == 0 || status
!= GLOB_NOMATCH
)
1092 /* We have successfully globbed the preceding directory name.
1093 For each name we found, call glob_in_dir on it and FILENAME,
1094 appending the results to PGLOB. */
1095 for (i
= 0; i
< dirs
.gl_pathc
; ++i
)
1099 old_pathc
= pglob
->gl_pathc
;
1100 status
= glob_in_dir (filename
, dirs
.gl_pathv
[i
],
1101 ((flags
| GLOB_APPEND
)
1102 & ~(GLOB_NOCHECK
| GLOB_NOMAGIC
)),
1103 errfunc
, pglob
, alloca_used
);
1104 if (status
== GLOB_NOMATCH
)
1105 /* No matches in this directory. Try the next. */
1112 pglob
->gl_pathc
= 0;
1117 /* Stick the directory on the front of each name. */
1118 if (prefix_array (dirs
.gl_pathv
[i
],
1119 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1120 pglob
->gl_pathc
- old_pathc
))
1124 pglob
->gl_pathc
= 0;
1125 retval
= GLOB_NOSPACE
;
1130 flags
|= GLOB_MAGCHAR
;
1132 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1133 But if we have not found any matching entry and the GLOB_NOCHECK
1134 flag was set we must return the input pattern itself. */
1135 if (pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1139 if (flags
& GLOB_NOCHECK
)
1141 size_t newcount
= pglob
->gl_pathc
+ pglob
->gl_offs
;
1142 char **new_gl_pathv
;
1144 if (newcount
> SIZE_MAX
/ sizeof (char *) - 2)
1148 retval
= GLOB_NOSPACE
;
1152 new_gl_pathv
= realloc (pglob
->gl_pathv
,
1153 (newcount
+ 2) * sizeof (char *));
1154 if (new_gl_pathv
== NULL
)
1156 pglob
->gl_pathv
= new_gl_pathv
;
1158 pglob
->gl_pathv
[newcount
] = strdup (pattern
);
1159 if (pglob
->gl_pathv
[newcount
] == NULL
)
1163 pglob
->gl_pathc
= 0;
1164 retval
= GLOB_NOSPACE
;
1171 pglob
->gl_pathv
[newcount
] = NULL
;
1172 pglob
->gl_flags
= flags
;
1177 retval
= GLOB_NOMATCH
;
1186 size_t old_pathc
= pglob
->gl_pathc
;
1187 int orig_flags
= flags
;
1191 char *p
= strchr (dirname
, '\\'), *q
;
1192 /* We need to unescape the dirname string. It is certainly
1193 allocated by alloca, as otherwise filename would be NULL
1194 or dirname wouldn't contain backslashes. */
1207 while (*p
++ != '\0');
1208 dirname_modified
= 1;
1210 if (dirname_modified
)
1211 flags
&= ~(GLOB_NOCHECK
| GLOB_NOMAGIC
);
1212 status
= glob_in_dir (filename
, dirname
, flags
, errfunc
, pglob
,
1216 if (status
== GLOB_NOMATCH
&& flags
!= orig_flags
1217 && pglob
->gl_pathc
+ pglob
->gl_offs
== oldcount
)
1219 /* Make sure globfree (&dirs); is a nop. */
1220 dirs
.gl_pathv
= NULL
;
1230 /* Stick the directory on the front of each name. */
1231 if (prefix_array (dirname
,
1232 &pglob
->gl_pathv
[old_pathc
+ pglob
->gl_offs
],
1233 pglob
->gl_pathc
- old_pathc
))
1236 pglob
->gl_pathc
= 0;
1237 retval
= GLOB_NOSPACE
;
1243 if (flags
& GLOB_MARK
)
1245 /* Append slashes to directory names. */
1250 for (i
= oldcount
; i
< pglob
->gl_pathc
+ pglob
->gl_offs
; ++i
)
1251 if ((__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1252 ? ((*pglob
->gl_stat
) (pglob
->gl_pathv
[i
], &st
) == 0
1253 && S_ISDIR (st
.st_mode
))
1254 : (__stat64 (pglob
->gl_pathv
[i
], &st64
) == 0
1255 && S_ISDIR (st64
.st_mode
))))
1257 size_t len
= strlen (pglob
->gl_pathv
[i
]) + 2;
1258 char *new = realloc (pglob
->gl_pathv
[i
], len
);
1262 pglob
->gl_pathc
= 0;
1263 retval
= GLOB_NOSPACE
;
1266 strcpy (&new[len
- 2], "/");
1267 pglob
->gl_pathv
[i
] = new;
1271 if (!(flags
& GLOB_NOSORT
))
1273 /* Sort the vector. */
1274 qsort (&pglob
->gl_pathv
[oldcount
],
1275 pglob
->gl_pathc
+ pglob
->gl_offs
- oldcount
,
1276 sizeof (char *), collated_compare
);
1280 if (__glibc_unlikely (malloc_dirname
))
1285 #if defined _LIBC && !defined glob
1286 libc_hidden_def (glob
)
1290 /* Do a collated comparison of A and B. */
1292 collated_compare (const void *a
, const void *b
)
1294 char *const *ps1
= a
; char *s1
= *ps1
;
1295 char *const *ps2
= b
; char *s2
= *ps2
;
1303 return strcoll (s1
, s2
);
1307 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1308 elements in place. Return nonzero if out of memory, zero if successful.
1309 A slash is inserted between DIRNAME and each elt of ARRAY,
1310 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1312 prefix_array (const char *dirname
, char **array
, size_t n
)
1315 size_t dirlen
= strlen (dirname
);
1316 char dirsep_char
= '/';
1318 if (dirlen
== 1 && dirname
[0] == '/')
1319 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1320 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1323 #if defined __MSDOS__ || defined WINDOWS32
1326 if (dirname
[dirlen
- 1] == '/' && dirname
[dirlen
- 2] == ':')
1327 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1329 else if (dirname
[dirlen
- 1] == ':')
1331 /* DIRNAME is "d:". Use ':' instead of '/'. */
1338 for (i
= 0; i
< n
; ++i
)
1340 size_t eltlen
= strlen (array
[i
]) + 1;
1341 char *new = malloc (dirlen
+ 1 + eltlen
);
1350 char *endp
= mempcpy (new, dirname
, dirlen
);
1351 *endp
++ = dirsep_char
;
1352 mempcpy (endp
, array
[i
], eltlen
);
1361 /* We put this in a separate function mainly to allow the memory
1362 allocated with alloca to be recycled. */
1364 __attribute_noinline__
1365 link_stat (const char *dir
, size_t dirlen
, const char *fname
,
1367 # if !defined _LIBC && !HAVE_FSTATAT
1372 size_t fnamelen
= strlen (fname
);
1373 char *fullname
= __alloca (dirlen
+ 1 + fnamelen
+ 1);
1376 mempcpy (mempcpy (mempcpy (fullname
, dir
, dirlen
), "/", 1),
1377 fname
, fnamelen
+ 1);
1379 # if !defined _LIBC && !HAVE_FSTATAT
1380 if (__builtin_expect ((flags
& GLOB_ALTDIRFUNC
) == 0, 1))
1383 return __stat64 (fullname
, &st64
);
1386 return (*pglob
->gl_stat
) (fullname
, &st
);
1389 /* Return true if DIR/FNAME exists. */
1391 link_exists_p (int dfd
, const char *dir
, size_t dirlen
, const char *fname
,
1392 glob_t
*pglob
, int flags
)
1395 # if defined _LIBC || HAVE_FSTATAT
1396 if (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0))
1397 status
= link_stat (dir
, dirlen
, fname
, pglob
);
1400 /* dfd cannot be -1 here, because dirfd never returns -1 on
1401 glibc, or on hosts that have fstatat. */
1403 status
= __fxstatat64 (_STAT_VER
, dfd
, fname
, &st64
, 0);
1406 status
= link_stat (dir
, dirlen
, fname
, pglob
, flags
);
1408 return status
== 0 || errno
== EOVERFLOW
;
1411 /* Like 'glob', but PATTERN is a final pathname component,
1412 and matches are searched for in DIRECTORY.
1413 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1414 The GLOB_APPEND flag is assumed to be set (always appends). */
1416 glob_in_dir (const char *pattern
, const char *directory
, int flags
,
1417 int (*errfunc
) (const char *, int),
1418 glob_t
*pglob
, size_t alloca_used
)
1420 size_t dirlen
= strlen (directory
);
1421 void *stream
= NULL
;
1422 # define GLOBNAMES_MEMBERS(nnames) \
1423 struct globnames *next; size_t count; char *name[nnames];
1424 struct globnames
{ GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER
) };
1425 struct { GLOBNAMES_MEMBERS (64) } init_names_buf
;
1426 struct globnames
*init_names
= (struct globnames
*) &init_names_buf
;
1427 struct globnames
*names
= init_names
;
1428 struct globnames
*names_alloca
= init_names
;
1435 alloca_used
+= sizeof init_names_buf
;
1437 init_names
->next
= NULL
;
1438 init_names
->count
= ((sizeof init_names_buf
1439 - offsetof (struct globnames
, name
))
1440 / sizeof init_names
->name
[0]);
1442 meta
= __glob_pattern_type (pattern
, !(flags
& GLOB_NOESCAPE
));
1443 if (meta
== 0 && (flags
& (GLOB_NOCHECK
|GLOB_NOMAGIC
)))
1445 /* We need not do any tests. The PATTERN contains no meta
1446 characters and we must not return an error therefore the
1447 result will always contain exactly one name. */
1448 flags
|= GLOB_NOCHECK
;
1452 /* Since we use the normal file functions we can also use stat()
1453 to verify the file is there. */
1459 size_t patlen
= strlen (pattern
);
1461 bool alloca_fullname
1462 = (! size_add_wrapv (dirlen
+ 1, patlen
+ 1, &fullsize
)
1463 && glob_use_alloca (alloca_used
, fullsize
));
1465 if (alloca_fullname
)
1466 fullname
= alloca_account (fullsize
, alloca_used
);
1469 fullname
= malloc (fullsize
);
1470 if (fullname
== NULL
)
1471 return GLOB_NOSPACE
;
1474 mempcpy (mempcpy (mempcpy (fullname
, directory
, dirlen
),
1476 pattern
, patlen
+ 1);
1477 if (((__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1478 ? (*pglob
->gl_stat
) (fullname
, &ust
.st
)
1479 : __stat64 (fullname
, &ust
.st64
))
1481 || errno
== EOVERFLOW
)
1482 /* We found this file to be existing. Now tell the rest
1483 of the function to copy this name into the result. */
1484 flags
|= GLOB_NOCHECK
;
1486 if (__glibc_unlikely (!alloca_fullname
))
1491 stream
= (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1492 ? (*pglob
->gl_opendir
) (directory
)
1493 : opendir (directory
));
1496 if (errno
!= ENOTDIR
1497 && ((errfunc
!= NULL
&& (*errfunc
) (directory
, errno
))
1498 || (flags
& GLOB_ERR
)))
1499 return GLOB_ABORTED
;
1503 int dfd
= (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0)
1504 ? -1 : dirfd ((DIR *) stream
));
1505 int fnm_flags
= ((!(flags
& GLOB_PERIOD
) ? FNM_PERIOD
: 0)
1506 | ((flags
& GLOB_NOESCAPE
) ? FNM_NOESCAPE
: 0));
1507 flags
|= GLOB_MAGCHAR
;
1511 struct readdir_result d
;
1513 if (__builtin_expect (flags
& GLOB_ALTDIRFUNC
, 0))
1514 d
= convert_dirent (GL_READDIR (pglob
, stream
));
1517 #ifdef COMPILE_GLOB64
1518 d
= convert_dirent (__readdir (stream
));
1520 d
= convert_dirent64 (__readdir64 (stream
));
1527 /* If we shall match only directories use the information
1528 provided by the dirent call if possible. */
1529 if (flags
& GLOB_ONLYDIR
)
1530 switch (readdir_result_type (d
))
1532 case DT_DIR
: case DT_LNK
: case DT_UNKNOWN
: break;
1536 if (fnmatch (pattern
, d
.name
, fnm_flags
) == 0)
1538 /* If the file we found is a symlink we have to
1539 make sure the target file exists. */
1540 dirent_type type
= readdir_result_type (d
);
1541 if (! (type
== DT_LNK
|| type
== DT_UNKNOWN
)
1542 || link_exists_p (dfd
, directory
, dirlen
, d
.name
,
1545 if (cur
== names
->count
)
1547 struct globnames
*newnames
;
1548 size_t count
= names
->count
* 2;
1549 size_t nameoff
= offsetof (struct globnames
, name
);
1550 size_t size
= FLEXSIZEOF (struct globnames
, name
,
1551 count
* sizeof (char *));
1552 if ((SIZE_MAX
- nameoff
) / 2 / sizeof (char *)
1555 if (glob_use_alloca (alloca_used
, size
))
1556 newnames
= names_alloca
1557 = alloca_account (size
, alloca_used
);
1558 else if ((newnames
= malloc (size
))
1561 newnames
->count
= count
;
1562 newnames
->next
= names
;
1566 names
->name
[cur
] = strdup (d
.name
);
1567 if (names
->name
[cur
] == NULL
)
1571 if (SIZE_MAX
- pglob
->gl_offs
<= nfound
)
1579 if (nfound
== 0 && (flags
& GLOB_NOCHECK
))
1581 size_t len
= strlen (pattern
);
1583 names
->name
[cur
] = malloc (len
+ 1);
1584 if (names
->name
[cur
] == NULL
)
1586 *((char *) mempcpy (names
->name
[cur
++], pattern
, len
)) = '\0';
1589 result
= GLOB_NOMATCH
;
1592 char **new_gl_pathv
;
1595 if (SIZE_MAX
/ sizeof (char *) - pglob
->gl_pathc
1596 < pglob
->gl_offs
+ nfound
+ 1)
1600 = realloc (pglob
->gl_pathv
,
1601 (pglob
->gl_pathc
+ pglob
->gl_offs
+ nfound
+ 1)
1604 if (new_gl_pathv
== NULL
)
1609 struct globnames
*old
= names
;
1610 for (size_t i
= 0; i
< cur
; ++i
)
1611 free (names
->name
[i
]);
1612 names
= names
->next
;
1613 /* NB: we will not leak memory here if we exit without
1614 freeing the current block assigned to OLD. At least
1615 the very first block is always allocated on the stack
1616 and this is the block assigned to OLD here. */
1619 assert (old
== init_names
);
1623 if (old
== names_alloca
)
1624 names_alloca
= names
;
1628 result
= GLOB_NOSPACE
;
1634 struct globnames
*old
= names
;
1635 for (size_t i
= 0; i
< cur
; ++i
)
1636 new_gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
++]
1638 names
= names
->next
;
1639 /* NB: we will not leak memory here if we exit without
1640 freeing the current block assigned to OLD. At least
1641 the very first block is always allocated on the stack
1642 and this is the block assigned to OLD here. */
1645 assert (old
== init_names
);
1649 if (old
== names_alloca
)
1650 names_alloca
= names
;
1655 pglob
->gl_pathv
= new_gl_pathv
;
1657 pglob
->gl_pathv
[pglob
->gl_offs
+ pglob
->gl_pathc
] = NULL
;
1659 pglob
->gl_flags
= flags
;
1666 if (__glibc_unlikely (flags
& GLOB_ALTDIRFUNC
))
1667 (*pglob
->gl_closedir
) (stream
);