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