]> git.ipfire.org Git - thirdparty/glibc.git/blob - posix/glob.c
posix: Allow glob to match dangling symlinks [BZ #866]
[thirdparty/glibc.git] / posix / glob.c
1 /* Copyright (C) 1991-2017 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 <http://www.gnu.org/licenses/>. */
17
18 #ifndef _LIBC
19 # include <config.h>
20 #endif
21
22 #include <glob.h>
23
24 #include <errno.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <assert.h>
31 #include <unistd.h>
32
33 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
34 # define WINDOWS32
35 #endif
36
37 #ifndef WINDOWS32
38 # include <pwd.h>
39 #endif
40
41 #include <errno.h>
42 #ifndef __set_errno
43 # define __set_errno(val) errno = (val)
44 #endif
45
46 #include <dirent.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <alloca.h>
50
51 #ifdef _LIBC
52 # undef strdup
53 # define strdup(str) __strdup (str)
54 # define sysconf(id) __sysconf (id)
55 # define closedir(dir) __closedir (dir)
56 # define opendir(name) __opendir (name)
57 # define readdir(str) __readdir64 (str)
58 # define getpwnam_r(name, bufp, buf, len, res) \
59 __getpwnam_r (name, bufp, buf, len, res)
60 # ifndef __lstat64
61 # define __lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
62 # endif
63 # ifndef __stat64
64 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
65 # endif
66 # define struct_stat64 struct stat64
67 # define FLEXIBLE_ARRAY_MEMBER
68 #else /* !_LIBC */
69 # define __getlogin_r(buf, len) getlogin_r (buf, len)
70 # define __lstat64(fname, buf) lstat (fname, buf)
71 # define __stat64(fname, buf) stat (fname, buf)
72 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
73 # define struct_stat64 struct stat
74 # ifndef __MVS__
75 # define __alloca alloca
76 # endif
77 # define __readdir readdir
78 # define COMPILE_GLOB64
79 #endif /* _LIBC */
80
81 #include <fnmatch.h>
82
83 #include <flexmember.h>
84 #include <glob_internal.h>
85
86 #ifdef _SC_GETPW_R_SIZE_MAX
87 # define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX)
88 #else
89 # define GETPW_R_SIZE_MAX() (-1)
90 #endif
91 #ifdef _SC_LOGIN_NAME_MAX
92 # define GET_LOGIN_NAME_MAX() sysconf (_SC_LOGIN_NAME_MAX)
93 #else
94 # define GET_LOGIN_NAME_MAX() (-1)
95 #endif
96 \f
97 static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
98
99 typedef uint_fast8_t dirent_type;
100
101 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
102 /* Any distinct values will do here.
103 Undef any existing macros out of the way. */
104 # undef DT_UNKNOWN
105 # undef DT_DIR
106 # undef DT_LNK
107 # define DT_UNKNOWN 0
108 # define DT_DIR 1
109 # define DT_LNK 2
110 #endif
111
112 /* A representation of a directory entry which does not depend on the
113 layout of struct dirent, or the size of ino_t. */
114 struct readdir_result
115 {
116 const char *name;
117 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
118 dirent_type type;
119 #endif
120 };
121
122 /* Initialize and return type member of struct readdir_result. */
123 static dirent_type
124 readdir_result_type (struct readdir_result d)
125 {
126 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
127 # define D_TYPE_TO_RESULT(source) (source)->d_type,
128 return d.type;
129 #else
130 # define D_TYPE_TO_RESULT(source)
131 return DT_UNKNOWN;
132 #endif
133 }
134
135 /* Construct an initializer for a struct readdir_result object from a
136 struct dirent *. No copy of the name is made. */
137 #define READDIR_RESULT_INITIALIZER(source) \
138 { \
139 source->d_name, \
140 D_TYPE_TO_RESULT (source) \
141 }
142
143 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
144 type safety if an old interface version needs to be supported. */
145 #ifndef GL_READDIR
146 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
147 #endif
148
149 /* Extract name and type from directory entry. No copy of the name is
150 made. If SOURCE is NULL, result name is NULL. Keep in sync with
151 convert_dirent64 below. */
152 static struct readdir_result
153 convert_dirent (const struct dirent *source)
154 {
155 if (source == NULL)
156 {
157 struct readdir_result result = { NULL, };
158 return result;
159 }
160 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
161 return result;
162 }
163
164 #ifndef COMPILE_GLOB64
165 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
166 sync with convert_dirent above. */
167 static struct readdir_result
168 convert_dirent64 (const struct dirent64 *source)
169 {
170 if (source == NULL)
171 {
172 struct readdir_result result = { NULL, };
173 return result;
174 }
175 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
176 return result;
177 }
178 #endif
179
180 #ifndef _LIBC
181 /* The results of opendir() in this file are not used with dirfd and fchdir,
182 and we do not leak fds to any single-threaded code that could use stdio,
183 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
184 FIXME - if the kernel ever adds support for multi-thread safety for
185 avoiding standard fds, then we should use opendir_safer. */
186 # ifdef GNULIB_defined_opendir
187 # undef opendir
188 # endif
189 # ifdef GNULIB_defined_closedir
190 # undef closedir
191 # endif
192
193 /* Just use malloc. */
194 # define __libc_use_alloca(n) false
195 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
196 # define extend_alloca_account(buf, len, newlen, avar) \
197 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
198 #endif
199
200 /* Set *R = A + B. Return true if the answer is mathematically
201 incorrect due to overflow; in this case, *R is the low order
202 bits of the correct answer. */
203
204 static bool
205 size_add_wrapv (size_t a, size_t b, size_t *r)
206 {
207 #if 5 <= __GNUC__ && !defined __ICC
208 return __builtin_add_overflow (a, b, r);
209 #else
210 *r = a + b;
211 return *r < a;
212 #endif
213 }
214
215 static bool
216 glob_use_alloca (size_t alloca_used, size_t len)
217 {
218 size_t size;
219 return (!size_add_wrapv (alloca_used, len, &size)
220 && __libc_use_alloca (size));
221 }
222
223 static int glob_in_dir (const char *pattern, const char *directory,
224 int flags, int (*errfunc) (const char *, int),
225 glob_t *pglob, size_t alloca_used);
226 extern int __glob_pattern_type (const char *pattern, int quote)
227 attribute_hidden;
228
229 static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
230 static int collated_compare (const void *, const void *) __THROWNL;
231
232
233 /* Return true if FILENAME is a directory or a symbolic link to a directory.
234 Use FLAGS and PGLOB to resolve the filename. */
235 static bool
236 is_dir (char const *filename, int flags, glob_t const *pglob)
237 {
238 struct stat st;
239 struct_stat64 st64;
240 return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
241 ? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
242 : __stat64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
243 }
244
245 /* Find the end of the sub-pattern in a brace expression. */
246 static const char *
247 next_brace_sub (const char *cp, int flags)
248 {
249 size_t depth = 0;
250 while (*cp != '\0')
251 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
252 {
253 if (*++cp == '\0')
254 break;
255 ++cp;
256 }
257 else
258 {
259 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
260 break;
261
262 if (*cp++ == '{')
263 depth++;
264 }
265
266 return *cp != '\0' ? cp : NULL;
267 }
268
269
270 /* Do glob searching for PATTERN, placing results in PGLOB.
271 The bits defined above may be set in FLAGS.
272 If a directory cannot be opened or read and ERRFUNC is not nil,
273 it is called with the pathname that caused the error, and the
274 'errno' value from the failing call; if it returns non-zero
275 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
276 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
277 Otherwise, 'glob' returns zero. */
278 int
279 #ifdef GLOB_ATTRIBUTE
280 GLOB_ATTRIBUTE
281 #endif
282 glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
283 glob_t *pglob)
284 {
285 const char *filename;
286 char *dirname = NULL;
287 size_t dirlen;
288 int status;
289 size_t oldcount;
290 int meta;
291 int dirname_modified;
292 int malloc_dirname = 0;
293 glob_t dirs;
294 int retval = 0;
295 size_t alloca_used = 0;
296
297 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
298 {
299 __set_errno (EINVAL);
300 return -1;
301 }
302
303 /* POSIX requires all slashes to be matched. This means that with
304 a trailing slash we must match only directories. */
305 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
306 flags |= GLOB_ONLYDIR;
307
308 if (!(flags & GLOB_DOOFFS))
309 /* Have to do this so 'globfree' knows where to start freeing. It
310 also makes all the code that uses gl_offs simpler. */
311 pglob->gl_offs = 0;
312
313 if (!(flags & GLOB_APPEND))
314 {
315 pglob->gl_pathc = 0;
316 if (!(flags & GLOB_DOOFFS))
317 pglob->gl_pathv = NULL;
318 else
319 {
320 size_t i;
321
322 if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
323 return GLOB_NOSPACE;
324
325 pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
326 * sizeof (char *));
327 if (pglob->gl_pathv == NULL)
328 return GLOB_NOSPACE;
329
330 for (i = 0; i <= pglob->gl_offs; ++i)
331 pglob->gl_pathv[i] = NULL;
332 }
333 }
334
335 if (flags & GLOB_BRACE)
336 {
337 const char *begin;
338
339 if (flags & GLOB_NOESCAPE)
340 begin = strchr (pattern, '{');
341 else
342 {
343 begin = pattern;
344 while (1)
345 {
346 if (*begin == '\0')
347 {
348 begin = NULL;
349 break;
350 }
351
352 if (*begin == '\\' && begin[1] != '\0')
353 ++begin;
354 else if (*begin == '{')
355 break;
356
357 ++begin;
358 }
359 }
360
361 if (begin != NULL)
362 {
363 /* Allocate working buffer large enough for our work. Note that
364 we have at least an opening and closing brace. */
365 size_t firstc;
366 char *alt_start;
367 const char *p;
368 const char *next;
369 const char *rest;
370 size_t rest_len;
371 char *onealt;
372 size_t pattern_len = strlen (pattern) - 1;
373 int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
374 if (alloca_onealt)
375 onealt = alloca_account (pattern_len, alloca_used);
376 else
377 {
378 onealt = malloc (pattern_len);
379 if (onealt == NULL)
380 return GLOB_NOSPACE;
381 }
382
383 /* We know the prefix for all sub-patterns. */
384 alt_start = mempcpy (onealt, pattern, begin - pattern);
385
386 /* Find the first sub-pattern and at the same time find the
387 rest after the closing brace. */
388 next = next_brace_sub (begin + 1, flags);
389 if (next == NULL)
390 {
391 /* It is an invalid expression. */
392 illegal_brace:
393 if (__glibc_unlikely (!alloca_onealt))
394 free (onealt);
395 flags &= ~GLOB_BRACE;
396 goto no_brace;
397 }
398
399 /* Now find the end of the whole brace expression. */
400 rest = next;
401 while (*rest != '}')
402 {
403 rest = next_brace_sub (rest + 1, flags);
404 if (rest == NULL)
405 /* It is an illegal expression. */
406 goto illegal_brace;
407 }
408 /* Please note that we now can be sure the brace expression
409 is well-formed. */
410 rest_len = strlen (++rest) + 1;
411
412 /* We have a brace expression. BEGIN points to the opening {,
413 NEXT points past the terminator of the first element, and END
414 points past the final }. We will accumulate result names from
415 recursive runs for each brace alternative in the buffer using
416 GLOB_APPEND. */
417 firstc = pglob->gl_pathc;
418
419 p = begin + 1;
420 while (1)
421 {
422 int result;
423
424 /* Construct the new glob expression. */
425 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
426
427 result = glob (onealt,
428 ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
429 | GLOB_APPEND), errfunc, pglob);
430
431 /* If we got an error, return it. */
432 if (result && result != GLOB_NOMATCH)
433 {
434 if (__glibc_unlikely (!alloca_onealt))
435 free (onealt);
436 if (!(flags & GLOB_APPEND))
437 {
438 globfree (pglob);
439 pglob->gl_pathc = 0;
440 }
441 return result;
442 }
443
444 if (*next == '}')
445 /* We saw the last entry. */
446 break;
447
448 p = next + 1;
449 next = next_brace_sub (p, flags);
450 assert (next != NULL);
451 }
452
453 if (__glibc_unlikely (!alloca_onealt))
454 free (onealt);
455
456 if (pglob->gl_pathc != firstc)
457 /* We found some entries. */
458 return 0;
459 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
460 return GLOB_NOMATCH;
461 }
462 }
463
464 no_brace:
465 oldcount = pglob->gl_pathc + pglob->gl_offs;
466
467 /* Find the filename. */
468 filename = strrchr (pattern, '/');
469
470 #if defined __MSDOS__ || defined WINDOWS32
471 /* The case of "d:pattern". Since ':' is not allowed in
472 file names, we can safely assume that wherever it
473 happens in pattern, it signals the filename part. This
474 is so we could some day support patterns like "[a-z]:foo". */
475 if (filename == NULL)
476 filename = strchr (pattern, ':');
477 #endif /* __MSDOS__ || WINDOWS32 */
478
479 dirname_modified = 0;
480 if (filename == NULL)
481 {
482 /* This can mean two things: a simple name or "~name". The latter
483 case is nothing but a notation for a directory. */
484 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
485 {
486 dirname = (char *) pattern;
487 dirlen = strlen (pattern);
488
489 /* Set FILENAME to NULL as a special flag. This is ugly but
490 other solutions would require much more code. We test for
491 this special case below. */
492 filename = NULL;
493 }
494 else
495 {
496 if (__glibc_unlikely (pattern[0] == '\0'))
497 {
498 dirs.gl_pathv = NULL;
499 goto no_matches;
500 }
501
502 filename = pattern;
503 dirname = (char *) ".";
504 dirlen = 0;
505 }
506 }
507 else if (filename == pattern
508 || (filename == pattern + 1 && pattern[0] == '\\'
509 && (flags & GLOB_NOESCAPE) == 0))
510 {
511 /* "/pattern" or "\\/pattern". */
512 dirname = (char *) "/";
513 dirlen = 1;
514 ++filename;
515 }
516 else
517 {
518 char *newp;
519 dirlen = filename - pattern;
520 #if defined __MSDOS__ || defined WINDOWS32
521 if (*filename == ':'
522 || (filename > pattern + 1 && filename[-1] == ':'))
523 {
524 char *drive_spec;
525
526 ++dirlen;
527 drive_spec = __alloca (dirlen + 1);
528 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
529 /* For now, disallow wildcards in the drive spec, to
530 prevent infinite recursion in glob. */
531 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
532 return GLOB_NOMATCH;
533 /* If this is "d:pattern", we need to copy ':' to DIRNAME
534 as well. If it's "d:/pattern", don't remove the slash
535 from "d:/", since "d:" and "d:/" are not the same.*/
536 }
537 #endif
538
539 if (glob_use_alloca (alloca_used, dirlen + 1))
540 newp = alloca_account (dirlen + 1, alloca_used);
541 else
542 {
543 newp = malloc (dirlen + 1);
544 if (newp == NULL)
545 return GLOB_NOSPACE;
546 malloc_dirname = 1;
547 }
548 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
549 dirname = newp;
550 ++filename;
551
552 #if defined __MSDOS__ || defined WINDOWS32
553 bool drive_root = (dirlen > 1
554 && (dirname[dirlen - 1] == ':'
555 || (dirlen > 2 && dirname[dirlen - 2] == ':'
556 && dirname[dirlen - 1] == '/')));
557 #else
558 bool drive_root = false;
559 #endif
560
561 if (filename[0] == '\0' && dirlen > 1 && !drive_root)
562 /* "pattern/". Expand "pattern", appending slashes. */
563 {
564 int orig_flags = flags;
565 if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
566 {
567 /* "pattern\\/". Remove the final backslash if it hasn't
568 been quoted. */
569 char *p = (char *) &dirname[dirlen - 1];
570
571 while (p > dirname && p[-1] == '\\') --p;
572 if ((&dirname[dirlen] - p) & 1)
573 {
574 *(char *) &dirname[--dirlen] = '\0';
575 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
576 }
577 }
578 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
579 if (val == 0)
580 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
581 | (flags & GLOB_MARK));
582 else if (val == GLOB_NOMATCH && flags != orig_flags)
583 {
584 /* Make sure globfree (&dirs); is a nop. */
585 dirs.gl_pathv = NULL;
586 flags = orig_flags;
587 oldcount = pglob->gl_pathc + pglob->gl_offs;
588 goto no_matches;
589 }
590 retval = val;
591 goto out;
592 }
593 }
594
595 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
596 {
597 if (dirname[1] == '\0' || dirname[1] == '/'
598 || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
599 && (dirname[2] == '\0' || dirname[2] == '/')))
600 {
601 /* Look up home directory. */
602 char *home_dir = getenv ("HOME");
603 int malloc_home_dir = 0;
604 if (home_dir == NULL || home_dir[0] == '\0')
605 {
606 #ifdef WINDOWS32
607 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
608 preference to HOME, because the user can change HOME. */
609 const char *home_drive = getenv ("HOMEDRIVE");
610 const char *home_path = getenv ("HOMEPATH");
611
612 if (home_drive != NULL && home_path != NULL)
613 {
614 size_t home_drive_len = strlen (home_drive);
615 size_t home_path_len = strlen (home_path);
616 char *mem = alloca (home_drive_len + home_path_len + 1);
617
618 memcpy (mem, home_drive, home_drive_len);
619 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
620 home_dir = mem;
621 }
622 else
623 home_dir = "c:/users/default"; /* poor default */
624 #else
625 int success;
626 char *name;
627 int malloc_name = 0;
628 size_t buflen = GET_LOGIN_NAME_MAX () + 1;
629
630 if (buflen == 0)
631 /* 'sysconf' does not support _SC_LOGIN_NAME_MAX. Try
632 a moderate value. */
633 buflen = 20;
634 if (glob_use_alloca (alloca_used, buflen))
635 name = alloca_account (buflen, alloca_used);
636 else
637 {
638 name = malloc (buflen);
639 if (name == NULL)
640 {
641 retval = GLOB_NOSPACE;
642 goto out;
643 }
644 malloc_name = 1;
645 }
646
647 success = __getlogin_r (name, buflen) == 0;
648 if (success)
649 {
650 struct passwd *p;
651 char *malloc_pwtmpbuf = NULL;
652 char *pwtmpbuf;
653 # if defined HAVE_GETPWNAM_R || defined _LIBC
654 long int pwbuflenmax = GETPW_R_SIZE_MAX ();
655 size_t pwbuflen = pwbuflenmax;
656 struct passwd pwbuf;
657 int save = errno;
658
659 # ifndef _LIBC
660 if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX))
661 /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.
662 Try a moderate value. */
663 pwbuflen = 1024;
664 # endif
665 if (glob_use_alloca (alloca_used, pwbuflen))
666 pwtmpbuf = alloca_account (pwbuflen, alloca_used);
667 else
668 {
669 pwtmpbuf = malloc (pwbuflen);
670 if (pwtmpbuf == NULL)
671 {
672 if (__glibc_unlikely (malloc_name))
673 free (name);
674 retval = GLOB_NOSPACE;
675 goto out;
676 }
677 malloc_pwtmpbuf = pwtmpbuf;
678 }
679
680 while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
681 != 0)
682 {
683 size_t newlen;
684 bool v;
685 if (errno != ERANGE)
686 {
687 p = NULL;
688 break;
689 }
690 v = size_add_wrapv (pwbuflen, pwbuflen, &newlen);
691 if (!v && malloc_pwtmpbuf == NULL
692 && glob_use_alloca (alloca_used, newlen))
693 pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen,
694 newlen, alloca_used);
695 else
696 {
697 char *newp = (v ? NULL
698 : realloc (malloc_pwtmpbuf, newlen));
699 if (newp == NULL)
700 {
701 free (malloc_pwtmpbuf);
702 if (__glibc_unlikely (malloc_name))
703 free (name);
704 retval = GLOB_NOSPACE;
705 goto out;
706 }
707 malloc_pwtmpbuf = pwtmpbuf = newp;
708 }
709 pwbuflen = newlen;
710 __set_errno (save);
711 }
712 # else
713 p = getpwnam (name);
714 # endif
715 if (__glibc_unlikely (malloc_name))
716 free (name);
717 if (p != NULL)
718 {
719 if (malloc_pwtmpbuf == NULL)
720 home_dir = p->pw_dir;
721 else
722 {
723 size_t home_dir_len = strlen (p->pw_dir) + 1;
724 if (glob_use_alloca (alloca_used, home_dir_len))
725 home_dir = alloca_account (home_dir_len,
726 alloca_used);
727 else
728 {
729 home_dir = malloc (home_dir_len);
730 if (home_dir == NULL)
731 {
732 free (pwtmpbuf);
733 retval = GLOB_NOSPACE;
734 goto out;
735 }
736 malloc_home_dir = 1;
737 }
738 memcpy (home_dir, p->pw_dir, home_dir_len);
739 }
740 }
741 free (malloc_pwtmpbuf);
742 }
743 else
744 {
745 if (__glibc_unlikely (malloc_name))
746 free (name);
747 }
748 #endif /* WINDOWS32 */
749 }
750 if (home_dir == NULL || home_dir[0] == '\0')
751 {
752 if (__glibc_unlikely (malloc_home_dir))
753 free (home_dir);
754 if (flags & GLOB_TILDE_CHECK)
755 {
756 retval = GLOB_NOMATCH;
757 goto out;
758 }
759 else
760 {
761 home_dir = (char *) "~"; /* No luck. */
762 malloc_home_dir = 0;
763 }
764 }
765 /* Now construct the full directory. */
766 if (dirname[1] == '\0')
767 {
768 if (__glibc_unlikely (malloc_dirname))
769 free (dirname);
770
771 dirname = home_dir;
772 dirlen = strlen (dirname);
773 malloc_dirname = malloc_home_dir;
774 }
775 else
776 {
777 char *newp;
778 size_t home_len = strlen (home_dir);
779 int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
780 if (use_alloca)
781 newp = alloca_account (home_len + dirlen, alloca_used);
782 else
783 {
784 newp = malloc (home_len + dirlen);
785 if (newp == NULL)
786 {
787 if (__glibc_unlikely (malloc_home_dir))
788 free (home_dir);
789 retval = GLOB_NOSPACE;
790 goto out;
791 }
792 }
793
794 mempcpy (mempcpy (newp, home_dir, home_len),
795 &dirname[1], dirlen);
796
797 if (__glibc_unlikely (malloc_dirname))
798 free (dirname);
799
800 dirname = newp;
801 dirlen += home_len - 1;
802 malloc_dirname = !use_alloca;
803
804 if (__glibc_unlikely (malloc_home_dir))
805 free (home_dir);
806 }
807 dirname_modified = 1;
808 }
809 else
810 {
811 #ifndef WINDOWS32
812 char *end_name = strchr (dirname, '/');
813 char *user_name;
814 int malloc_user_name = 0;
815 char *unescape = NULL;
816
817 if (!(flags & GLOB_NOESCAPE))
818 {
819 if (end_name == NULL)
820 {
821 unescape = strchr (dirname, '\\');
822 if (unescape)
823 end_name = strchr (unescape, '\0');
824 }
825 else
826 unescape = memchr (dirname, '\\', end_name - dirname);
827 }
828 if (end_name == NULL)
829 user_name = dirname + 1;
830 else
831 {
832 char *newp;
833 if (glob_use_alloca (alloca_used, end_name - dirname))
834 newp = alloca_account (end_name - dirname, alloca_used);
835 else
836 {
837 newp = malloc (end_name - dirname);
838 if (newp == NULL)
839 {
840 retval = GLOB_NOSPACE;
841 goto out;
842 }
843 malloc_user_name = 1;
844 }
845 if (unescape != NULL)
846 {
847 char *p = mempcpy (newp, dirname + 1,
848 unescape - dirname - 1);
849 char *q = unescape;
850 while (*q != '\0')
851 {
852 if (*q == '\\')
853 {
854 if (q[1] == '\0')
855 {
856 /* "~fo\\o\\" unescape to user_name "foo\\",
857 but "~fo\\o\\/" unescape to user_name
858 "foo". */
859 if (filename == NULL)
860 *p++ = '\\';
861 break;
862 }
863 ++q;
864 }
865 *p++ = *q++;
866 }
867 *p = '\0';
868 }
869 else
870 *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
871 = '\0';
872 user_name = newp;
873 }
874
875 /* Look up specific user's home directory. */
876 {
877 struct passwd *p;
878 char *malloc_pwtmpbuf = NULL;
879 # if defined HAVE_GETPWNAM_R || defined _LIBC
880 long int buflenmax = GETPW_R_SIZE_MAX ();
881 size_t buflen = buflenmax;
882 char *pwtmpbuf;
883 struct passwd pwbuf;
884 int save = errno;
885
886 # ifndef _LIBC
887 if (! (0 <= buflenmax && buflenmax <= SIZE_MAX))
888 /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
889 moderate value. */
890 buflen = 1024;
891 # endif
892 if (glob_use_alloca (alloca_used, buflen))
893 pwtmpbuf = alloca_account (buflen, alloca_used);
894 else
895 {
896 pwtmpbuf = malloc (buflen);
897 if (pwtmpbuf == NULL)
898 {
899 nomem_getpw:
900 if (__glibc_unlikely (malloc_user_name))
901 free (user_name);
902 retval = GLOB_NOSPACE;
903 goto out;
904 }
905 malloc_pwtmpbuf = pwtmpbuf;
906 }
907
908 while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
909 {
910 size_t newlen;
911 bool v;
912 if (errno != ERANGE)
913 {
914 p = NULL;
915 break;
916 }
917 v = size_add_wrapv (buflen, buflen, &newlen);
918 if (!v && malloc_pwtmpbuf == NULL
919 && glob_use_alloca (alloca_used, newlen))
920 pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen,
921 newlen, alloca_used);
922 else
923 {
924 char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen);
925 if (newp == NULL)
926 {
927 free (malloc_pwtmpbuf);
928 goto nomem_getpw;
929 }
930 malloc_pwtmpbuf = pwtmpbuf = newp;
931 }
932 __set_errno (save);
933 }
934 # else
935 p = getpwnam (user_name);
936 # endif
937
938 if (__glibc_unlikely (malloc_user_name))
939 free (user_name);
940
941 /* If we found a home directory use this. */
942 if (p != NULL)
943 {
944 size_t home_len = strlen (p->pw_dir);
945 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
946
947 if (__glibc_unlikely (malloc_dirname))
948 free (dirname);
949 malloc_dirname = 0;
950
951 if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
952 dirname = alloca_account (home_len + rest_len + 1,
953 alloca_used);
954 else
955 {
956 dirname = malloc (home_len + rest_len + 1);
957 if (dirname == NULL)
958 {
959 free (malloc_pwtmpbuf);
960 retval = GLOB_NOSPACE;
961 goto out;
962 }
963 malloc_dirname = 1;
964 }
965 *((char *) mempcpy (mempcpy (dirname, p->pw_dir, home_len),
966 end_name, rest_len)) = '\0';
967
968 dirlen = home_len + rest_len;
969 dirname_modified = 1;
970
971 free (malloc_pwtmpbuf);
972 }
973 else
974 {
975 free (malloc_pwtmpbuf);
976
977 if (flags & GLOB_TILDE_CHECK)
978 {
979 /* We have to regard it as an error if we cannot find the
980 home directory. */
981 retval = GLOB_NOMATCH;
982 goto out;
983 }
984 }
985 }
986 #endif /* !WINDOWS32 */
987 }
988 }
989
990 /* Now test whether we looked for "~" or "~NAME". In this case we
991 can give the answer now. */
992 if (filename == NULL)
993 {
994 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
995 char **new_gl_pathv;
996
997 if (newcount > SIZE_MAX / sizeof (char *) - 2)
998 {
999 nospace:
1000 free (pglob->gl_pathv);
1001 pglob->gl_pathv = NULL;
1002 pglob->gl_pathc = 0;
1003 retval = GLOB_NOSPACE;
1004 goto out;
1005 }
1006
1007 new_gl_pathv = realloc (pglob->gl_pathv,
1008 (newcount + 2) * sizeof (char *));
1009 if (new_gl_pathv == NULL)
1010 goto nospace;
1011 pglob->gl_pathv = new_gl_pathv;
1012
1013 if (flags & GLOB_MARK && is_dir (dirname, flags, pglob))
1014 {
1015 char *p;
1016 pglob->gl_pathv[newcount] = malloc (dirlen + 2);
1017 if (pglob->gl_pathv[newcount] == NULL)
1018 goto nospace;
1019 p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
1020 p[0] = '/';
1021 p[1] = '\0';
1022 if (__glibc_unlikely (malloc_dirname))
1023 free (dirname);
1024 }
1025 else
1026 {
1027 if (__glibc_unlikely (malloc_dirname))
1028 pglob->gl_pathv[newcount] = dirname;
1029 else
1030 {
1031 pglob->gl_pathv[newcount] = strdup (dirname);
1032 if (pglob->gl_pathv[newcount] == NULL)
1033 goto nospace;
1034 }
1035 }
1036 pglob->gl_pathv[++newcount] = NULL;
1037 ++pglob->gl_pathc;
1038 pglob->gl_flags = flags;
1039
1040 return 0;
1041 }
1042
1043 meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
1044 /* meta is 1 if correct glob pattern containing metacharacters.
1045 If meta has bit (1 << 2) set, it means there was an unterminated
1046 [ which we handle the same, using fnmatch. Broken unterminated
1047 pattern bracket expressions ought to be rare enough that it is
1048 not worth special casing them, fnmatch will do the right thing. */
1049 if (meta & 5)
1050 {
1051 /* The directory name contains metacharacters, so we
1052 have to glob for the directory, and then glob for
1053 the pattern in each directory found. */
1054 size_t i;
1055
1056 if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
1057 {
1058 /* "foo\\/bar". Remove the final backslash from dirname
1059 if it has not been quoted. */
1060 char *p = (char *) &dirname[dirlen - 1];
1061
1062 while (p > dirname && p[-1] == '\\') --p;
1063 if ((&dirname[dirlen] - p) & 1)
1064 *(char *) &dirname[--dirlen] = '\0';
1065 }
1066
1067 if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
1068 {
1069 /* Use the alternative access functions also in the recursive
1070 call. */
1071 dirs.gl_opendir = pglob->gl_opendir;
1072 dirs.gl_readdir = pglob->gl_readdir;
1073 dirs.gl_closedir = pglob->gl_closedir;
1074 dirs.gl_stat = pglob->gl_stat;
1075 dirs.gl_lstat = pglob->gl_lstat;
1076 }
1077
1078 status = glob (dirname,
1079 ((flags & (GLOB_ERR | GLOB_NOESCAPE
1080 | GLOB_ALTDIRFUNC))
1081 | GLOB_NOSORT | GLOB_ONLYDIR),
1082 errfunc, &dirs);
1083 if (status != 0)
1084 {
1085 if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
1086 {
1087 retval = status;
1088 goto out;
1089 }
1090 goto no_matches;
1091 }
1092
1093 /* We have successfully globbed the preceding directory name.
1094 For each name we found, call glob_in_dir on it and FILENAME,
1095 appending the results to PGLOB. */
1096 for (i = 0; i < dirs.gl_pathc; ++i)
1097 {
1098 size_t old_pathc;
1099
1100 old_pathc = pglob->gl_pathc;
1101 status = glob_in_dir (filename, dirs.gl_pathv[i],
1102 ((flags | GLOB_APPEND)
1103 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
1104 errfunc, pglob, alloca_used);
1105 if (status == GLOB_NOMATCH)
1106 /* No matches in this directory. Try the next. */
1107 continue;
1108
1109 if (status != 0)
1110 {
1111 globfree (&dirs);
1112 globfree (pglob);
1113 pglob->gl_pathc = 0;
1114 retval = status;
1115 goto out;
1116 }
1117
1118 /* Stick the directory on the front of each name. */
1119 if (prefix_array (dirs.gl_pathv[i],
1120 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1121 pglob->gl_pathc - old_pathc))
1122 {
1123 globfree (&dirs);
1124 globfree (pglob);
1125 pglob->gl_pathc = 0;
1126 retval = GLOB_NOSPACE;
1127 goto out;
1128 }
1129 }
1130
1131 flags |= GLOB_MAGCHAR;
1132
1133 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1134 But if we have not found any matching entry and the GLOB_NOCHECK
1135 flag was set we must return the input pattern itself. */
1136 if (pglob->gl_pathc + pglob->gl_offs == oldcount)
1137 {
1138 no_matches:
1139 /* No matches. */
1140 if (flags & GLOB_NOCHECK)
1141 {
1142 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1143 char **new_gl_pathv;
1144
1145 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1146 {
1147 nospace2:
1148 globfree (&dirs);
1149 retval = GLOB_NOSPACE;
1150 goto out;
1151 }
1152
1153 new_gl_pathv = realloc (pglob->gl_pathv,
1154 (newcount + 2) * sizeof (char *));
1155 if (new_gl_pathv == NULL)
1156 goto nospace2;
1157 pglob->gl_pathv = new_gl_pathv;
1158
1159 pglob->gl_pathv[newcount] = strdup (pattern);
1160 if (pglob->gl_pathv[newcount] == NULL)
1161 {
1162 globfree (&dirs);
1163 globfree (pglob);
1164 pglob->gl_pathc = 0;
1165 retval = GLOB_NOSPACE;
1166 goto out;
1167 }
1168
1169 ++pglob->gl_pathc;
1170 ++newcount;
1171
1172 pglob->gl_pathv[newcount] = NULL;
1173 pglob->gl_flags = flags;
1174 }
1175 else
1176 {
1177 globfree (&dirs);
1178 retval = GLOB_NOMATCH;
1179 goto out;
1180 }
1181 }
1182
1183 globfree (&dirs);
1184 }
1185 else
1186 {
1187 size_t old_pathc = pglob->gl_pathc;
1188 int orig_flags = flags;
1189
1190 if (meta & 2)
1191 {
1192 char *p = strchr (dirname, '\\'), *q;
1193 /* We need to unescape the dirname string. It is certainly
1194 allocated by alloca, as otherwise filename would be NULL
1195 or dirname wouldn't contain backslashes. */
1196 q = p;
1197 do
1198 {
1199 if (*p == '\\')
1200 {
1201 *q = *++p;
1202 --dirlen;
1203 }
1204 else
1205 *q = *p;
1206 ++q;
1207 }
1208 while (*p++ != '\0');
1209 dirname_modified = 1;
1210 }
1211 if (dirname_modified)
1212 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
1213 status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
1214 alloca_used);
1215 if (status != 0)
1216 {
1217 if (status == GLOB_NOMATCH && flags != orig_flags
1218 && pglob->gl_pathc + pglob->gl_offs == oldcount)
1219 {
1220 /* Make sure globfree (&dirs); is a nop. */
1221 dirs.gl_pathv = NULL;
1222 flags = orig_flags;
1223 goto no_matches;
1224 }
1225 retval = status;
1226 goto out;
1227 }
1228
1229 if (dirlen > 0)
1230 {
1231 /* Stick the directory on the front of each name. */
1232 if (prefix_array (dirname,
1233 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1234 pglob->gl_pathc - old_pathc))
1235 {
1236 globfree (pglob);
1237 pglob->gl_pathc = 0;
1238 retval = GLOB_NOSPACE;
1239 goto out;
1240 }
1241 }
1242 }
1243
1244 if (flags & GLOB_MARK)
1245 {
1246 /* Append slashes to directory names. */
1247 size_t i;
1248
1249 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
1250 if (is_dir (pglob->gl_pathv[i], flags, pglob))
1251 {
1252 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1253 char *new = realloc (pglob->gl_pathv[i], len);
1254 if (new == NULL)
1255 {
1256 globfree (pglob);
1257 pglob->gl_pathc = 0;
1258 retval = GLOB_NOSPACE;
1259 goto out;
1260 }
1261 strcpy (&new[len - 2], "/");
1262 pglob->gl_pathv[i] = new;
1263 }
1264 }
1265
1266 if (!(flags & GLOB_NOSORT))
1267 {
1268 /* Sort the vector. */
1269 qsort (&pglob->gl_pathv[oldcount],
1270 pglob->gl_pathc + pglob->gl_offs - oldcount,
1271 sizeof (char *), collated_compare);
1272 }
1273
1274 out:
1275 if (__glibc_unlikely (malloc_dirname))
1276 free (dirname);
1277
1278 return retval;
1279 }
1280 #if defined _LIBC && !defined glob
1281 libc_hidden_def (glob)
1282 #endif
1283
1284
1285 /* Do a collated comparison of A and B. */
1286 static int
1287 collated_compare (const void *a, const void *b)
1288 {
1289 char *const *ps1 = a; char *s1 = *ps1;
1290 char *const *ps2 = b; char *s2 = *ps2;
1291
1292 if (s1 == s2)
1293 return 0;
1294 if (s1 == NULL)
1295 return 1;
1296 if (s2 == NULL)
1297 return -1;
1298 return strcoll (s1, s2);
1299 }
1300
1301
1302 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1303 elements in place. Return nonzero if out of memory, zero if successful.
1304 A slash is inserted between DIRNAME and each elt of ARRAY,
1305 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1306 static int
1307 prefix_array (const char *dirname, char **array, size_t n)
1308 {
1309 size_t i;
1310 size_t dirlen = strlen (dirname);
1311 char dirsep_char = '/';
1312
1313 if (dirlen == 1 && dirname[0] == '/')
1314 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1315 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1316 dirlen = 0;
1317
1318 #if defined __MSDOS__ || defined WINDOWS32
1319 if (dirlen > 1)
1320 {
1321 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1322 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1323 --dirlen;
1324 else if (dirname[dirlen - 1] == ':')
1325 {
1326 /* DIRNAME is "d:". Use ':' instead of '/'. */
1327 --dirlen;
1328 dirsep_char = ':';
1329 }
1330 }
1331 #endif
1332
1333 for (i = 0; i < n; ++i)
1334 {
1335 size_t eltlen = strlen (array[i]) + 1;
1336 char *new = malloc (dirlen + 1 + eltlen);
1337 if (new == NULL)
1338 {
1339 while (i > 0)
1340 free (array[--i]);
1341 return 1;
1342 }
1343
1344 {
1345 char *endp = mempcpy (new, dirname, dirlen);
1346 *endp++ = dirsep_char;
1347 mempcpy (endp, array[i], eltlen);
1348 }
1349 free (array[i]);
1350 array[i] = new;
1351 }
1352
1353 return 0;
1354 }
1355
1356 /* Like 'glob', but PATTERN is a final pathname component,
1357 and matches are searched for in DIRECTORY.
1358 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1359 The GLOB_APPEND flag is assumed to be set (always appends). */
1360 static int
1361 glob_in_dir (const char *pattern, const char *directory, int flags,
1362 int (*errfunc) (const char *, int),
1363 glob_t *pglob, size_t alloca_used)
1364 {
1365 size_t dirlen = strlen (directory);
1366 void *stream = NULL;
1367 # define GLOBNAMES_MEMBERS(nnames) \
1368 struct globnames *next; size_t count; char *name[nnames];
1369 struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
1370 struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
1371 struct globnames *init_names = (struct globnames *) &init_names_buf;
1372 struct globnames *names = init_names;
1373 struct globnames *names_alloca = init_names;
1374 size_t nfound = 0;
1375 size_t cur = 0;
1376 int meta;
1377 int save;
1378 int result;
1379
1380 alloca_used += sizeof init_names_buf;
1381
1382 init_names->next = NULL;
1383 init_names->count = ((sizeof init_names_buf
1384 - offsetof (struct globnames, name))
1385 / sizeof init_names->name[0]);
1386
1387 meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
1388 if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1389 {
1390 /* We need not do any tests. The PATTERN contains no meta
1391 characters and we must not return an error therefore the
1392 result will always contain exactly one name. */
1393 flags |= GLOB_NOCHECK;
1394 }
1395 else if (meta == 0)
1396 {
1397 union
1398 {
1399 struct stat st;
1400 struct_stat64 st64;
1401 } ust;
1402 size_t patlen = strlen (pattern);
1403 size_t fullsize;
1404 bool alloca_fullname
1405 = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
1406 && glob_use_alloca (alloca_used, fullsize));
1407 char *fullname;
1408 if (alloca_fullname)
1409 fullname = alloca_account (fullsize, alloca_used);
1410 else
1411 {
1412 fullname = malloc (fullsize);
1413 if (fullname == NULL)
1414 return GLOB_NOSPACE;
1415 }
1416
1417 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1418 "/", 1),
1419 pattern, patlen + 1);
1420 if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1421 ? (*pglob->gl_lstat) (fullname, &ust.st)
1422 : __lstat64 (fullname, &ust.st64))
1423 == 0)
1424 || errno == EOVERFLOW)
1425 /* We found this file to be existing. Now tell the rest
1426 of the function to copy this name into the result. */
1427 flags |= GLOB_NOCHECK;
1428
1429 if (__glibc_unlikely (!alloca_fullname))
1430 free (fullname);
1431 }
1432 else
1433 {
1434 stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1435 ? (*pglob->gl_opendir) (directory)
1436 : opendir (directory));
1437 if (stream == NULL)
1438 {
1439 if (errno != ENOTDIR
1440 && ((errfunc != NULL && (*errfunc) (directory, errno))
1441 || (flags & GLOB_ERR)))
1442 return GLOB_ABORTED;
1443 }
1444 else
1445 {
1446 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1447 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
1448 flags |= GLOB_MAGCHAR;
1449
1450 while (1)
1451 {
1452 struct readdir_result d;
1453 {
1454 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1455 d = convert_dirent (GL_READDIR (pglob, stream));
1456 else
1457 {
1458 #ifdef COMPILE_GLOB64
1459 d = convert_dirent (__readdir (stream));
1460 #else
1461 d = convert_dirent64 (__readdir64 (stream));
1462 #endif
1463 }
1464 }
1465 if (d.name == NULL)
1466 break;
1467
1468 /* If we shall match only directories use the information
1469 provided by the dirent call if possible. */
1470 if (flags & GLOB_ONLYDIR)
1471 switch (readdir_result_type (d))
1472 {
1473 case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
1474 default: continue;
1475 }
1476
1477 if (fnmatch (pattern, d.name, fnm_flags) == 0)
1478 {
1479 if (cur == names->count)
1480 {
1481 struct globnames *newnames;
1482 size_t count = names->count * 2;
1483 size_t nameoff = offsetof (struct globnames, name);
1484 size_t size = FLEXSIZEOF (struct globnames, name,
1485 count * sizeof (char *));
1486 if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
1487 < names->count)
1488 goto memory_error;
1489 if (glob_use_alloca (alloca_used, size))
1490 newnames = names_alloca
1491 = alloca_account (size, alloca_used);
1492 else if ((newnames = malloc (size))
1493 == NULL)
1494 goto memory_error;
1495 newnames->count = count;
1496 newnames->next = names;
1497 names = newnames;
1498 cur = 0;
1499 }
1500 names->name[cur] = strdup (d.name);
1501 if (names->name[cur] == NULL)
1502 goto memory_error;
1503 ++cur;
1504 ++nfound;
1505 if (SIZE_MAX - pglob->gl_offs <= nfound)
1506 goto memory_error;
1507 }
1508 }
1509 }
1510 }
1511
1512 if (nfound == 0 && (flags & GLOB_NOCHECK))
1513 {
1514 size_t len = strlen (pattern);
1515 nfound = 1;
1516 names->name[cur] = malloc (len + 1);
1517 if (names->name[cur] == NULL)
1518 goto memory_error;
1519 *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1520 }
1521
1522 result = GLOB_NOMATCH;
1523 if (nfound != 0)
1524 {
1525 char **new_gl_pathv;
1526 result = 0;
1527
1528 if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1529 < pglob->gl_offs + nfound + 1)
1530 goto memory_error;
1531
1532 new_gl_pathv
1533 = realloc (pglob->gl_pathv,
1534 (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1535 * sizeof (char *));
1536
1537 if (new_gl_pathv == NULL)
1538 {
1539 memory_error:
1540 while (1)
1541 {
1542 struct globnames *old = names;
1543 for (size_t i = 0; i < cur; ++i)
1544 free (names->name[i]);
1545 names = names->next;
1546 /* NB: we will not leak memory here if we exit without
1547 freeing the current block assigned to OLD. At least
1548 the very first block is always allocated on the stack
1549 and this is the block assigned to OLD here. */
1550 if (names == NULL)
1551 {
1552 assert (old == init_names);
1553 break;
1554 }
1555 cur = names->count;
1556 if (old == names_alloca)
1557 names_alloca = names;
1558 else
1559 free (old);
1560 }
1561 result = GLOB_NOSPACE;
1562 }
1563 else
1564 {
1565 while (1)
1566 {
1567 struct globnames *old = names;
1568 for (size_t i = 0; i < cur; ++i)
1569 new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
1570 = names->name[i];
1571 names = names->next;
1572 /* NB: we will not leak memory here if we exit without
1573 freeing the current block assigned to OLD. At least
1574 the very first block is always allocated on the stack
1575 and this is the block assigned to OLD here. */
1576 if (names == NULL)
1577 {
1578 assert (old == init_names);
1579 break;
1580 }
1581 cur = names->count;
1582 if (old == names_alloca)
1583 names_alloca = names;
1584 else
1585 free (old);
1586 }
1587
1588 pglob->gl_pathv = new_gl_pathv;
1589
1590 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1591
1592 pglob->gl_flags = flags;
1593 }
1594 }
1595
1596 if (stream != NULL)
1597 {
1598 save = errno;
1599 if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
1600 (*pglob->gl_closedir) (stream);
1601 else
1602 closedir (stream);
1603 __set_errno (save);
1604 }
1605
1606 return result;
1607 }