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