1  /* Copyright (C) 1991-2023 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 <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  # undef dirfd
      60  # define dirfd(str) __dirfd (str)
      61  # define readdir(str) __readdir64 (str)
      62  # define getpwnam_r(name, bufp, buf, len, res) \
      63      __getpwnam_r (name, bufp, buf, len, res)
      64  # define FLEXIBLE_ARRAY_MEMBER
      65  # ifndef struct_stat
      66  #  define struct_stat           struct stat
      67  # endif
      68  # ifndef struct_stat64
      69  #  define struct_stat64         struct stat64
      70  # endif
      71  # ifndef GLOB_LSTAT
      72  #  define GLOB_LSTAT            gl_lstat
      73  # endif
      74  # ifndef GLOB_FSTATAT64
      75  #  define GLOB_FSTATAT64        __fstatat64
      76  # endif
      77  # include <shlib-compat.h>
      78  #else /* !_LIBC */
      79  # define __glob                 glob
      80  # define __getlogin_r(buf, len) getlogin_r (buf, len)
      81  # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
      82  # ifndef __MVS__
      83  #  define __alloca              alloca
      84  # endif
      85  # define __readdir              readdir
      86  # define COMPILE_GLOB64
      87  # define struct_stat            struct stat
      88  # define struct_stat64          struct stat
      89  # define GLOB_LSTAT             gl_lstat
      90  # define GLOB_FSTATAT64         fstatat
      91  #endif /* _LIBC */
      92  
      93  #include <fnmatch.h>
      94  
      95  #include <flexmember.h>
      96  #include <glob_internal.h>
      97  #include <scratch_buffer.h>
      98  
      99  static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
     100  
     101  /* The type of ((struct dirent *) 0)->d_type is 'unsigned char' on most
     102     platforms, but 'unsigned int' in the mingw from mingw.org.  */
     103  typedef uint_fast32_t dirent_type;
     104  
     105  #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
     106  /* Any distinct values will do here.
     107     Undef any existing macros out of the way.  */
     108  # undef DT_UNKNOWN
     109  # undef DT_DIR
     110  # undef DT_LNK
     111  # define DT_UNKNOWN 0
     112  # define DT_DIR 1
     113  # define DT_LNK 2
     114  #endif
     115  
     116  /* A representation of a directory entry which does not depend on the
     117     layout of struct dirent, or the size of ino_t.  */
     118  struct readdir_result
     119  {
     120    const char *name;
     121  #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
     122    dirent_type type;
     123  #endif
     124  };
     125  
     126  /* Initialize and return type member of struct readdir_result.  */
     127  static dirent_type
     128  readdir_result_type (struct readdir_result d)
     129  {
     130  #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
     131  # define D_TYPE_TO_RESULT(source) (source)->d_type,
     132    return d.type;
     133  #else
     134  # define D_TYPE_TO_RESULT(source)
     135    return DT_UNKNOWN;
     136  #endif
     137  }
     138  
     139  /* Construct an initializer for a struct readdir_result object from a
     140     struct dirent *.  No copy of the name is made.  */
     141  #define READDIR_RESULT_INITIALIZER(source) \
     142    {                                        \
     143      source->d_name,                        \
     144      D_TYPE_TO_RESULT (source)              \
     145    }
     146  
     147  /* Call gl_readdir on STREAM.  This macro can be overridden to reduce
     148     type safety if an old interface version needs to be supported.  */
     149  #ifndef GL_READDIR
     150  # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
     151  #endif
     152  
     153  /* Extract name and type from directory entry.  No copy of the name is
     154     made.  If SOURCE is NULL, result name is NULL.  Keep in sync with
     155     convert_dirent64 below.  */
     156  static struct readdir_result
     157  convert_dirent (const struct dirent *source)
     158  {
     159    if (source == NULL)
     160      {
     161        struct readdir_result result = { NULL, };
     162        return result;
     163      }
     164    struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
     165    return result;
     166  }
     167  
     168  #ifndef COMPILE_GLOB64
     169  /* Like convert_dirent, but works on struct dirent64 instead.  Keep in
     170     sync with convert_dirent above.  */
     171  static struct readdir_result
     172  convert_dirent64 (const struct dirent64 *source)
     173  {
     174    if (source == NULL)
     175      {
     176        struct readdir_result result = { NULL, };
     177        return result;
     178      }
     179    struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
     180    return result;
     181  }
     182  #endif
     183  
     184  #ifndef _LIBC
     185  /* The results of opendir() in this file are used with dirfd.  But they are
     186     not used with fchdir, and we do not leak fds to any single-threaded code
     187     that could use stdio, therefore save some unnecessary recursion in
     188     fchdir.c and opendir_safer.c.  */
     189  # ifndef GNULIB_defined_DIR
     190  #  ifdef GNULIB_defined_opendir
     191  #   undef opendir
     192  #  endif
     193  #  ifdef GNULIB_defined_closedir
     194  #   undef closedir
     195  #  endif
     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  }