linux: Fail as unsupported if personality call is filtered
[glibc.git] / posix / glob.c
blobf2e359f385ff4c63265334af2db2be6b1d3aebf0
1 /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #ifndef _LIBC
20 /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
21 optimizes away the pattern == NULL test below. */
22 # define _GL_ARG_NONNULL(params)
24 # include <libc-config.h>
26 #endif
28 #include <glob.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <stdbool.h>
35 #include <stddef.h>
36 #include <stdint.h>
37 #include <assert.h>
38 #include <unistd.h>
40 #if defined _WIN32 && ! defined __CYGWIN__
41 # define WINDOWS32
42 #endif
44 #ifndef WINDOWS32
45 # include <pwd.h>
46 #endif
48 #include <errno.h>
49 #include <dirent.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <alloca.h>
54 #ifdef _LIBC
55 # undef strdup
56 # define strdup(str) __strdup (str)
57 # define sysconf(id) __sysconf (id)
58 # define closedir(dir) __closedir (dir)
59 # define opendir(name) __opendir (name)
60 # undef dirfd
61 # define dirfd(str) __dirfd (str)
62 # define readdir(str) __readdir64 (str)
63 # define getpwnam_r(name, bufp, buf, len, res) \
64 __getpwnam_r (name, bufp, buf, len, res)
65 # define FLEXIBLE_ARRAY_MEMBER
66 # ifndef struct_stat
67 # define struct_stat struct stat
68 # endif
69 # ifndef struct_stat64
70 # define struct_stat64 struct stat64
71 # endif
72 # ifndef GLOB_LSTAT
73 # define GLOB_LSTAT gl_lstat
74 # endif
75 # ifndef GLOB_FSTATAT64
76 # define GLOB_FSTATAT64 __fstatat64
77 # endif
78 # include <shlib-compat.h>
79 #else /* !_LIBC */
80 # define __glob glob
81 # define __getlogin_r(buf, len) getlogin_r (buf, len)
82 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
83 # ifndef __MVS__
84 # define __alloca alloca
85 # endif
86 # define __readdir readdir
87 # define COMPILE_GLOB64
88 # define struct_stat struct stat
89 # define struct_stat64 struct stat
90 # define GLOB_LSTAT gl_lstat
91 # define GLOB_FSTATAT64 fstatat
92 #endif /* _LIBC */
94 #include <fnmatch.h>
96 #include <flexmember.h>
97 #include <glob_internal.h>
98 #include <scratch_buffer.h>
100 static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
102 /* The type of ((struct dirent *) 0)->d_type is 'unsigned char' on most
103 platforms, but 'unsigned int' in the mingw from mingw.org. */
104 typedef uint_fast32_t dirent_type;
106 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
107 /* Any distinct values will do here.
108 Undef any existing macros out of the way. */
109 # undef DT_UNKNOWN
110 # undef DT_DIR
111 # undef DT_LNK
112 # define DT_UNKNOWN 0
113 # define DT_DIR 1
114 # define DT_LNK 2
115 #endif
117 /* A representation of a directory entry which does not depend on the
118 layout of struct dirent, or the size of ino_t. */
119 struct readdir_result
121 const char *name;
122 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
123 dirent_type type;
124 #endif
127 /* Initialize and return type member of struct readdir_result. */
128 static dirent_type
129 readdir_result_type (struct readdir_result d)
131 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
132 # define D_TYPE_TO_RESULT(source) (source)->d_type,
133 return d.type;
134 #else
135 # define D_TYPE_TO_RESULT(source)
136 return DT_UNKNOWN;
137 #endif
140 /* Construct an initializer for a struct readdir_result object from a
141 struct dirent *. No copy of the name is made. */
142 #define READDIR_RESULT_INITIALIZER(source) \
144 source->d_name, \
145 D_TYPE_TO_RESULT (source) \
148 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
149 type safety if an old interface version needs to be supported. */
150 #ifndef GL_READDIR
151 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
152 #endif
154 /* Extract name and type from directory entry. No copy of the name is
155 made. If SOURCE is NULL, result name is NULL. Keep in sync with
156 convert_dirent64 below. */
157 static struct readdir_result
158 convert_dirent (const struct dirent *source)
160 if (source == NULL)
162 struct readdir_result result = { NULL, };
163 return result;
165 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
166 return result;
169 #ifndef COMPILE_GLOB64
170 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
171 sync with convert_dirent above. */
172 static struct readdir_result
173 convert_dirent64 (const struct dirent64 *source)
175 if (source == NULL)
177 struct readdir_result result = { NULL, };
178 return result;
180 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
181 return result;
183 #endif
185 #ifndef _LIBC
186 /* The results of opendir() in this file are not used with dirfd and fchdir,
187 and we do not leak fds to any single-threaded code that could use stdio,
188 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
189 FIXME - if the kernel ever adds support for multi-thread safety for
190 avoiding standard fds, then we should use opendir_safer. */
191 # ifdef GNULIB_defined_opendir
192 # undef opendir
193 # endif
194 # ifdef GNULIB_defined_closedir
195 # undef closedir
196 # endif
198 /* Just use malloc. */
199 # define __libc_use_alloca(n) false
200 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
201 # define extend_alloca_account(buf, len, newlen, avar) \
202 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
203 #endif
205 static int
206 glob_lstat (glob_t *pglob, int flags, const char *fullname)
208 /* Use on glob-lstat-compat.c to provide a compat symbol which does not
209 use lstat / gl_lstat. */
210 union
212 struct_stat st;
213 struct_stat64 st64;
214 } ust;
215 return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
216 ? pglob->GLOB_LSTAT (fullname, &ust.st)
217 : GLOB_FSTATAT64 (AT_FDCWD, fullname, &ust.st64,
218 AT_SYMLINK_NOFOLLOW));
221 /* Set *R = A + B. Return true if the answer is mathematically
222 incorrect due to overflow; in this case, *R is the low order
223 bits of the correct answer. */
225 static bool
226 size_add_wrapv (size_t a, size_t b, size_t *r)
228 #if 7 <= __GNUC__ && !defined __ICC
229 return __builtin_add_overflow (a, b, r);
230 #else
231 *r = a + b;
232 return *r < a;
233 #endif
236 static bool
237 glob_use_alloca (size_t alloca_used, size_t len)
239 size_t size;
240 return (!size_add_wrapv (alloca_used, len, &size)
241 && __libc_use_alloca (size));
244 static int glob_in_dir (const char *pattern, const char *directory,
245 int flags, int (*errfunc) (const char *, int),
246 glob_t *pglob, size_t alloca_used);
247 static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
248 static int collated_compare (const void *, const void *) __THROWNL;
251 /* Return true if FILENAME is a directory or a symbolic link to a directory.
252 Use FLAGS and PGLOB to resolve the filename. */
253 static bool
254 is_dir (char const *filename, int flags, glob_t const *pglob)
256 struct_stat st;
257 struct_stat64 st64;
258 return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
259 ? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
260 : (GLOB_FSTATAT64 (AT_FDCWD, filename, &st64, 0) == 0
261 && S_ISDIR (st64.st_mode)));
264 /* Find the end of the sub-pattern in a brace expression. */
265 static const char *
266 next_brace_sub (const char *cp, int flags)
268 size_t depth = 0;
269 while (*cp != '\0')
270 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
272 if (*++cp == '\0')
273 break;
274 ++cp;
276 else
278 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
279 break;
281 if (*cp++ == '{')
282 depth++;
285 return *cp != '\0' ? cp : NULL;
288 #ifndef GLOB_ATTRIBUTE
289 # define GLOB_ATTRIBUTE
290 #endif
292 /* Do glob searching for PATTERN, placing results in PGLOB.
293 The bits defined above may be set in FLAGS.
294 If a directory cannot be opened or read and ERRFUNC is not nil,
295 it is called with the pathname that caused the error, and the
296 'errno' value from the failing call; if it returns non-zero
297 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
298 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
299 Otherwise, 'glob' returns zero. */
301 GLOB_ATTRIBUTE
302 __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
303 glob_t *pglob)
305 const char *filename;
306 char *dirname = NULL;
307 size_t dirlen;
308 int status;
309 size_t oldcount;
310 int meta;
311 int dirname_modified;
312 int malloc_dirname = 0;
313 glob_t dirs;
314 int retval = 0;
315 size_t alloca_used = 0;
317 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
319 __set_errno (EINVAL);
320 return -1;
323 /* POSIX requires all slashes to be matched. This means that with
324 a trailing slash we must match only directories. */
325 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
326 flags |= GLOB_ONLYDIR;
328 if (!(flags & GLOB_DOOFFS))
329 /* Have to do this so 'globfree' knows where to start freeing. It
330 also makes all the code that uses gl_offs simpler. */
331 pglob->gl_offs = 0;
333 if (!(flags & GLOB_APPEND))
335 pglob->gl_pathc = 0;
336 if (!(flags & GLOB_DOOFFS))
337 pglob->gl_pathv = NULL;
338 else
340 size_t i;
342 if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
343 return GLOB_NOSPACE;
345 pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
346 * sizeof (char *));
347 if (pglob->gl_pathv == NULL)
348 return GLOB_NOSPACE;
350 for (i = 0; i <= pglob->gl_offs; ++i)
351 pglob->gl_pathv[i] = NULL;
355 if (flags & GLOB_BRACE)
357 const char *begin;
359 if (flags & GLOB_NOESCAPE)
360 begin = strchr (pattern, '{');
361 else
363 begin = pattern;
364 while (1)
366 if (*begin == '\0')
368 begin = NULL;
369 break;
372 if (*begin == '\\' && begin[1] != '\0')
373 ++begin;
374 else if (*begin == '{')
375 break;
377 ++begin;
381 if (begin != NULL)
383 /* Allocate working buffer large enough for our work. Note that
384 we have at least an opening and closing brace. */
385 size_t firstc;
386 char *alt_start;
387 const char *p;
388 const char *next;
389 const char *rest;
390 size_t rest_len;
391 char *onealt;
392 size_t pattern_len = strlen (pattern) - 1;
393 int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
394 if (alloca_onealt)
395 onealt = alloca_account (pattern_len, alloca_used);
396 else
398 onealt = malloc (pattern_len);
399 if (onealt == NULL)
400 return GLOB_NOSPACE;
403 /* We know the prefix for all sub-patterns. */
404 alt_start = mempcpy (onealt, pattern, begin - pattern);
406 /* Find the first sub-pattern and at the same time find the
407 rest after the closing brace. */
408 next = next_brace_sub (begin + 1, flags);
409 if (next == NULL)
411 /* It is an invalid expression. */
412 illegal_brace:
413 if (__glibc_unlikely (!alloca_onealt))
414 free (onealt);
415 flags &= ~GLOB_BRACE;
416 goto no_brace;
419 /* Now find the end of the whole brace expression. */
420 rest = next;
421 while (*rest != '}')
423 rest = next_brace_sub (rest + 1, flags);
424 if (rest == NULL)
425 /* It is an illegal expression. */
426 goto illegal_brace;
428 /* Please note that we now can be sure the brace expression
429 is well-formed. */
430 rest_len = strlen (++rest) + 1;
432 /* We have a brace expression. BEGIN points to the opening {,
433 NEXT points past the terminator of the first element, and END
434 points past the final }. We will accumulate result names from
435 recursive runs for each brace alternative in the buffer using
436 GLOB_APPEND. */
437 firstc = pglob->gl_pathc;
439 p = begin + 1;
440 while (1)
442 int result;
444 /* Construct the new glob expression. */
445 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
447 result = __glob (onealt,
448 ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
449 | GLOB_APPEND),
450 errfunc, pglob);
452 /* If we got an error, return it. */
453 if (result && result != GLOB_NOMATCH)
455 if (__glibc_unlikely (!alloca_onealt))
456 free (onealt);
457 if (!(flags & GLOB_APPEND))
459 globfree (pglob);
460 pglob->gl_pathc = 0;
462 return result;
465 if (*next == '}')
466 /* We saw the last entry. */
467 break;
469 p = next + 1;
470 next = next_brace_sub (p, flags);
471 assert (next != NULL);
474 if (__glibc_unlikely (!alloca_onealt))
475 free (onealt);
477 if (pglob->gl_pathc != firstc)
478 /* We found some entries. */
479 return 0;
480 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
481 return GLOB_NOMATCH;
485 no_brace:
486 oldcount = pglob->gl_pathc + pglob->gl_offs;
488 /* Find the filename. */
489 filename = strrchr (pattern, '/');
491 #if defined __MSDOS__ || defined WINDOWS32
492 /* The case of "d:pattern". Since ':' is not allowed in
493 file names, we can safely assume that wherever it
494 happens in pattern, it signals the filename part. This
495 is so we could some day support patterns like "[a-z]:foo". */
496 if (filename == NULL)
497 filename = strchr (pattern, ':');
498 #endif /* __MSDOS__ || WINDOWS32 */
500 dirname_modified = 0;
501 if (filename == NULL)
503 /* This can mean two things: a simple name or "~name". The latter
504 case is nothing but a notation for a directory. */
505 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
507 dirname = (char *) pattern;
508 dirlen = strlen (pattern);
510 /* Set FILENAME to NULL as a special flag. This is ugly but
511 other solutions would require much more code. We test for
512 this special case below. */
513 filename = NULL;
515 else
517 if (__glibc_unlikely (pattern[0] == '\0'))
519 dirs.gl_pathv = NULL;
520 goto no_matches;
523 filename = pattern;
524 dirname = (char *) ".";
525 dirlen = 0;
528 else if (filename == pattern
529 || (filename == pattern + 1 && pattern[0] == '\\'
530 && (flags & GLOB_NOESCAPE) == 0))
532 /* "/pattern" or "\\/pattern". */
533 dirname = (char *) "/";
534 dirlen = 1;
535 ++filename;
537 else
539 char *newp;
540 dirlen = filename - pattern;
541 #if defined __MSDOS__ || defined WINDOWS32
542 if (*filename == ':'
543 || (filename > pattern + 1 && filename[-1] == ':'))
545 char *drive_spec;
547 ++dirlen;
548 drive_spec = __alloca (dirlen + 1);
549 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
550 /* For now, disallow wildcards in the drive spec, to
551 prevent infinite recursion in glob. */
552 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
553 return GLOB_NOMATCH;
554 /* If this is "d:pattern", we need to copy ':' to DIRNAME
555 as well. If it's "d:/pattern", don't remove the slash
556 from "d:/", since "d:" and "d:/" are not the same.*/
558 #endif
560 if (glob_use_alloca (alloca_used, dirlen + 1))
561 newp = alloca_account (dirlen + 1, alloca_used);
562 else
564 newp = malloc (dirlen + 1);
565 if (newp == NULL)
566 return GLOB_NOSPACE;
567 malloc_dirname = 1;
569 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
570 dirname = newp;
571 ++filename;
573 #if defined __MSDOS__ || defined WINDOWS32
574 bool drive_root = (dirlen > 1
575 && (dirname[dirlen - 1] == ':'
576 || (dirlen > 2 && dirname[dirlen - 2] == ':'
577 && dirname[dirlen - 1] == '/')));
578 #else
579 bool drive_root = false;
580 #endif
582 if (filename[0] == '\0' && dirlen > 1 && !drive_root)
583 /* "pattern/". Expand "pattern", appending slashes. */
585 int orig_flags = flags;
586 if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
588 /* "pattern\\/". Remove the final backslash if it hasn't
589 been quoted. */
590 char *p = (char *) &dirname[dirlen - 1];
592 while (p > dirname && p[-1] == '\\') --p;
593 if ((&dirname[dirlen] - p) & 1)
595 *(char *) &dirname[--dirlen] = '\0';
596 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
599 int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob);
600 if (val == 0)
601 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
602 | (flags & GLOB_MARK));
603 else if (val == GLOB_NOMATCH && flags != orig_flags)
605 /* Make sure globfree (&dirs); is a nop. */
606 dirs.gl_pathv = NULL;
607 flags = orig_flags;
608 oldcount = pglob->gl_pathc + pglob->gl_offs;
609 goto no_matches;
611 retval = val;
612 goto out;
616 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
618 if (dirname[1] == '\0' || dirname[1] == '/'
619 || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
620 && (dirname[2] == '\0' || dirname[2] == '/')))
622 /* Look up home directory. */
623 char *home_dir = getenv ("HOME");
624 int malloc_home_dir = 0;
625 if (home_dir == NULL || home_dir[0] == '\0')
627 #ifdef WINDOWS32
628 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
629 preference to HOME, because the user can change HOME. */
630 const char *home_drive = getenv ("HOMEDRIVE");
631 const char *home_path = getenv ("HOMEPATH");
633 if (home_drive != NULL && home_path != NULL)
635 size_t home_drive_len = strlen (home_drive);
636 size_t home_path_len = strlen (home_path);
637 char *mem = alloca (home_drive_len + home_path_len + 1);
639 memcpy (mem, home_drive, home_drive_len);
640 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
641 home_dir = mem;
643 else
644 home_dir = "c:/users/default"; /* poor default */
645 #else
646 int err;
647 struct passwd *p;
648 struct passwd pwbuf;
649 struct scratch_buffer s;
650 scratch_buffer_init (&s);
651 while (true)
653 p = NULL;
654 err = __getlogin_r (s.data, s.length);
655 if (err == 0)
657 # if defined HAVE_GETPWNAM_R || defined _LIBC
658 size_t ssize = strlen (s.data) + 1;
659 char *sdata = s.data;
660 err = getpwnam_r (sdata, &pwbuf, sdata + ssize,
661 s.length - ssize, &p);
662 # else
663 p = getpwnam (s.data);
664 if (p == NULL)
665 err = errno;
666 # endif
668 if (err != ERANGE)
669 break;
670 if (!scratch_buffer_grow (&s))
672 retval = GLOB_NOSPACE;
673 goto out;
676 if (err == 0)
678 home_dir = strdup (p->pw_dir);
679 malloc_home_dir = 1;
681 scratch_buffer_free (&s);
682 if (err == 0 && home_dir == NULL)
684 retval = GLOB_NOSPACE;
685 goto out;
687 #endif /* WINDOWS32 */
689 if (home_dir == NULL || home_dir[0] == '\0')
691 if (__glibc_unlikely (malloc_home_dir))
692 free (home_dir);
693 if (flags & GLOB_TILDE_CHECK)
695 retval = GLOB_NOMATCH;
696 goto out;
698 else
700 home_dir = (char *) "~"; /* No luck. */
701 malloc_home_dir = 0;
704 /* Now construct the full directory. */
705 if (dirname[1] == '\0')
707 if (__glibc_unlikely (malloc_dirname))
708 free (dirname);
710 dirname = home_dir;
711 dirlen = strlen (dirname);
712 malloc_dirname = malloc_home_dir;
714 else
716 char *newp;
717 size_t home_len = strlen (home_dir);
718 int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
719 if (use_alloca)
720 newp = alloca_account (home_len + dirlen, alloca_used);
721 else
723 newp = malloc (home_len + dirlen);
724 if (newp == NULL)
726 if (__glibc_unlikely (malloc_home_dir))
727 free (home_dir);
728 retval = GLOB_NOSPACE;
729 goto out;
733 mempcpy (mempcpy (newp, home_dir, home_len),
734 &dirname[1], dirlen);
736 if (__glibc_unlikely (malloc_dirname))
737 free (dirname);
739 dirname = newp;
740 dirlen += home_len - 1;
741 malloc_dirname = !use_alloca;
743 if (__glibc_unlikely (malloc_home_dir))
744 free (home_dir);
746 dirname_modified = 1;
748 else
750 #ifndef WINDOWS32
751 /* Recognize ~user as a shorthand for the specified user's home
752 directory. */
753 char *end_name = strchr (dirname, '/');
754 char *user_name;
755 int malloc_user_name = 0;
756 char *unescape = NULL;
758 if (!(flags & GLOB_NOESCAPE))
760 if (end_name == NULL)
762 unescape = strchr (dirname, '\\');
763 if (unescape)
764 end_name = strchr (unescape, '\0');
766 else
767 unescape = memchr (dirname, '\\', end_name - dirname);
769 if (end_name == NULL)
770 user_name = dirname + 1;
771 else
773 char *newp;
774 if (glob_use_alloca (alloca_used, end_name - dirname))
775 newp = alloca_account (end_name - dirname, alloca_used);
776 else
778 newp = malloc (end_name - dirname);
779 if (newp == NULL)
781 retval = GLOB_NOSPACE;
782 goto out;
784 malloc_user_name = 1;
786 if (unescape != NULL)
788 char *p = mempcpy (newp, dirname + 1,
789 unescape - dirname - 1);
790 char *q = unescape;
791 while (q != end_name)
793 if (*q == '\\')
795 if (q + 1 == end_name)
797 /* "~fo\\o\\" unescape to user_name "foo\\",
798 but "~fo\\o\\/" unescape to user_name
799 "foo". */
800 if (filename == NULL)
801 *p++ = '\\';
802 break;
804 ++q;
806 *p++ = *q++;
808 *p = '\0';
810 else
811 *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
812 = '\0';
813 user_name = newp;
816 /* Look up specific user's home directory. */
818 struct passwd *p;
819 struct scratch_buffer pwtmpbuf;
820 scratch_buffer_init (&pwtmpbuf);
822 # if defined HAVE_GETPWNAM_R || defined _LIBC
823 struct passwd pwbuf;
825 while (getpwnam_r (user_name, &pwbuf,
826 pwtmpbuf.data, pwtmpbuf.length, &p)
827 == ERANGE)
829 if (!scratch_buffer_grow (&pwtmpbuf))
831 retval = GLOB_NOSPACE;
832 goto out;
835 # else
836 p = getpwnam (user_name);
837 # endif
839 if (__glibc_unlikely (malloc_user_name))
840 free (user_name);
842 /* If we found a home directory use this. */
843 if (p != NULL)
845 size_t home_len = strlen (p->pw_dir);
846 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
847 /* dirname contains end_name; we can't free it now. */
848 char *prev_dirname =
849 (__glibc_unlikely (malloc_dirname) ? dirname : NULL);
850 char *d;
852 malloc_dirname = 0;
854 if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
855 dirname = alloca_account (home_len + rest_len + 1,
856 alloca_used);
857 else
859 dirname = malloc (home_len + rest_len + 1);
860 if (dirname == NULL)
862 free (prev_dirname);
863 scratch_buffer_free (&pwtmpbuf);
864 retval = GLOB_NOSPACE;
865 goto out;
867 malloc_dirname = 1;
869 d = mempcpy (dirname, p->pw_dir, home_len);
870 if (end_name != NULL)
871 d = mempcpy (d, end_name, rest_len);
872 *d = '\0';
874 free (prev_dirname);
876 dirlen = home_len + rest_len;
877 dirname_modified = 1;
879 else
881 if (flags & GLOB_TILDE_CHECK)
883 /* We have to regard it as an error if we cannot find the
884 home directory. */
885 retval = GLOB_NOMATCH;
886 goto out;
889 scratch_buffer_free (&pwtmpbuf);
891 #else /* WINDOWS32 */
892 /* On native Windows, access to a user's home directory
893 (via GetUserProfileDirectory) or to a user's environment
894 variables (via ExpandEnvironmentStringsForUser) requires
895 the credentials of the user. Therefore we cannot support
896 the ~user syntax on this platform.
897 Handling ~user specially (and treat it like plain ~) if
898 user is getenv ("USERNAME") would not be a good idea,
899 since it would make people think that ~user is supported
900 in general. */
901 if (flags & GLOB_TILDE_CHECK)
903 retval = GLOB_NOMATCH;
904 goto out;
906 #endif /* WINDOWS32 */
910 /* Now test whether we looked for "~" or "~NAME". In this case we
911 can give the answer now. */
912 if (filename == NULL)
914 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
915 char **new_gl_pathv;
917 if (newcount > SIZE_MAX / sizeof (char *) - 2)
919 nospace:
920 free (pglob->gl_pathv);
921 pglob->gl_pathv = NULL;
922 pglob->gl_pathc = 0;
923 retval = GLOB_NOSPACE;
924 goto out;
927 new_gl_pathv = realloc (pglob->gl_pathv,
928 (newcount + 2) * sizeof (char *));
929 if (new_gl_pathv == NULL)
930 goto nospace;
931 pglob->gl_pathv = new_gl_pathv;
933 if (flags & GLOB_MARK && is_dir (dirname, flags, pglob))
935 char *p;
936 pglob->gl_pathv[newcount] = malloc (dirlen + 2);
937 if (pglob->gl_pathv[newcount] == NULL)
938 goto nospace;
939 p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
940 p[0] = '/';
941 p[1] = '\0';
942 if (__glibc_unlikely (malloc_dirname))
943 free (dirname);
945 else
947 if (__glibc_unlikely (malloc_dirname))
948 pglob->gl_pathv[newcount] = dirname;
949 else
951 pglob->gl_pathv[newcount] = strdup (dirname);
952 if (pglob->gl_pathv[newcount] == NULL)
953 goto nospace;
956 pglob->gl_pathv[++newcount] = NULL;
957 ++pglob->gl_pathc;
958 pglob->gl_flags = flags;
960 return 0;
963 meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
964 /* meta is 1 if correct glob pattern containing metacharacters.
965 If meta has bit (1 << 2) set, it means there was an unterminated
966 [ which we handle the same, using fnmatch. Broken unterminated
967 pattern bracket expressions ought to be rare enough that it is
968 not worth special casing them, fnmatch will do the right thing. */
969 if (meta & (GLOBPAT_SPECIAL | GLOBPAT_BRACKET))
971 /* The directory name contains metacharacters, so we
972 have to glob for the directory, and then glob for
973 the pattern in each directory found. */
974 size_t i;
976 if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
978 /* "foo\\/bar". Remove the final backslash from dirname
979 if it has not been quoted. */
980 char *p = (char *) &dirname[dirlen - 1];
982 while (p > dirname && p[-1] == '\\') --p;
983 if ((&dirname[dirlen] - p) & 1)
984 *(char *) &dirname[--dirlen] = '\0';
987 if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
989 /* Use the alternative access functions also in the recursive
990 call. */
991 dirs.gl_opendir = pglob->gl_opendir;
992 dirs.gl_readdir = pglob->gl_readdir;
993 dirs.gl_closedir = pglob->gl_closedir;
994 dirs.gl_stat = pglob->gl_stat;
995 dirs.gl_lstat = pglob->gl_lstat;
998 status = __glob (dirname,
999 ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
1000 | GLOB_NOSORT | GLOB_ONLYDIR),
1001 errfunc, &dirs);
1002 if (status != 0)
1004 if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
1006 retval = status;
1007 goto out;
1009 goto no_matches;
1012 /* We have successfully globbed the preceding directory name.
1013 For each name we found, call glob_in_dir on it and FILENAME,
1014 appending the results to PGLOB. */
1015 for (i = 0; i < dirs.gl_pathc; ++i)
1017 size_t old_pathc;
1019 old_pathc = pglob->gl_pathc;
1020 status = glob_in_dir (filename, dirs.gl_pathv[i],
1021 ((flags | GLOB_APPEND)
1022 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
1023 errfunc, pglob, alloca_used);
1024 if (status == GLOB_NOMATCH)
1025 /* No matches in this directory. Try the next. */
1026 continue;
1028 if (status != 0)
1030 globfree (&dirs);
1031 globfree (pglob);
1032 pglob->gl_pathc = 0;
1033 retval = status;
1034 goto out;
1037 /* Stick the directory on the front of each name. */
1038 if (prefix_array (dirs.gl_pathv[i],
1039 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1040 pglob->gl_pathc - old_pathc))
1042 globfree (&dirs);
1043 globfree (pglob);
1044 pglob->gl_pathc = 0;
1045 retval = GLOB_NOSPACE;
1046 goto out;
1050 flags |= GLOB_MAGCHAR;
1052 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1053 But if we have not found any matching entry and the GLOB_NOCHECK
1054 flag was set we must return the input pattern itself. */
1055 if (pglob->gl_pathc + pglob->gl_offs == oldcount)
1057 no_matches:
1058 /* No matches. */
1059 if (flags & GLOB_NOCHECK)
1061 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1062 char **new_gl_pathv;
1064 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1066 nospace2:
1067 globfree (&dirs);
1068 retval = GLOB_NOSPACE;
1069 goto out;
1072 new_gl_pathv = realloc (pglob->gl_pathv,
1073 (newcount + 2) * sizeof (char *));
1074 if (new_gl_pathv == NULL)
1075 goto nospace2;
1076 pglob->gl_pathv = new_gl_pathv;
1078 pglob->gl_pathv[newcount] = strdup (pattern);
1079 if (pglob->gl_pathv[newcount] == NULL)
1081 globfree (&dirs);
1082 globfree (pglob);
1083 pglob->gl_pathc = 0;
1084 retval = GLOB_NOSPACE;
1085 goto out;
1088 ++pglob->gl_pathc;
1089 ++newcount;
1091 pglob->gl_pathv[newcount] = NULL;
1092 pglob->gl_flags = flags;
1094 else
1096 globfree (&dirs);
1097 retval = GLOB_NOMATCH;
1098 goto out;
1102 globfree (&dirs);
1104 else
1106 size_t old_pathc = pglob->gl_pathc;
1107 int orig_flags = flags;
1109 if (meta & GLOBPAT_BACKSLASH)
1111 char *p = strchr (dirname, '\\'), *q;
1112 /* We need to unescape the dirname string. It is certainly
1113 allocated by alloca, as otherwise filename would be NULL
1114 or dirname wouldn't contain backslashes. */
1115 q = p;
1118 if (*p == '\\')
1120 *q = *++p;
1121 --dirlen;
1123 else
1124 *q = *p;
1125 ++q;
1127 while (*p++ != '\0');
1128 dirname_modified = 1;
1130 if (dirname_modified)
1131 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
1132 status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
1133 alloca_used);
1134 if (status != 0)
1136 if (status == GLOB_NOMATCH && flags != orig_flags
1137 && pglob->gl_pathc + pglob->gl_offs == oldcount)
1139 /* Make sure globfree (&dirs); is a nop. */
1140 dirs.gl_pathv = NULL;
1141 flags = orig_flags;
1142 goto no_matches;
1144 retval = status;
1145 goto out;
1148 if (dirlen > 0)
1150 /* Stick the directory on the front of each name. */
1151 if (prefix_array (dirname,
1152 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1153 pglob->gl_pathc - old_pathc))
1155 globfree (pglob);
1156 pglob->gl_pathc = 0;
1157 retval = GLOB_NOSPACE;
1158 goto out;
1163 if (flags & GLOB_MARK)
1165 /* Append slashes to directory names. */
1166 size_t i;
1168 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
1169 if (is_dir (pglob->gl_pathv[i], flags, pglob))
1171 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1172 char *new = realloc (pglob->gl_pathv[i], len);
1173 if (new == NULL)
1175 globfree (pglob);
1176 pglob->gl_pathc = 0;
1177 retval = GLOB_NOSPACE;
1178 goto out;
1180 strcpy (&new[len - 2], "/");
1181 pglob->gl_pathv[i] = new;
1185 if (!(flags & GLOB_NOSORT))
1187 /* Sort the vector. */
1188 qsort (&pglob->gl_pathv[oldcount],
1189 pglob->gl_pathc + pglob->gl_offs - oldcount,
1190 sizeof (char *), collated_compare);
1193 out:
1194 if (__glibc_unlikely (malloc_dirname))
1195 free (dirname);
1197 return retval;
1199 #if defined _LIBC && !defined __glob
1200 versioned_symbol (libc, __glob, glob, GLIBC_2_27);
1201 libc_hidden_ver (__glob, glob)
1202 #endif
1205 /* Do a collated comparison of A and B. */
1206 static int
1207 collated_compare (const void *a, const void *b)
1209 char *const *ps1 = a; char *s1 = *ps1;
1210 char *const *ps2 = b; char *s2 = *ps2;
1212 if (s1 == s2)
1213 return 0;
1214 if (s1 == NULL)
1215 return 1;
1216 if (s2 == NULL)
1217 return -1;
1218 return strcoll (s1, s2);
1222 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1223 elements in place. Return nonzero if out of memory, zero if successful.
1224 A slash is inserted between DIRNAME and each elt of ARRAY,
1225 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1226 static int
1227 prefix_array (const char *dirname, char **array, size_t n)
1229 size_t i;
1230 size_t dirlen = strlen (dirname);
1231 char dirsep_char = '/';
1233 if (dirlen == 1 && dirname[0] == '/')
1234 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1235 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1236 dirlen = 0;
1238 #if defined __MSDOS__ || defined WINDOWS32
1239 if (dirlen > 1)
1241 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1242 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1243 --dirlen;
1244 else if (dirname[dirlen - 1] == ':')
1246 /* DIRNAME is "d:". Use ':' instead of '/'. */
1247 --dirlen;
1248 dirsep_char = ':';
1251 #endif
1253 for (i = 0; i < n; ++i)
1255 size_t eltlen = strlen (array[i]) + 1;
1256 char *new = malloc (dirlen + 1 + eltlen);
1257 if (new == NULL)
1259 while (i > 0)
1260 free (array[--i]);
1261 return 1;
1265 char *endp = mempcpy (new, dirname, dirlen);
1266 *endp++ = dirsep_char;
1267 mempcpy (endp, array[i], eltlen);
1269 free (array[i]);
1270 array[i] = new;
1273 return 0;
1276 /* Like 'glob', but PATTERN is a final pathname component,
1277 and matches are searched for in DIRECTORY.
1278 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1279 The GLOB_APPEND flag is assumed to be set (always appends). */
1280 static int
1281 glob_in_dir (const char *pattern, const char *directory, int flags,
1282 int (*errfunc) (const char *, int),
1283 glob_t *pglob, size_t alloca_used)
1285 size_t dirlen = strlen (directory);
1286 void *stream = NULL;
1287 struct scratch_buffer s;
1288 scratch_buffer_init (&s);
1289 # define GLOBNAMES_MEMBERS(nnames) \
1290 struct globnames *next; size_t count; char *name[nnames];
1291 struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
1292 struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
1293 struct globnames *init_names = (struct globnames *) &init_names_buf;
1294 struct globnames *names = init_names;
1295 struct globnames *names_alloca = init_names;
1296 size_t nfound = 0;
1297 size_t cur = 0;
1298 int meta;
1299 int save;
1300 int result;
1302 alloca_used += sizeof init_names_buf;
1304 init_names->next = NULL;
1305 init_names->count = ((sizeof init_names_buf
1306 - offsetof (struct globnames, name))
1307 / sizeof init_names->name[0]);
1309 meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
1310 if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1312 /* We need not do any tests. The PATTERN contains no meta
1313 characters and we must not return an error therefore the
1314 result will always contain exactly one name. */
1315 flags |= GLOB_NOCHECK;
1317 else if (meta == GLOBPAT_NONE)
1319 size_t patlen = strlen (pattern);
1320 size_t fullsize;
1321 bool alloca_fullname
1322 = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
1323 && glob_use_alloca (alloca_used, fullsize));
1324 char *fullname;
1325 if (alloca_fullname)
1326 fullname = alloca_account (fullsize, alloca_used);
1327 else
1329 fullname = malloc (fullsize);
1330 if (fullname == NULL)
1331 return GLOB_NOSPACE;
1334 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1335 "/", 1),
1336 pattern, patlen + 1);
1337 if (glob_lstat (pglob, flags, fullname) == 0
1338 || errno == EOVERFLOW)
1339 /* We found this file to be existing. Now tell the rest
1340 of the function to copy this name into the result. */
1341 flags |= GLOB_NOCHECK;
1343 if (__glibc_unlikely (!alloca_fullname))
1344 free (fullname);
1346 else
1348 stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1349 ? (*pglob->gl_opendir) (directory)
1350 : opendir (directory));
1351 if (stream == NULL)
1353 if (errno != ENOTDIR
1354 && ((errfunc != NULL && (*errfunc) (directory, errno))
1355 || (flags & GLOB_ERR)))
1356 return GLOB_ABORTED;
1358 else
1360 int dfd = dirfd (stream);
1361 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1362 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
1363 flags |= GLOB_MAGCHAR;
1365 while (1)
1367 struct readdir_result d;
1369 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1370 d = convert_dirent (GL_READDIR (pglob, stream));
1371 else
1373 #ifdef COMPILE_GLOB64
1374 d = convert_dirent (__readdir (stream));
1375 #else
1376 d = convert_dirent64 (__readdir64 (stream));
1377 #endif
1380 if (d.name == NULL)
1381 break;
1383 /* If we shall match only directories use the information
1384 provided by the dirent call if possible. */
1385 if (flags & GLOB_ONLYDIR)
1386 switch (readdir_result_type (d))
1388 default: continue;
1389 case DT_DIR: break;
1390 case DT_LNK: case DT_UNKNOWN:
1391 /* The filesystem was too lazy to give us a hint,
1392 so we have to do it the hard way. */
1393 if (__glibc_unlikely (dfd < 0 || flags & GLOB_ALTDIRFUNC))
1395 size_t namelen = strlen (d.name);
1396 size_t need = dirlen + 1 + namelen + 1;
1397 if (s.length < need
1398 && !scratch_buffer_set_array_size (&s, need, 1))
1399 goto memory_error;
1400 char *p = mempcpy (s.data, directory, dirlen);
1401 *p = '/';
1402 p += p[-1] != '/';
1403 memcpy (p, d.name, namelen + 1);
1404 if (! is_dir (s.data, flags, pglob))
1405 continue;
1407 else
1409 struct_stat64 st64;
1410 if (! (GLOB_FSTATAT64 (dfd, d.name, &st64, 0) == 0
1411 && S_ISDIR (st64.st_mode)))
1412 continue;
1416 if (fnmatch (pattern, d.name, fnm_flags) == 0)
1418 if (cur == names->count)
1420 struct globnames *newnames;
1421 size_t count = names->count * 2;
1422 size_t nameoff = offsetof (struct globnames, name);
1423 size_t size = FLEXSIZEOF (struct globnames, name,
1424 count * sizeof (char *));
1425 if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
1426 < names->count)
1427 goto memory_error;
1428 if (glob_use_alloca (alloca_used, size))
1429 newnames = names_alloca
1430 = alloca_account (size, alloca_used);
1431 else if ((newnames = malloc (size))
1432 == NULL)
1433 goto memory_error;
1434 newnames->count = count;
1435 newnames->next = names;
1436 names = newnames;
1437 cur = 0;
1439 names->name[cur] = strdup (d.name);
1440 if (names->name[cur] == NULL)
1441 goto memory_error;
1442 ++cur;
1443 ++nfound;
1444 if (SIZE_MAX - pglob->gl_offs <= nfound)
1445 goto memory_error;
1451 if (nfound == 0 && (flags & GLOB_NOCHECK))
1453 size_t len = strlen (pattern);
1454 nfound = 1;
1455 names->name[cur] = malloc (len + 1);
1456 if (names->name[cur] == NULL)
1457 goto memory_error;
1458 *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1461 result = GLOB_NOMATCH;
1462 if (nfound != 0)
1464 char **new_gl_pathv;
1465 result = 0;
1467 if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1468 < pglob->gl_offs + nfound + 1)
1469 goto memory_error;
1471 new_gl_pathv
1472 = realloc (pglob->gl_pathv,
1473 (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1474 * sizeof (char *));
1476 if (new_gl_pathv == NULL)
1478 memory_error:
1479 while (1)
1481 struct globnames *old = names;
1482 for (size_t i = 0; i < cur; ++i)
1483 free (names->name[i]);
1484 names = names->next;
1485 /* NB: we will not leak memory here if we exit without
1486 freeing the current block assigned to OLD. At least
1487 the very first block is always allocated on the stack
1488 and this is the block assigned to OLD here. */
1489 if (names == NULL)
1491 assert (old == init_names);
1492 break;
1494 cur = names->count;
1495 if (old == names_alloca)
1496 names_alloca = names;
1497 else
1498 free (old);
1500 result = GLOB_NOSPACE;
1502 else
1504 while (1)
1506 struct globnames *old = names;
1507 for (size_t i = 0; i < cur; ++i)
1508 new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
1509 = names->name[i];
1510 names = names->next;
1511 /* NB: we will not leak memory here if we exit without
1512 freeing the current block assigned to OLD. At least
1513 the very first block is always allocated on the stack
1514 and this is the block assigned to OLD here. */
1515 if (names == NULL)
1517 assert (old == init_names);
1518 break;
1520 cur = names->count;
1521 if (old == names_alloca)
1522 names_alloca = names;
1523 else
1524 free (old);
1527 pglob->gl_pathv = new_gl_pathv;
1529 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1531 pglob->gl_flags = flags;
1535 if (stream != NULL)
1537 save = errno;
1538 if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
1539 (*pglob->gl_closedir) (stream);
1540 else
1541 closedir (stream);
1542 __set_errno (save);
1545 scratch_buffer_free (&s);
1546 return result;