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