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