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