1/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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/>. */
17
18#ifndef _LIBC
19
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)
23
24# include <libc-config.h>
25
26#endif
27
28#include <glob.h>
29
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>
39
40#if defined _WIN32 && ! defined __CYGWIN__
41# define WINDOWS32
42#endif
43
44#ifndef WINDOWS32
45# include <pwd.h>
46#endif
47
48#include <errno.h>
49#include <dirent.h>
50#include <stdlib.h>
51#include <string.h>
52#include <alloca.h>
53
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 */
93
94#include <fnmatch.h>
95
96#include <flexmember.h>
97#include <glob_internal.h>
98#include <scratch_buffer.h>
99
100static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
101
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. */
104typedef uint_fast32_t dirent_type;
105
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
116
117/* A representation of a directory entry which does not depend on the
118 layout of struct dirent, or the size of ino_t. */
119struct readdir_result
120{
121 const char *name;
122#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
123 dirent_type type;
124#endif
125};
126
127/* Initialize and return type member of struct readdir_result. */
128static dirent_type
129readdir_result_type (struct readdir_result d)
130{
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
138}
139
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) \
143 { \
144 source->d_name, \
145 D_TYPE_TO_RESULT (source) \
146 }
147
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
153
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. */
157static struct readdir_result
158convert_dirent (const struct dirent *source)
159{
160 if (source == NULL)
161 {
162 struct readdir_result result = { NULL, };
163 return result;
164 }
165 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
166 return result;
167}
168
169#ifndef COMPILE_GLOB64
170/* Like convert_dirent, but works on struct dirent64 instead. Keep in
171 sync with convert_dirent above. */
172static struct readdir_result
173convert_dirent64 (const struct dirent64 *source)
174{
175 if (source == NULL)
176 {
177 struct readdir_result result = { NULL, };
178 return result;
179 }
180 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
181 return result;
182}
183#endif
184
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
197
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
204
205static int
206glob_lstat (glob_t *pglob, int flags, const char *fullname)
207{
208/* Use on glob-lstat-compat.c to provide a compat symbol which does not
209 use lstat / gl_lstat. */
210 union
211 {
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));
219}
220
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. */
224
225static bool
226size_add_wrapv (size_t a, size_t b, size_t *r)
227{
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
234}
235
236static bool
237glob_use_alloca (size_t alloca_used, size_t len)
238{
239 size_t size;
240 return (!size_add_wrapv (a: alloca_used, b: len, r: &size)
241 && __libc_use_alloca (size));
242}
243
244static 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);
247static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
248static int collated_compare (const void *, const void *) __THROWNL;
249
250
251/* Return true if FILENAME is a directory or a symbolic link to a directory.
252 Use FLAGS and PGLOB to resolve the filename. */
253static bool
254is_dir (char const *filename, int flags, glob_t const *pglob)
255{
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)));
262}
263
264/* Find the end of the sub-pattern in a brace expression. */
265static const char *
266next_brace_sub (const char *cp, int flags)
267{
268 size_t depth = 0;
269 while (*cp != '\0')
270 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
271 {
272 if (*++cp == '\0')
273 break;
274 ++cp;
275 }
276 else
277 {
278 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
279 break;
280
281 if (*cp++ == '{')
282 depth++;
283 }
284
285 return *cp != '\0' ? cp : NULL;
286}
287
288#ifndef GLOB_ATTRIBUTE
289# define GLOB_ATTRIBUTE
290#endif
291
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. */
300int
301GLOB_ATTRIBUTE
302__glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
303 glob_t *pglob)
304{
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;
316
317 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
318 {
319 __set_errno (EINVAL);
320 return -1;
321 }
322
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;
327
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;
332
333 if (!(flags & GLOB_APPEND))
334 {
335 pglob->gl_pathc = 0;
336 if (!(flags & GLOB_DOOFFS))
337 pglob->gl_pathv = NULL;
338 else
339 {
340 size_t i;
341
342 if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
343 return GLOB_NOSPACE;
344
345 pglob->gl_pathv = (char **) malloc (size: (pglob->gl_offs + 1)
346 * sizeof (char *));
347 if (pglob->gl_pathv == NULL)
348 return GLOB_NOSPACE;
349
350 for (i = 0; i <= pglob->gl_offs; ++i)
351 pglob->gl_pathv[i] = NULL;
352 }
353 }
354
355 if (flags & GLOB_BRACE)
356 {
357 const char *begin;
358
359 if (flags & GLOB_NOESCAPE)
360 begin = strchr (pattern, '{');
361 else
362 {
363 begin = pattern;
364 while (1)
365 {
366 if (*begin == '\0')
367 {
368 begin = NULL;
369 break;
370 }
371
372 if (*begin == '\\' && begin[1] != '\0')
373 ++begin;
374 else if (*begin == '{')
375 break;
376
377 ++begin;
378 }
379 }
380
381 if (begin != NULL)
382 {
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, len: pattern_len);
394 if (alloca_onealt)
395 onealt = alloca_account (pattern_len, alloca_used);
396 else
397 {
398 onealt = malloc (size: pattern_len);
399 if (onealt == NULL)
400 return GLOB_NOSPACE;
401 }
402
403 /* We know the prefix for all sub-patterns. */
404 alt_start = mempcpy (onealt, pattern, begin - pattern);
405
406 /* Find the first sub-pattern and at the same time find the
407 rest after the closing brace. */
408 next = next_brace_sub (cp: begin + 1, flags);
409 if (next == NULL)
410 {
411 /* It is an invalid expression. */
412 illegal_brace:
413 if (__glibc_unlikely (!alloca_onealt))
414 free (ptr: onealt);
415 flags &= ~GLOB_BRACE;
416 goto no_brace;
417 }
418
419 /* Now find the end of the whole brace expression. */
420 rest = next;
421 while (*rest != '}')
422 {
423 rest = next_brace_sub (cp: rest + 1, flags);
424 if (rest == NULL)
425 /* It is an illegal expression. */
426 goto illegal_brace;
427 }
428 /* Please note that we now can be sure the brace expression
429 is well-formed. */
430 rest_len = strlen (++rest) + 1;
431
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;
438
439 p = begin + 1;
440 while (1)
441 {
442 int result;
443
444 /* Construct the new glob expression. */
445 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
446
447 result = __glob (pattern: onealt,
448 flags: ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
449 | GLOB_APPEND),
450 errfunc, pglob);
451
452 /* If we got an error, return it. */
453 if (result && result != GLOB_NOMATCH)
454 {
455 if (__glibc_unlikely (!alloca_onealt))
456 free (ptr: onealt);
457 if (!(flags & GLOB_APPEND))
458 {
459 globfree (pglob);
460 pglob->gl_pathc = 0;
461 }
462 return result;
463 }
464
465 if (*next == '}')
466 /* We saw the last entry. */
467 break;
468
469 p = next + 1;
470 next = next_brace_sub (cp: p, flags);
471 assert (next != NULL);
472 }
473
474 if (__glibc_unlikely (!alloca_onealt))
475 free (ptr: onealt);
476
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;
482 }
483 }
484
485 no_brace:
486 oldcount = pglob->gl_pathc + pglob->gl_offs;
487
488 /* Find the filename. */
489 filename = strrchr (pattern, '/');
490
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 */
499
500 dirname_modified = 0;
501 if (filename == NULL)
502 {
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] == '~')
506 {
507 dirname = (char *) pattern;
508 dirlen = strlen (pattern);
509
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;
514 }
515 else
516 {
517 if (__glibc_unlikely (pattern[0] == '\0'))
518 {
519 dirs.gl_pathv = NULL;
520 goto no_matches;
521 }
522
523 filename = pattern;
524 dirname = (char *) ".";
525 dirlen = 0;
526 }
527 }
528 else if (filename == pattern
529 || (filename == pattern + 1 && pattern[0] == '\\'
530 && (flags & GLOB_NOESCAPE) == 0))
531 {
532 /* "/pattern" or "\\/pattern". */
533 dirname = (char *) "/";
534 dirlen = 1;
535 ++filename;
536 }
537 else
538 {
539 char *newp;
540 dirlen = filename - pattern;
541#if defined __MSDOS__ || defined WINDOWS32
542 if (*filename == ':'
543 || (filename > pattern + 1 && filename[-1] == ':'))
544 {
545 char *drive_spec;
546
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.*/
557 }
558#endif
559
560 if (glob_use_alloca (alloca_used, len: dirlen + 1))
561 newp = alloca_account (dirlen + 1, alloca_used);
562 else
563 {
564 newp = malloc (size: dirlen + 1);
565 if (newp == NULL)
566 return GLOB_NOSPACE;
567 malloc_dirname = 1;
568 }
569 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
570 dirname = newp;
571 ++filename;
572
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
581
582 if (filename[0] == '\0' && dirlen > 1 && !drive_root)
583 /* "pattern/". Expand "pattern", appending slashes. */
584 {
585 int orig_flags = flags;
586 if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
587 {
588 /* "pattern\\/". Remove the final backslash if it hasn't
589 been quoted. */
590 char *p = (char *) &dirname[dirlen - 1];
591
592 while (p > dirname && p[-1] == '\\') --p;
593 if ((&dirname[dirlen] - p) & 1)
594 {
595 *(char *) &dirname[--dirlen] = '\0';
596 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
597 }
598 }
599 int val = __glob (pattern: dirname, flags: 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)
604 {
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;
610 }
611 retval = val;
612 goto out;
613 }
614 }
615
616 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
617 {
618 if (dirname[1] == '\0' || dirname[1] == '/'
619 || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
620 && (dirname[2] == '\0' || dirname[2] == '/')))
621 {
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')
626 {
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");
632
633 if (home_drive != NULL && home_path != NULL)
634 {
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);
638
639 memcpy (mem, home_drive, home_drive_len);
640 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
641 home_dir = mem;
642 }
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 (buffer: &s);
651 while (true)
652 {
653 p = NULL;
654 err = __getlogin_r (s.data, s.length);
655 if (err == 0)
656 {
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
667 }
668 if (err != ERANGE)
669 break;
670 if (!scratch_buffer_grow (buffer: &s))
671 {
672 retval = GLOB_NOSPACE;
673 goto out;
674 }
675 }
676 if (err == 0)
677 {
678 home_dir = strdup (p->pw_dir);
679 malloc_home_dir = 1;
680 }
681 scratch_buffer_free (buffer: &s);
682 if (err == 0 && home_dir == NULL)
683 {
684 retval = GLOB_NOSPACE;
685 goto out;
686 }
687#endif /* WINDOWS32 */
688 }
689 if (home_dir == NULL || home_dir[0] == '\0')
690 {
691 if (__glibc_unlikely (malloc_home_dir))
692 free (ptr: home_dir);
693 if (flags & GLOB_TILDE_CHECK)
694 {
695 retval = GLOB_NOMATCH;
696 goto out;
697 }
698 else
699 {
700 home_dir = (char *) "~"; /* No luck. */
701 malloc_home_dir = 0;
702 }
703 }
704 /* Now construct the full directory. */
705 if (dirname[1] == '\0')
706 {
707 if (__glibc_unlikely (malloc_dirname))
708 free (ptr: dirname);
709
710 dirname = home_dir;
711 dirlen = strlen (dirname);
712 malloc_dirname = malloc_home_dir;
713 }
714 else
715 {
716 char *newp;
717 size_t home_len = strlen (home_dir);
718 int use_alloca = glob_use_alloca (alloca_used, len: home_len + dirlen);
719 if (use_alloca)
720 newp = alloca_account (home_len + dirlen, alloca_used);
721 else
722 {
723 newp = malloc (size: home_len + dirlen);
724 if (newp == NULL)
725 {
726 if (__glibc_unlikely (malloc_home_dir))
727 free (ptr: home_dir);
728 retval = GLOB_NOSPACE;
729 goto out;
730 }
731 }
732
733 mempcpy (mempcpy (newp, home_dir, home_len),
734 &dirname[1], dirlen);
735
736 if (__glibc_unlikely (malloc_dirname))
737 free (ptr: dirname);
738
739 dirname = newp;
740 dirlen += home_len - 1;
741 malloc_dirname = !use_alloca;
742
743 if (__glibc_unlikely (malloc_home_dir))
744 free (ptr: home_dir);
745 }
746 dirname_modified = 1;
747 }
748 else
749 {
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;
757
758 if (!(flags & GLOB_NOESCAPE))
759 {
760 if (end_name == NULL)
761 {
762 unescape = strchr (dirname, '\\');
763 if (unescape)
764 end_name = strchr (unescape, '\0');
765 }
766 else
767 unescape = memchr (dirname, '\\', end_name - dirname);
768 }
769 if (end_name == NULL)
770 user_name = dirname + 1;
771 else
772 {
773 char *newp;
774 if (glob_use_alloca (alloca_used, len: end_name - dirname))
775 newp = alloca_account (end_name - dirname, alloca_used);
776 else
777 {
778 newp = malloc (size: end_name - dirname);
779 if (newp == NULL)
780 {
781 retval = GLOB_NOSPACE;
782 goto out;
783 }
784 malloc_user_name = 1;
785 }
786 if (unescape != NULL)
787 {
788 char *p = mempcpy (newp, dirname + 1,
789 unescape - dirname - 1);
790 char *q = unescape;
791 while (q != end_name)
792 {
793 if (*q == '\\')
794 {
795 if (q + 1 == end_name)
796 {
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;
803 }
804 ++q;
805 }
806 *p++ = *q++;
807 }
808 *p = '\0';
809 }
810 else
811 *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
812 = '\0';
813 user_name = newp;
814 }
815
816 /* Look up specific user's home directory. */
817 {
818 struct passwd *p;
819 struct scratch_buffer pwtmpbuf;
820 scratch_buffer_init (buffer: &pwtmpbuf);
821
822# if defined HAVE_GETPWNAM_R || defined _LIBC
823 struct passwd pwbuf;
824
825 while (getpwnam_r (user_name, &pwbuf,
826 pwtmpbuf.data, pwtmpbuf.length, &p)
827 == ERANGE)
828 {
829 if (!scratch_buffer_grow (buffer: &pwtmpbuf))
830 {
831 retval = GLOB_NOSPACE;
832 goto out;
833 }
834 }
835# else
836 p = getpwnam (user_name);
837# endif
838
839 if (__glibc_unlikely (malloc_user_name))
840 free (ptr: user_name);
841
842 /* If we found a home directory use this. */
843 if (p != NULL)
844 {
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;
851
852 malloc_dirname = 0;
853
854 if (glob_use_alloca (alloca_used, len: home_len + rest_len + 1))
855 dirname = alloca_account (home_len + rest_len + 1,
856 alloca_used);
857 else
858 {
859 dirname = malloc (size: home_len + rest_len + 1);
860 if (dirname == NULL)
861 {
862 free (ptr: prev_dirname);
863 scratch_buffer_free (buffer: &pwtmpbuf);
864 retval = GLOB_NOSPACE;
865 goto out;
866 }
867 malloc_dirname = 1;
868 }
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';
873
874 free (ptr: prev_dirname);
875
876 dirlen = home_len + rest_len;
877 dirname_modified = 1;
878 }
879 else
880 {
881 if (flags & GLOB_TILDE_CHECK)
882 {
883 /* We have to regard it as an error if we cannot find the
884 home directory. */
885 retval = GLOB_NOMATCH;
886 goto out;
887 }
888 }
889 scratch_buffer_free (buffer: &pwtmpbuf);
890 }
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)
902 {
903 retval = GLOB_NOMATCH;
904 goto out;
905 }
906#endif /* WINDOWS32 */
907 }
908 }
909
910 /* Now test whether we looked for "~" or "~NAME". In this case we
911 can give the answer now. */
912 if (filename == NULL)
913 {
914 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
915 char **new_gl_pathv;
916
917 if (newcount > SIZE_MAX / sizeof (char *) - 2)
918 {
919 nospace:
920 free (ptr: pglob->gl_pathv);
921 pglob->gl_pathv = NULL;
922 pglob->gl_pathc = 0;
923 retval = GLOB_NOSPACE;
924 goto out;
925 }
926
927 new_gl_pathv = realloc (ptr: pglob->gl_pathv,
928 size: (newcount + 2) * sizeof (char *));
929 if (new_gl_pathv == NULL)
930 goto nospace;
931 pglob->gl_pathv = new_gl_pathv;
932
933 if (flags & GLOB_MARK && is_dir (filename: dirname, flags, pglob))
934 {
935 char *p;
936 pglob->gl_pathv[newcount] = malloc (size: 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 (ptr: dirname);
944 }
945 else
946 {
947 if (__glibc_unlikely (malloc_dirname))
948 pglob->gl_pathv[newcount] = dirname;
949 else
950 {
951 pglob->gl_pathv[newcount] = strdup (dirname);
952 if (pglob->gl_pathv[newcount] == NULL)
953 goto nospace;
954 }
955 }
956 pglob->gl_pathv[++newcount] = NULL;
957 ++pglob->gl_pathc;
958 pglob->gl_flags = flags;
959
960 return 0;
961 }
962
963 meta = __glob_pattern_type (pattern: dirname, quote: !(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))
970 {
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;
975
976 if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
977 {
978 /* "foo\\/bar". Remove the final backslash from dirname
979 if it has not been quoted. */
980 char *p = (char *) &dirname[dirlen - 1];
981
982 while (p > dirname && p[-1] == '\\') --p;
983 if ((&dirname[dirlen] - p) & 1)
984 *(char *) &dirname[--dirlen] = '\0';
985 }
986
987 if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
988 {
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;
996 }
997
998 status = __glob (pattern: dirname,
999 flags: ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
1000 | GLOB_NOSORT | GLOB_ONLYDIR),
1001 errfunc, pglob: &dirs);
1002 if (status != 0)
1003 {
1004 if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
1005 {
1006 retval = status;
1007 goto out;
1008 }
1009 goto no_matches;
1010 }
1011
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)
1016 {
1017 size_t old_pathc;
1018
1019 old_pathc = pglob->gl_pathc;
1020 status = glob_in_dir (pattern: filename, directory: dirs.gl_pathv[i],
1021 flags: ((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;
1027
1028 if (status != 0)
1029 {
1030 globfree (&dirs);
1031 globfree (pglob);
1032 pglob->gl_pathc = 0;
1033 retval = status;
1034 goto out;
1035 }
1036
1037 /* Stick the directory on the front of each name. */
1038 if (prefix_array (prefix: dirs.gl_pathv[i],
1039 array: &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1040 n: pglob->gl_pathc - old_pathc))
1041 {
1042 globfree (&dirs);
1043 globfree (pglob);
1044 pglob->gl_pathc = 0;
1045 retval = GLOB_NOSPACE;
1046 goto out;
1047 }
1048 }
1049
1050 flags |= GLOB_MAGCHAR;
1051
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)
1056 {
1057 no_matches:
1058 /* No matches. */
1059 if (flags & GLOB_NOCHECK)
1060 {
1061 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1062 char **new_gl_pathv;
1063
1064 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1065 {
1066 nospace2:
1067 globfree (&dirs);
1068 retval = GLOB_NOSPACE;
1069 goto out;
1070 }
1071
1072 new_gl_pathv = realloc (ptr: pglob->gl_pathv,
1073 size: (newcount + 2) * sizeof (char *));
1074 if (new_gl_pathv == NULL)
1075 goto nospace2;
1076 pglob->gl_pathv = new_gl_pathv;
1077
1078 pglob->gl_pathv[newcount] = strdup (pattern);
1079 if (pglob->gl_pathv[newcount] == NULL)
1080 {
1081 globfree (&dirs);
1082 globfree (pglob);
1083 pglob->gl_pathc = 0;
1084 retval = GLOB_NOSPACE;
1085 goto out;
1086 }
1087
1088 ++pglob->gl_pathc;
1089 ++newcount;
1090
1091 pglob->gl_pathv[newcount] = NULL;
1092 pglob->gl_flags = flags;
1093 }
1094 else
1095 {
1096 globfree (&dirs);
1097 retval = GLOB_NOMATCH;
1098 goto out;
1099 }
1100 }
1101
1102 globfree (&dirs);
1103 }
1104 else
1105 {
1106 size_t old_pathc = pglob->gl_pathc;
1107 int orig_flags = flags;
1108
1109 if (meta & GLOBPAT_BACKSLASH)
1110 {
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;
1116 do
1117 {
1118 if (*p == '\\')
1119 {
1120 *q = *++p;
1121 --dirlen;
1122 }
1123 else
1124 *q = *p;
1125 ++q;
1126 }
1127 while (*p++ != '\0');
1128 dirname_modified = 1;
1129 }
1130 if (dirname_modified)
1131 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
1132 status = glob_in_dir (pattern: filename, directory: dirname, flags, errfunc, pglob,
1133 alloca_used);
1134 if (status != 0)
1135 {
1136 if (status == GLOB_NOMATCH && flags != orig_flags
1137 && pglob->gl_pathc + pglob->gl_offs == oldcount)
1138 {
1139 /* Make sure globfree (&dirs); is a nop. */
1140 dirs.gl_pathv = NULL;
1141 flags = orig_flags;
1142 goto no_matches;
1143 }
1144 retval = status;
1145 goto out;
1146 }
1147
1148 if (dirlen > 0)
1149 {
1150 /* Stick the directory on the front of each name. */
1151 if (prefix_array (prefix: dirname,
1152 array: &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1153 n: pglob->gl_pathc - old_pathc))
1154 {
1155 globfree (pglob);
1156 pglob->gl_pathc = 0;
1157 retval = GLOB_NOSPACE;
1158 goto out;
1159 }
1160 }
1161 }
1162
1163 if (flags & GLOB_MARK)
1164 {
1165 /* Append slashes to directory names. */
1166 size_t i;
1167
1168 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
1169 if (is_dir (filename: pglob->gl_pathv[i], flags, pglob))
1170 {
1171 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1172 char *new = realloc (ptr: pglob->gl_pathv[i], size: len);
1173 if (new == NULL)
1174 {
1175 globfree (pglob);
1176 pglob->gl_pathc = 0;
1177 retval = GLOB_NOSPACE;
1178 goto out;
1179 }
1180 strcpy (&new[len - 2], "/");
1181 pglob->gl_pathv[i] = new;
1182 }
1183 }
1184
1185 if (!(flags & GLOB_NOSORT))
1186 {
1187 /* Sort the vector. */
1188 qsort (&pglob->gl_pathv[oldcount],
1189 pglob->gl_pathc + pglob->gl_offs - oldcount,
1190 sizeof (char *), collated_compare);
1191 }
1192
1193 out:
1194 if (__glibc_unlikely (malloc_dirname))
1195 free (ptr: dirname);
1196
1197 return retval;
1198}
1199#if defined _LIBC && !defined __glob
1200versioned_symbol (libc, __glob, glob, GLIBC_2_27);
1201libc_hidden_ver (__glob, glob)
1202#endif
1203
1204
1205/* Do a collated comparison of A and B. */
1206static int
1207collated_compare (const void *a, const void *b)
1208{
1209 char *const *ps1 = a; char *s1 = *ps1;
1210 char *const *ps2 = b; char *s2 = *ps2;
1211
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);
1219}
1220
1221
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. */
1226static int
1227prefix_array (const char *dirname, char **array, size_t n)
1228{
1229 size_t i;
1230 size_t dirlen = strlen (dirname);
1231 char dirsep_char = '/';
1232
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;
1237
1238#if defined __MSDOS__ || defined WINDOWS32
1239 if (dirlen > 1)
1240 {
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] == ':')
1245 {
1246 /* DIRNAME is "d:". Use ':' instead of '/'. */
1247 --dirlen;
1248 dirsep_char = ':';
1249 }
1250 }
1251#endif
1252
1253 for (i = 0; i < n; ++i)
1254 {
1255 size_t eltlen = strlen (array[i]) + 1;
1256 char *new = malloc (size: dirlen + 1 + eltlen);
1257 if (new == NULL)
1258 {
1259 while (i > 0)
1260 free (ptr: array[--i]);
1261 return 1;
1262 }
1263
1264 {
1265 char *endp = mempcpy (new, dirname, dirlen);
1266 *endp++ = dirsep_char;
1267 mempcpy (endp, array[i], eltlen);
1268 }
1269 free (ptr: array[i]);
1270 array[i] = new;
1271 }
1272
1273 return 0;
1274}
1275
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). */
1280static int
1281glob_in_dir (const char *pattern, const char *directory, int flags,
1282 int (*errfunc) (const char *, int),
1283 glob_t *pglob, size_t alloca_used)
1284{
1285 size_t dirlen = strlen (directory);
1286 void *stream = NULL;
1287 struct scratch_buffer s;
1288 scratch_buffer_init (buffer: &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;
1301
1302 alloca_used += sizeof init_names_buf;
1303
1304 init_names->next = NULL;
1305 init_names->count = ((sizeof init_names_buf
1306 - offsetof (struct globnames, name))
1307 / sizeof init_names->name[0]);
1308
1309 meta = __glob_pattern_type (pattern, quote: !(flags & GLOB_NOESCAPE));
1310 if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1311 {
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;
1316 }
1317 else if (meta == GLOBPAT_NONE)
1318 {
1319 size_t patlen = strlen (pattern);
1320 size_t fullsize;
1321 bool alloca_fullname
1322 = (! size_add_wrapv (a: dirlen + 1, b: patlen + 1, r: &fullsize)
1323 && glob_use_alloca (alloca_used, len: fullsize));
1324 char *fullname;
1325 if (alloca_fullname)
1326 fullname = alloca_account (fullsize, alloca_used);
1327 else
1328 {
1329 fullname = malloc (size: fullsize);
1330 if (fullname == NULL)
1331 return GLOB_NOSPACE;
1332 }
1333
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;
1342
1343 if (__glibc_unlikely (!alloca_fullname))
1344 free (ptr: fullname);
1345 }
1346 else
1347 {
1348 stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1349 ? (*pglob->gl_opendir) (directory)
1350 : opendir (directory));
1351 if (stream == NULL)
1352 {
1353 if (errno != ENOTDIR
1354 && ((errfunc != NULL && (*errfunc) (directory, errno))
1355 || (flags & GLOB_ERR)))
1356 return GLOB_ABORTED;
1357 }
1358 else
1359 {
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;
1364
1365 while (1)
1366 {
1367 struct readdir_result d;
1368 {
1369 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1370 d = convert_dirent (GL_READDIR (pglob, stream));
1371 else
1372 {
1373#ifdef COMPILE_GLOB64
1374 d = convert_dirent (__readdir (stream));
1375#else
1376 d = convert_dirent64 (source: __readdir64 (stream));
1377#endif
1378 }
1379 }
1380 if (d.name == NULL)
1381 break;
1382
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))
1387 {
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))
1394 {
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 (buffer: &s, nelem: need, size: 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 (filename: s.data, flags, pglob))
1405 continue;
1406 }
1407 else
1408 {
1409 struct_stat64 st64;
1410 if (! (GLOB_FSTATAT64 (dfd, d.name, &st64, 0) == 0
1411 && S_ISDIR (st64.st_mode)))
1412 continue;
1413 }
1414 }
1415
1416 if (fnmatch (pattern, d.name, fnm_flags) == 0)
1417 {
1418 if (cur == names->count)
1419 {
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, len: size))
1429 newnames = names_alloca
1430 = alloca_account (size, alloca_used);
1431 else if ((newnames = malloc (size: size))
1432 == NULL)
1433 goto memory_error;
1434 newnames->count = count;
1435 newnames->next = names;
1436 names = newnames;
1437 cur = 0;
1438 }
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;
1446 }
1447 }
1448 }
1449 }
1450
1451 if (nfound == 0 && (flags & GLOB_NOCHECK))
1452 {
1453 size_t len = strlen (pattern);
1454 nfound = 1;
1455 names->name[cur] = malloc (size: len + 1);
1456 if (names->name[cur] == NULL)
1457 goto memory_error;
1458 *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1459 }
1460
1461 result = GLOB_NOMATCH;
1462 if (nfound != 0)
1463 {
1464 char **new_gl_pathv;
1465 result = 0;
1466
1467 if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1468 < pglob->gl_offs + nfound + 1)
1469 goto memory_error;
1470
1471 new_gl_pathv
1472 = realloc (ptr: pglob->gl_pathv,
1473 size: (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1474 * sizeof (char *));
1475
1476 if (new_gl_pathv == NULL)
1477 {
1478 memory_error:
1479 while (1)
1480 {
1481 struct globnames *old = names;
1482 for (size_t i = 0; i < cur; ++i)
1483 free (ptr: 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)
1490 {
1491 assert (old == init_names);
1492 break;
1493 }
1494 cur = names->count;
1495 if (old == names_alloca)
1496 names_alloca = names;
1497 else
1498 free (ptr: old);
1499 }
1500 result = GLOB_NOSPACE;
1501 }
1502 else
1503 {
1504 while (1)
1505 {
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)
1516 {
1517 assert (old == init_names);
1518 break;
1519 }
1520 cur = names->count;
1521 if (old == names_alloca)
1522 names_alloca = names;
1523 else
1524 free (ptr: old);
1525 }
1526
1527 pglob->gl_pathv = new_gl_pathv;
1528
1529 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1530
1531 pglob->gl_flags = flags;
1532 }
1533 }
1534
1535 if (stream != NULL)
1536 {
1537 save = errno;
1538 if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
1539 (*pglob->gl_closedir) (stream);
1540 else
1541 closedir (stream);
1542 __set_errno (save);
1543 }
1544
1545 scratch_buffer_free (buffer: &s);
1546 return result;
1547}
1548

source code of glibc/posix/glob.c