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