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