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