riscv: align stack before calling _dl_init [BZ #28703]
[glibc.git] / posix / glob.c
blob593a4c358f3d42e52257d470ff87dc97aece74f1
1 /* Copyright (C) 1991-2021 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
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 <config.h>
26 #endif
28 #include <glob.h>
30 #include <errno.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <stdbool.h>
34 #include <stddef.h>
35 #include <stdint.h>
36 #include <assert.h>
37 #include <unistd.h>
39 #if defined _WIN32 && ! defined __CYGWIN__
40 # define WINDOWS32
41 #endif
43 #ifndef WINDOWS32
44 # include <pwd.h>
45 #endif
47 #include <errno.h>
48 #include <dirent.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <alloca.h>
53 #ifdef _LIBC
54 # undef strdup
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)
62 # define FLEXIBLE_ARRAY_MEMBER
63 # ifndef struct_stat
64 # define struct_stat struct stat
65 # endif
66 # ifndef struct_stat64
67 # define struct_stat64 struct stat64
68 # endif
69 # ifndef GLOB_LSTAT
70 # define GLOB_LSTAT gl_lstat
71 # endif
72 # ifndef GLOB_STAT64
73 # define GLOB_STAT64 __stat64
74 # endif
75 # ifndef GLOB_LSTAT64
76 # define GLOB_LSTAT64 __lstat64
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_STAT64 stat
92 # define GLOB_LSTAT64 lstat
93 #endif /* _LIBC */
95 #include <fnmatch.h>
97 #include <flexmember.h>
98 #include <glob_internal.h>
99 #include <scratch_buffer.h>
101 static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
103 /* The type of ((struct dirent *) 0)->d_type is 'unsigned char' on most
104 platforms, but 'unsigned int' in the mingw from mingw.org. */
105 typedef uint_fast32_t dirent_type;
107 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
108 /* Any distinct values will do here.
109 Undef any existing macros out of the way. */
110 # undef DT_UNKNOWN
111 # undef DT_DIR
112 # undef DT_LNK
113 # define DT_UNKNOWN 0
114 # define DT_DIR 1
115 # define DT_LNK 2
116 #endif
118 /* A representation of a directory entry which does not depend on the
119 layout of struct dirent, or the size of ino_t. */
120 struct readdir_result
122 const char *name;
123 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
124 dirent_type type;
125 #endif
128 /* Initialize and return type member of struct readdir_result. */
129 static dirent_type
130 readdir_result_type (struct readdir_result d)
132 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
133 # define D_TYPE_TO_RESULT(source) (source)->d_type,
134 return d.type;
135 #else
136 # define D_TYPE_TO_RESULT(source)
137 return DT_UNKNOWN;
138 #endif
141 /* Construct an initializer for a struct readdir_result object from a
142 struct dirent *. No copy of the name is made. */
143 #define READDIR_RESULT_INITIALIZER(source) \
145 source->d_name, \
146 D_TYPE_TO_RESULT (source) \
149 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
150 type safety if an old interface version needs to be supported. */
151 #ifndef GL_READDIR
152 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
153 #endif
155 /* Extract name and type from directory entry. No copy of the name is
156 made. If SOURCE is NULL, result name is NULL. Keep in sync with
157 convert_dirent64 below. */
158 static struct readdir_result
159 convert_dirent (const struct dirent *source)
161 if (source == NULL)
163 struct readdir_result result = { NULL, };
164 return result;
166 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
167 return result;
170 #ifndef COMPILE_GLOB64
171 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
172 sync with convert_dirent above. */
173 static struct readdir_result
174 convert_dirent64 (const struct dirent64 *source)
176 if (source == NULL)
178 struct readdir_result result = { NULL, };
179 return result;
181 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
182 return result;
184 #endif
186 #ifndef _LIBC
187 /* The results of opendir() in this file are not used with dirfd and fchdir,
188 and we do not leak fds to any single-threaded code that could use stdio,
189 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
190 FIXME - if the kernel ever adds support for multi-thread safety for
191 avoiding standard fds, then we should use opendir_safer. */
192 # ifdef GNULIB_defined_opendir
193 # undef opendir
194 # endif
195 # ifdef GNULIB_defined_closedir
196 # undef closedir
197 # endif
199 /* Just use malloc. */
200 # define __libc_use_alloca(n) false
201 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
202 # define extend_alloca_account(buf, len, newlen, avar) \
203 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
204 #endif
206 static int
207 glob_lstat (glob_t *pglob, int flags, const char *fullname)
209 /* Use on glob-lstat-compat.c to provide a compat symbol which does not
210 use lstat / gl_lstat. */
211 union
213 struct_stat st;
214 struct_stat64 st64;
215 } ust;
216 return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
217 ? pglob->GLOB_LSTAT (fullname, &ust.st)
218 : GLOB_LSTAT64 (fullname, &ust.st64));
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_STAT64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
263 /* Find the end of the sub-pattern in a brace expression. */
264 static const char *
265 next_brace_sub (const char *cp, int flags)
267 size_t depth = 0;
268 while (*cp != '\0')
269 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
271 if (*++cp == '\0')
272 break;
273 ++cp;
275 else
277 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
278 break;
280 if (*cp++ == '{')
281 depth++;
284 return *cp != '\0' ? cp : NULL;
287 #ifndef GLOB_ATTRIBUTE
288 # define GLOB_ATTRIBUTE
289 #endif
291 /* Do glob searching for PATTERN, placing results in PGLOB.
292 The bits defined above may be set in FLAGS.
293 If a directory cannot be opened or read and ERRFUNC is not nil,
294 it is called with the pathname that caused the error, and the
295 'errno' value from the failing call; if it returns non-zero
296 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
297 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
298 Otherwise, 'glob' returns zero. */
300 GLOB_ATTRIBUTE
301 __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
302 glob_t *pglob)
304 const char *filename;
305 char *dirname = NULL;
306 size_t dirlen;
307 int status;
308 size_t oldcount;
309 int meta;
310 int dirname_modified;
311 int malloc_dirname = 0;
312 glob_t dirs;
313 int retval = 0;
314 size_t alloca_used = 0;
316 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
318 __set_errno (EINVAL);
319 return -1;
322 /* POSIX requires all slashes to be matched. This means that with
323 a trailing slash we must match only directories. */
324 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
325 flags |= GLOB_ONLYDIR;
327 if (!(flags & GLOB_DOOFFS))
328 /* Have to do this so 'globfree' knows where to start freeing. It
329 also makes all the code that uses gl_offs simpler. */
330 pglob->gl_offs = 0;
332 if (!(flags & GLOB_APPEND))
334 pglob->gl_pathc = 0;
335 if (!(flags & GLOB_DOOFFS))
336 pglob->gl_pathv = NULL;
337 else
339 size_t i;
341 if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
342 return GLOB_NOSPACE;
344 pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
345 * sizeof (char *));
346 if (pglob->gl_pathv == NULL)
347 return GLOB_NOSPACE;
349 for (i = 0; i <= pglob->gl_offs; ++i)
350 pglob->gl_pathv[i] = NULL;
354 if (flags & GLOB_BRACE)
356 const char *begin;
358 if (flags & GLOB_NOESCAPE)
359 begin = strchr (pattern, '{');
360 else
362 begin = pattern;
363 while (1)
365 if (*begin == '\0')
367 begin = NULL;
368 break;
371 if (*begin == '\\' && begin[1] != '\0')
372 ++begin;
373 else if (*begin == '{')
374 break;
376 ++begin;
380 if (begin != NULL)
382 /* Allocate working buffer large enough for our work. Note that
383 we have at least an opening and closing brace. */
384 size_t firstc;
385 char *alt_start;
386 const char *p;
387 const char *next;
388 const char *rest;
389 size_t rest_len;
390 char *onealt;
391 size_t pattern_len = strlen (pattern) - 1;
392 int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
393 if (alloca_onealt)
394 onealt = alloca_account (pattern_len, alloca_used);
395 else
397 onealt = malloc (pattern_len);
398 if (onealt == NULL)
399 return GLOB_NOSPACE;
402 /* We know the prefix for all sub-patterns. */
403 alt_start = mempcpy (onealt, pattern, begin - pattern);
405 /* Find the first sub-pattern and at the same time find the
406 rest after the closing brace. */
407 next = next_brace_sub (begin + 1, flags);
408 if (next == NULL)
410 /* It is an invalid expression. */
411 illegal_brace:
412 if (__glibc_unlikely (!alloca_onealt))
413 free (onealt);
414 flags &= ~GLOB_BRACE;
415 goto no_brace;
418 /* Now find the end of the whole brace expression. */
419 rest = next;
420 while (*rest != '}')
422 rest = next_brace_sub (rest + 1, flags);
423 if (rest == NULL)
424 /* It is an illegal expression. */
425 goto illegal_brace;
427 /* Please note that we now can be sure the brace expression
428 is well-formed. */
429 rest_len = strlen (++rest) + 1;
431 /* We have a brace expression. BEGIN points to the opening {,
432 NEXT points past the terminator of the first element, and END
433 points past the final }. We will accumulate result names from
434 recursive runs for each brace alternative in the buffer using
435 GLOB_APPEND. */
436 firstc = pglob->gl_pathc;
438 p = begin + 1;
439 while (1)
441 int result;
443 /* Construct the new glob expression. */
444 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
446 result = __glob (onealt,
447 ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
448 | GLOB_APPEND),
449 errfunc, pglob);
451 /* If we got an error, return it. */
452 if (result && result != GLOB_NOMATCH)
454 if (__glibc_unlikely (!alloca_onealt))
455 free (onealt);
456 if (!(flags & GLOB_APPEND))
458 globfree (pglob);
459 pglob->gl_pathc = 0;
461 return result;
464 if (*next == '}')
465 /* We saw the last entry. */
466 break;
468 p = next + 1;
469 next = next_brace_sub (p, flags);
470 assert (next != NULL);
473 if (__glibc_unlikely (!alloca_onealt))
474 free (onealt);
476 if (pglob->gl_pathc != firstc)
477 /* We found some entries. */
478 return 0;
479 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
480 return GLOB_NOMATCH;
484 no_brace:
485 oldcount = pglob->gl_pathc + pglob->gl_offs;
487 /* Find the filename. */
488 filename = strrchr (pattern, '/');
490 #if defined __MSDOS__ || defined WINDOWS32
491 /* The case of "d:pattern". Since ':' is not allowed in
492 file names, we can safely assume that wherever it
493 happens in pattern, it signals the filename part. This
494 is so we could some day support patterns like "[a-z]:foo". */
495 if (filename == NULL)
496 filename = strchr (pattern, ':');
497 #endif /* __MSDOS__ || WINDOWS32 */
499 dirname_modified = 0;
500 if (filename == NULL)
502 /* This can mean two things: a simple name or "~name". The latter
503 case is nothing but a notation for a directory. */
504 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
506 dirname = (char *) pattern;
507 dirlen = strlen (pattern);
509 /* Set FILENAME to NULL as a special flag. This is ugly but
510 other solutions would require much more code. We test for
511 this special case below. */
512 filename = NULL;
514 else
516 if (__glibc_unlikely (pattern[0] == '\0'))
518 dirs.gl_pathv = NULL;
519 goto no_matches;
522 filename = pattern;
523 dirname = (char *) ".";
524 dirlen = 0;
527 else if (filename == pattern
528 || (filename == pattern + 1 && pattern[0] == '\\'
529 && (flags & GLOB_NOESCAPE) == 0))
531 /* "/pattern" or "\\/pattern". */
532 dirname = (char *) "/";
533 dirlen = 1;
534 ++filename;
536 else
538 char *newp;
539 dirlen = filename - pattern;
540 #if defined __MSDOS__ || defined WINDOWS32
541 if (*filename == ':'
542 || (filename > pattern + 1 && filename[-1] == ':'))
544 char *drive_spec;
546 ++dirlen;
547 drive_spec = __alloca (dirlen + 1);
548 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
549 /* For now, disallow wildcards in the drive spec, to
550 prevent infinite recursion in glob. */
551 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
552 return GLOB_NOMATCH;
553 /* If this is "d:pattern", we need to copy ':' to DIRNAME
554 as well. If it's "d:/pattern", don't remove the slash
555 from "d:/", since "d:" and "d:/" are not the same.*/
557 #endif
559 if (glob_use_alloca (alloca_used, dirlen + 1))
560 newp = alloca_account (dirlen + 1, alloca_used);
561 else
563 newp = malloc (dirlen + 1);
564 if (newp == NULL)
565 return GLOB_NOSPACE;
566 malloc_dirname = 1;
568 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
569 dirname = newp;
570 ++filename;
572 #if defined __MSDOS__ || defined WINDOWS32
573 bool drive_root = (dirlen > 1
574 && (dirname[dirlen - 1] == ':'
575 || (dirlen > 2 && dirname[dirlen - 2] == ':'
576 && dirname[dirlen - 1] == '/')));
577 #else
578 bool drive_root = false;
579 #endif
581 if (filename[0] == '\0' && dirlen > 1 && !drive_root)
582 /* "pattern/". Expand "pattern", appending slashes. */
584 int orig_flags = flags;
585 if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
587 /* "pattern\\/". Remove the final backslash if it hasn't
588 been quoted. */
589 char *p = (char *) &dirname[dirlen - 1];
591 while (p > dirname && p[-1] == '\\') --p;
592 if ((&dirname[dirlen] - p) & 1)
594 *(char *) &dirname[--dirlen] = '\0';
595 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
598 int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob);
599 if (val == 0)
600 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
601 | (flags & GLOB_MARK));
602 else if (val == GLOB_NOMATCH && flags != orig_flags)
604 /* Make sure globfree (&dirs); is a nop. */
605 dirs.gl_pathv = NULL;
606 flags = orig_flags;
607 oldcount = pglob->gl_pathc + pglob->gl_offs;
608 goto no_matches;
610 retval = val;
611 goto out;
615 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
617 if (dirname[1] == '\0' || dirname[1] == '/'
618 || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
619 && (dirname[2] == '\0' || dirname[2] == '/')))
621 /* Look up home directory. */
622 char *home_dir = getenv ("HOME");
623 int malloc_home_dir = 0;
624 if (home_dir == NULL || home_dir[0] == '\0')
626 #ifdef WINDOWS32
627 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
628 preference to HOME, because the user can change HOME. */
629 const char *home_drive = getenv ("HOMEDRIVE");
630 const char *home_path = getenv ("HOMEPATH");
632 if (home_drive != NULL && home_path != NULL)
634 size_t home_drive_len = strlen (home_drive);
635 size_t home_path_len = strlen (home_path);
636 char *mem = alloca (home_drive_len + home_path_len + 1);
638 memcpy (mem, home_drive, home_drive_len);
639 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
640 home_dir = mem;
642 else
643 home_dir = "c:/users/default"; /* poor default */
644 #else
645 int err;
646 struct passwd *p;
647 struct passwd pwbuf;
648 struct scratch_buffer s;
649 scratch_buffer_init (&s);
650 while (true)
652 p = NULL;
653 err = __getlogin_r (s.data, s.length);
654 if (err == 0)
656 # if defined HAVE_GETPWNAM_R || defined _LIBC
657 size_t ssize = strlen (s.data) + 1;
658 char *sdata = s.data;
659 err = getpwnam_r (sdata, &pwbuf, sdata + ssize,
660 s.length - ssize, &p);
661 # else
662 p = getpwnam (s.data);
663 if (p == NULL)
664 err = errno;
665 # endif
667 if (err != ERANGE)
668 break;
669 if (!scratch_buffer_grow (&s))
671 retval = GLOB_NOSPACE;
672 goto out;
675 if (err == 0)
677 home_dir = strdup (p->pw_dir);
678 malloc_home_dir = 1;
680 scratch_buffer_free (&s);
681 if (err == 0 && home_dir == NULL)
683 retval = GLOB_NOSPACE;
684 goto out;
686 #endif /* WINDOWS32 */
688 if (home_dir == NULL || home_dir[0] == '\0')
690 if (__glibc_unlikely (malloc_home_dir))
691 free (home_dir);
692 if (flags & GLOB_TILDE_CHECK)
694 retval = GLOB_NOMATCH;
695 goto out;
697 else
699 home_dir = (char *) "~"; /* No luck. */
700 malloc_home_dir = 0;
703 /* Now construct the full directory. */
704 if (dirname[1] == '\0')
706 if (__glibc_unlikely (malloc_dirname))
707 free (dirname);
709 dirname = home_dir;
710 dirlen = strlen (dirname);
711 malloc_dirname = malloc_home_dir;
713 else
715 char *newp;
716 size_t home_len = strlen (home_dir);
717 int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
718 if (use_alloca)
719 newp = alloca_account (home_len + dirlen, alloca_used);
720 else
722 newp = malloc (home_len + dirlen);
723 if (newp == NULL)
725 if (__glibc_unlikely (malloc_home_dir))
726 free (home_dir);
727 retval = GLOB_NOSPACE;
728 goto out;
732 mempcpy (mempcpy (newp, home_dir, home_len),
733 &dirname[1], dirlen);
735 if (__glibc_unlikely (malloc_dirname))
736 free (dirname);
738 dirname = newp;
739 dirlen += home_len - 1;
740 malloc_dirname = !use_alloca;
742 if (__glibc_unlikely (malloc_home_dir))
743 free (home_dir);
745 dirname_modified = 1;
747 else
749 #ifndef WINDOWS32
750 char *end_name = strchr (dirname, '/');
751 char *user_name;
752 int malloc_user_name = 0;
753 char *unescape = NULL;
755 if (!(flags & GLOB_NOESCAPE))
757 if (end_name == NULL)
759 unescape = strchr (dirname, '\\');
760 if (unescape)
761 end_name = strchr (unescape, '\0');
763 else
764 unescape = memchr (dirname, '\\', end_name - dirname);
766 if (end_name == NULL)
767 user_name = dirname + 1;
768 else
770 char *newp;
771 if (glob_use_alloca (alloca_used, end_name - dirname))
772 newp = alloca_account (end_name - dirname, alloca_used);
773 else
775 newp = malloc (end_name - dirname);
776 if (newp == NULL)
778 retval = GLOB_NOSPACE;
779 goto out;
781 malloc_user_name = 1;
783 if (unescape != NULL)
785 char *p = mempcpy (newp, dirname + 1,
786 unescape - dirname - 1);
787 char *q = unescape;
788 while (q != end_name)
790 if (*q == '\\')
792 if (q + 1 == end_name)
794 /* "~fo\\o\\" unescape to user_name "foo\\",
795 but "~fo\\o\\/" unescape to user_name
796 "foo". */
797 if (filename == NULL)
798 *p++ = '\\';
799 break;
801 ++q;
803 *p++ = *q++;
805 *p = '\0';
807 else
808 *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
809 = '\0';
810 user_name = newp;
813 /* Look up specific user's home directory. */
815 struct passwd *p;
816 struct scratch_buffer pwtmpbuf;
817 scratch_buffer_init (&pwtmpbuf);
819 # if defined HAVE_GETPWNAM_R || defined _LIBC
820 struct passwd pwbuf;
822 while (getpwnam_r (user_name, &pwbuf,
823 pwtmpbuf.data, pwtmpbuf.length, &p)
824 == ERANGE)
826 if (!scratch_buffer_grow (&pwtmpbuf))
828 retval = GLOB_NOSPACE;
829 goto out;
832 # else
833 p = getpwnam (user_name);
834 # endif
836 if (__glibc_unlikely (malloc_user_name))
837 free (user_name);
839 /* If we found a home directory use this. */
840 if (p != NULL)
842 size_t home_len = strlen (p->pw_dir);
843 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
844 /* dirname contains end_name; we can't free it now. */
845 char *prev_dirname =
846 (__glibc_unlikely (malloc_dirname) ? dirname : NULL);
847 char *d;
849 malloc_dirname = 0;
851 if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
852 dirname = alloca_account (home_len + rest_len + 1,
853 alloca_used);
854 else
856 dirname = malloc (home_len + rest_len + 1);
857 if (dirname == NULL)
859 free (prev_dirname);
860 scratch_buffer_free (&pwtmpbuf);
861 retval = GLOB_NOSPACE;
862 goto out;
864 malloc_dirname = 1;
866 d = mempcpy (dirname, p->pw_dir, home_len);
867 if (end_name != NULL)
868 d = mempcpy (d, end_name, rest_len);
869 *d = '\0';
871 free (prev_dirname);
873 dirlen = home_len + rest_len;
874 dirname_modified = 1;
876 else
878 if (flags & GLOB_TILDE_CHECK)
880 /* We have to regard it as an error if we cannot find the
881 home directory. */
882 retval = GLOB_NOMATCH;
883 goto out;
886 scratch_buffer_free (&pwtmpbuf);
888 #endif /* !WINDOWS32 */
892 /* Now test whether we looked for "~" or "~NAME". In this case we
893 can give the answer now. */
894 if (filename == NULL)
896 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
897 char **new_gl_pathv;
899 if (newcount > SIZE_MAX / sizeof (char *) - 2)
901 nospace:
902 free (pglob->gl_pathv);
903 pglob->gl_pathv = NULL;
904 pglob->gl_pathc = 0;
905 retval = GLOB_NOSPACE;
906 goto out;
909 new_gl_pathv = realloc (pglob->gl_pathv,
910 (newcount + 2) * sizeof (char *));
911 if (new_gl_pathv == NULL)
912 goto nospace;
913 pglob->gl_pathv = new_gl_pathv;
915 if (flags & GLOB_MARK && is_dir (dirname, flags, pglob))
917 char *p;
918 pglob->gl_pathv[newcount] = malloc (dirlen + 2);
919 if (pglob->gl_pathv[newcount] == NULL)
920 goto nospace;
921 p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
922 p[0] = '/';
923 p[1] = '\0';
924 if (__glibc_unlikely (malloc_dirname))
925 free (dirname);
927 else
929 if (__glibc_unlikely (malloc_dirname))
930 pglob->gl_pathv[newcount] = dirname;
931 else
933 pglob->gl_pathv[newcount] = strdup (dirname);
934 if (pglob->gl_pathv[newcount] == NULL)
935 goto nospace;
938 pglob->gl_pathv[++newcount] = NULL;
939 ++pglob->gl_pathc;
940 pglob->gl_flags = flags;
942 return 0;
945 meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
946 /* meta is 1 if correct glob pattern containing metacharacters.
947 If meta has bit (1 << 2) set, it means there was an unterminated
948 [ which we handle the same, using fnmatch. Broken unterminated
949 pattern bracket expressions ought to be rare enough that it is
950 not worth special casing them, fnmatch will do the right thing. */
951 if (meta & (GLOBPAT_SPECIAL | GLOBPAT_BRACKET))
953 /* The directory name contains metacharacters, so we
954 have to glob for the directory, and then glob for
955 the pattern in each directory found. */
956 size_t i;
958 if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
960 /* "foo\\/bar". Remove the final backslash from dirname
961 if it has not been quoted. */
962 char *p = (char *) &dirname[dirlen - 1];
964 while (p > dirname && p[-1] == '\\') --p;
965 if ((&dirname[dirlen] - p) & 1)
966 *(char *) &dirname[--dirlen] = '\0';
969 if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
971 /* Use the alternative access functions also in the recursive
972 call. */
973 dirs.gl_opendir = pglob->gl_opendir;
974 dirs.gl_readdir = pglob->gl_readdir;
975 dirs.gl_closedir = pglob->gl_closedir;
976 dirs.gl_stat = pglob->gl_stat;
977 dirs.gl_lstat = pglob->gl_lstat;
980 status = __glob (dirname,
981 ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
982 | GLOB_NOSORT | GLOB_ONLYDIR),
983 errfunc, &dirs);
984 if (status != 0)
986 if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
988 retval = status;
989 goto out;
991 goto no_matches;
994 /* We have successfully globbed the preceding directory name.
995 For each name we found, call glob_in_dir on it and FILENAME,
996 appending the results to PGLOB. */
997 for (i = 0; i < dirs.gl_pathc; ++i)
999 size_t old_pathc;
1001 old_pathc = pglob->gl_pathc;
1002 status = glob_in_dir (filename, dirs.gl_pathv[i],
1003 ((flags | GLOB_APPEND)
1004 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
1005 errfunc, pglob, alloca_used);
1006 if (status == GLOB_NOMATCH)
1007 /* No matches in this directory. Try the next. */
1008 continue;
1010 if (status != 0)
1012 globfree (&dirs);
1013 globfree (pglob);
1014 pglob->gl_pathc = 0;
1015 retval = status;
1016 goto out;
1019 /* Stick the directory on the front of each name. */
1020 if (prefix_array (dirs.gl_pathv[i],
1021 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1022 pglob->gl_pathc - old_pathc))
1024 globfree (&dirs);
1025 globfree (pglob);
1026 pglob->gl_pathc = 0;
1027 retval = GLOB_NOSPACE;
1028 goto out;
1032 flags |= GLOB_MAGCHAR;
1034 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1035 But if we have not found any matching entry and the GLOB_NOCHECK
1036 flag was set we must return the input pattern itself. */
1037 if (pglob->gl_pathc + pglob->gl_offs == oldcount)
1039 no_matches:
1040 /* No matches. */
1041 if (flags & GLOB_NOCHECK)
1043 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1044 char **new_gl_pathv;
1046 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1048 nospace2:
1049 globfree (&dirs);
1050 retval = GLOB_NOSPACE;
1051 goto out;
1054 new_gl_pathv = realloc (pglob->gl_pathv,
1055 (newcount + 2) * sizeof (char *));
1056 if (new_gl_pathv == NULL)
1057 goto nospace2;
1058 pglob->gl_pathv = new_gl_pathv;
1060 pglob->gl_pathv[newcount] = strdup (pattern);
1061 if (pglob->gl_pathv[newcount] == NULL)
1063 globfree (&dirs);
1064 globfree (pglob);
1065 pglob->gl_pathc = 0;
1066 retval = GLOB_NOSPACE;
1067 goto out;
1070 ++pglob->gl_pathc;
1071 ++newcount;
1073 pglob->gl_pathv[newcount] = NULL;
1074 pglob->gl_flags = flags;
1076 else
1078 globfree (&dirs);
1079 retval = GLOB_NOMATCH;
1080 goto out;
1084 globfree (&dirs);
1086 else
1088 size_t old_pathc = pglob->gl_pathc;
1089 int orig_flags = flags;
1091 if (meta & GLOBPAT_BACKSLASH)
1093 char *p = strchr (dirname, '\\'), *q;
1094 /* We need to unescape the dirname string. It is certainly
1095 allocated by alloca, as otherwise filename would be NULL
1096 or dirname wouldn't contain backslashes. */
1097 q = p;
1100 if (*p == '\\')
1102 *q = *++p;
1103 --dirlen;
1105 else
1106 *q = *p;
1107 ++q;
1109 while (*p++ != '\0');
1110 dirname_modified = 1;
1112 if (dirname_modified)
1113 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
1114 status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
1115 alloca_used);
1116 if (status != 0)
1118 if (status == GLOB_NOMATCH && flags != orig_flags
1119 && pglob->gl_pathc + pglob->gl_offs == oldcount)
1121 /* Make sure globfree (&dirs); is a nop. */
1122 dirs.gl_pathv = NULL;
1123 flags = orig_flags;
1124 goto no_matches;
1126 retval = status;
1127 goto out;
1130 if (dirlen > 0)
1132 /* Stick the directory on the front of each name. */
1133 if (prefix_array (dirname,
1134 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1135 pglob->gl_pathc - old_pathc))
1137 globfree (pglob);
1138 pglob->gl_pathc = 0;
1139 retval = GLOB_NOSPACE;
1140 goto out;
1145 if (flags & GLOB_MARK)
1147 /* Append slashes to directory names. */
1148 size_t i;
1150 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
1151 if (is_dir (pglob->gl_pathv[i], flags, pglob))
1153 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1154 char *new = realloc (pglob->gl_pathv[i], len);
1155 if (new == NULL)
1157 globfree (pglob);
1158 pglob->gl_pathc = 0;
1159 retval = GLOB_NOSPACE;
1160 goto out;
1162 strcpy (&new[len - 2], "/");
1163 pglob->gl_pathv[i] = new;
1167 if (!(flags & GLOB_NOSORT))
1169 /* Sort the vector. */
1170 qsort (&pglob->gl_pathv[oldcount],
1171 pglob->gl_pathc + pglob->gl_offs - oldcount,
1172 sizeof (char *), collated_compare);
1175 out:
1176 if (__glibc_unlikely (malloc_dirname))
1177 free (dirname);
1179 return retval;
1181 #if defined _LIBC && !defined __glob
1182 versioned_symbol (libc, __glob, glob, GLIBC_2_27);
1183 libc_hidden_ver (__glob, glob)
1184 #endif
1187 /* Do a collated comparison of A and B. */
1188 static int
1189 collated_compare (const void *a, const void *b)
1191 char *const *ps1 = a; char *s1 = *ps1;
1192 char *const *ps2 = b; char *s2 = *ps2;
1194 if (s1 == s2)
1195 return 0;
1196 if (s1 == NULL)
1197 return 1;
1198 if (s2 == NULL)
1199 return -1;
1200 return strcoll (s1, s2);
1204 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1205 elements in place. Return nonzero if out of memory, zero if successful.
1206 A slash is inserted between DIRNAME and each elt of ARRAY,
1207 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1208 static int
1209 prefix_array (const char *dirname, char **array, size_t n)
1211 size_t i;
1212 size_t dirlen = strlen (dirname);
1213 char dirsep_char = '/';
1215 if (dirlen == 1 && dirname[0] == '/')
1216 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1217 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1218 dirlen = 0;
1220 #if defined __MSDOS__ || defined WINDOWS32
1221 if (dirlen > 1)
1223 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1224 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1225 --dirlen;
1226 else if (dirname[dirlen - 1] == ':')
1228 /* DIRNAME is "d:". Use ':' instead of '/'. */
1229 --dirlen;
1230 dirsep_char = ':';
1233 #endif
1235 for (i = 0; i < n; ++i)
1237 size_t eltlen = strlen (array[i]) + 1;
1238 char *new = malloc (dirlen + 1 + eltlen);
1239 if (new == NULL)
1241 while (i > 0)
1242 free (array[--i]);
1243 return 1;
1247 char *endp = mempcpy (new, dirname, dirlen);
1248 *endp++ = dirsep_char;
1249 mempcpy (endp, array[i], eltlen);
1251 free (array[i]);
1252 array[i] = new;
1255 return 0;
1258 /* Like 'glob', but PATTERN is a final pathname component,
1259 and matches are searched for in DIRECTORY.
1260 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1261 The GLOB_APPEND flag is assumed to be set (always appends). */
1262 static int
1263 glob_in_dir (const char *pattern, const char *directory, int flags,
1264 int (*errfunc) (const char *, int),
1265 glob_t *pglob, size_t alloca_used)
1267 size_t dirlen = strlen (directory);
1268 void *stream = NULL;
1269 # define GLOBNAMES_MEMBERS(nnames) \
1270 struct globnames *next; size_t count; char *name[nnames];
1271 struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
1272 struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
1273 struct globnames *init_names = (struct globnames *) &init_names_buf;
1274 struct globnames *names = init_names;
1275 struct globnames *names_alloca = init_names;
1276 size_t nfound = 0;
1277 size_t cur = 0;
1278 int meta;
1279 int save;
1280 int result;
1282 alloca_used += sizeof init_names_buf;
1284 init_names->next = NULL;
1285 init_names->count = ((sizeof init_names_buf
1286 - offsetof (struct globnames, name))
1287 / sizeof init_names->name[0]);
1289 meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
1290 if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1292 /* We need not do any tests. The PATTERN contains no meta
1293 characters and we must not return an error therefore the
1294 result will always contain exactly one name. */
1295 flags |= GLOB_NOCHECK;
1297 else if (meta == GLOBPAT_NONE)
1299 size_t patlen = strlen (pattern);
1300 size_t fullsize;
1301 bool alloca_fullname
1302 = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
1303 && glob_use_alloca (alloca_used, fullsize));
1304 char *fullname;
1305 if (alloca_fullname)
1306 fullname = alloca_account (fullsize, alloca_used);
1307 else
1309 fullname = malloc (fullsize);
1310 if (fullname == NULL)
1311 return GLOB_NOSPACE;
1314 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1315 "/", 1),
1316 pattern, patlen + 1);
1317 if (glob_lstat (pglob, flags, fullname) == 0
1318 || errno == EOVERFLOW)
1319 /* We found this file to be existing. Now tell the rest
1320 of the function to copy this name into the result. */
1321 flags |= GLOB_NOCHECK;
1323 if (__glibc_unlikely (!alloca_fullname))
1324 free (fullname);
1326 else
1328 stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1329 ? (*pglob->gl_opendir) (directory)
1330 : opendir (directory));
1331 if (stream == NULL)
1333 if (errno != ENOTDIR
1334 && ((errfunc != NULL && (*errfunc) (directory, errno))
1335 || (flags & GLOB_ERR)))
1336 return GLOB_ABORTED;
1338 else
1340 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1341 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
1342 flags |= GLOB_MAGCHAR;
1344 while (1)
1346 struct readdir_result d;
1348 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1349 d = convert_dirent (GL_READDIR (pglob, stream));
1350 else
1352 #ifdef COMPILE_GLOB64
1353 d = convert_dirent (__readdir (stream));
1354 #else
1355 d = convert_dirent64 (__readdir64 (stream));
1356 #endif
1359 if (d.name == NULL)
1360 break;
1362 /* If we shall match only directories use the information
1363 provided by the dirent call if possible. */
1364 if (flags & GLOB_ONLYDIR)
1365 switch (readdir_result_type (d))
1367 case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
1368 default: continue;
1371 if (fnmatch (pattern, d.name, fnm_flags) == 0)
1373 if (cur == names->count)
1375 struct globnames *newnames;
1376 size_t count = names->count * 2;
1377 size_t nameoff = offsetof (struct globnames, name);
1378 size_t size = FLEXSIZEOF (struct globnames, name,
1379 count * sizeof (char *));
1380 if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
1381 < names->count)
1382 goto memory_error;
1383 if (glob_use_alloca (alloca_used, size))
1384 newnames = names_alloca
1385 = alloca_account (size, alloca_used);
1386 else if ((newnames = malloc (size))
1387 == NULL)
1388 goto memory_error;
1389 newnames->count = count;
1390 newnames->next = names;
1391 names = newnames;
1392 cur = 0;
1394 names->name[cur] = strdup (d.name);
1395 if (names->name[cur] == NULL)
1396 goto memory_error;
1397 ++cur;
1398 ++nfound;
1399 if (SIZE_MAX - pglob->gl_offs <= nfound)
1400 goto memory_error;
1406 if (nfound == 0 && (flags & GLOB_NOCHECK))
1408 size_t len = strlen (pattern);
1409 nfound = 1;
1410 names->name[cur] = malloc (len + 1);
1411 if (names->name[cur] == NULL)
1412 goto memory_error;
1413 *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1416 result = GLOB_NOMATCH;
1417 if (nfound != 0)
1419 char **new_gl_pathv;
1420 result = 0;
1422 if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1423 < pglob->gl_offs + nfound + 1)
1424 goto memory_error;
1426 new_gl_pathv
1427 = realloc (pglob->gl_pathv,
1428 (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1429 * sizeof (char *));
1431 if (new_gl_pathv == NULL)
1433 memory_error:
1434 while (1)
1436 struct globnames *old = names;
1437 for (size_t i = 0; i < cur; ++i)
1438 free (names->name[i]);
1439 names = names->next;
1440 /* NB: we will not leak memory here if we exit without
1441 freeing the current block assigned to OLD. At least
1442 the very first block is always allocated on the stack
1443 and this is the block assigned to OLD here. */
1444 if (names == NULL)
1446 assert (old == init_names);
1447 break;
1449 cur = names->count;
1450 if (old == names_alloca)
1451 names_alloca = names;
1452 else
1453 free (old);
1455 result = GLOB_NOSPACE;
1457 else
1459 while (1)
1461 struct globnames *old = names;
1462 for (size_t i = 0; i < cur; ++i)
1463 new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
1464 = names->name[i];
1465 names = names->next;
1466 /* NB: we will not leak memory here if we exit without
1467 freeing the current block assigned to OLD. At least
1468 the very first block is always allocated on the stack
1469 and this is the block assigned to OLD here. */
1470 if (names == NULL)
1472 assert (old == init_names);
1473 break;
1475 cur = names->count;
1476 if (old == names_alloca)
1477 names_alloca = names;
1478 else
1479 free (old);
1482 pglob->gl_pathv = new_gl_pathv;
1484 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1486 pglob->gl_flags = flags;
1490 if (stream != NULL)
1492 save = errno;
1493 if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
1494 (*pglob->gl_closedir) (stream);
1495 else
1496 closedir (stream);
1497 __set_errno (save);
1500 return result;