xref: /netbsd-src/external/gpl2/gmake/dist/glob/glob.c (revision 327f8a3690adee8fb79c8a84e09a2d75fbfe880f)
169606e3fSchristos /* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
269606e3fSchristos 
369606e3fSchristos This library is free software; you can redistribute it and/or
469606e3fSchristos modify it under the terms of the GNU Library General Public License as
569606e3fSchristos published by the Free Software Foundation; either version 2 of the
669606e3fSchristos License, or (at your option) any later version.
769606e3fSchristos 
869606e3fSchristos This library is distributed in the hope that it will be useful,
969606e3fSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1069606e3fSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1169606e3fSchristos Library General Public License for more details.
1269606e3fSchristos 
1369606e3fSchristos You should have received a copy of the GNU Library General Public License
1469606e3fSchristos along with this library; see the file COPYING.LIB.  If not, write to the Free
1569606e3fSchristos Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
1669606e3fSchristos USA.  */
1769606e3fSchristos 
1869606e3fSchristos /* AIX requires this to be the first thing in the file.  */
1969606e3fSchristos #if defined _AIX && !defined __GNUC__
2069606e3fSchristos  #pragma alloca
2169606e3fSchristos #endif
2269606e3fSchristos 
2369606e3fSchristos #ifdef	HAVE_CONFIG_H
2469606e3fSchristos # include <config.h>
2569606e3fSchristos #endif
2669606e3fSchristos 
2769606e3fSchristos /* Enable GNU extensions in glob.h.  */
2869606e3fSchristos #ifndef _GNU_SOURCE
2969606e3fSchristos # define _GNU_SOURCE	1
3069606e3fSchristos #endif
3169606e3fSchristos 
3269606e3fSchristos #include <errno.h>
3369606e3fSchristos #include <sys/types.h>
3469606e3fSchristos #include <sys/stat.h>
3569606e3fSchristos 
3669606e3fSchristos /* Outcomment the following line for production quality code.  */
3769606e3fSchristos /* #define NDEBUG 1 */
3869606e3fSchristos #include <assert.h>
3969606e3fSchristos 
4069606e3fSchristos #include <stdio.h>		/* Needed on stupid SunOS for assert.  */
4169606e3fSchristos 
4269606e3fSchristos 
4369606e3fSchristos /* Comment out all this code if we are using the GNU C Library, and are not
4469606e3fSchristos    actually compiling the library itself.  This code is part of the GNU C
4569606e3fSchristos    Library, but also included in many other GNU distributions.  Compiling
4669606e3fSchristos    and linking in this code is a waste when using the GNU C library
4769606e3fSchristos    (especially if it is a shared library).  Rather than having every GNU
4869606e3fSchristos    program understand `configure --with-gnu-libc' and omit the object files,
4969606e3fSchristos    it is simpler to just do this in the source for each such file.  */
5069606e3fSchristos 
5169606e3fSchristos #define GLOB_INTERFACE_VERSION 1
5269606e3fSchristos #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
5369606e3fSchristos # include <gnu-versions.h>
5469606e3fSchristos # if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
5569606e3fSchristos #  define ELIDE_CODE
5669606e3fSchristos # endif
5769606e3fSchristos #endif
5869606e3fSchristos 
5969606e3fSchristos #ifndef ELIDE_CODE
6069606e3fSchristos 
6169606e3fSchristos #if defined STDC_HEADERS || defined __GNU_LIBRARY__
6269606e3fSchristos # include <stddef.h>
6369606e3fSchristos #endif
6469606e3fSchristos 
6569606e3fSchristos #if defined HAVE_UNISTD_H || defined _LIBC
6669606e3fSchristos # include <unistd.h>
6769606e3fSchristos # ifndef POSIX
6869606e3fSchristos #  ifdef _POSIX_VERSION
6969606e3fSchristos #   define POSIX
7069606e3fSchristos #  endif
7169606e3fSchristos # endif
7269606e3fSchristos #endif
7369606e3fSchristos 
7469606e3fSchristos #if !defined _AMIGA && !defined VMS && !defined WINDOWS32
7569606e3fSchristos # include <pwd.h>
7669606e3fSchristos #endif
7769606e3fSchristos 
7869606e3fSchristos #if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS
7969606e3fSchristos extern int errno;
8069606e3fSchristos #endif
8169606e3fSchristos #ifndef __set_errno
8269606e3fSchristos # define __set_errno(val) errno = (val)
8369606e3fSchristos #endif
8469606e3fSchristos 
8569606e3fSchristos #ifndef	NULL
8669606e3fSchristos # define NULL	0
8769606e3fSchristos #endif
8869606e3fSchristos 
8969606e3fSchristos 
9069606e3fSchristos #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
9169606e3fSchristos # include <dirent.h>
9269606e3fSchristos # define NAMLEN(dirent) strlen((dirent)->d_name)
9369606e3fSchristos #else
9469606e3fSchristos # define dirent direct
9569606e3fSchristos # define NAMLEN(dirent) (dirent)->d_namlen
9669606e3fSchristos # ifdef HAVE_SYS_NDIR_H
9769606e3fSchristos #  include <sys/ndir.h>
9869606e3fSchristos # endif
9969606e3fSchristos # ifdef HAVE_SYS_DIR_H
10069606e3fSchristos #  include <sys/dir.h>
10169606e3fSchristos # endif
10269606e3fSchristos # ifdef HAVE_NDIR_H
10369606e3fSchristos #  include <ndir.h>
10469606e3fSchristos # endif
10569606e3fSchristos # ifdef HAVE_VMSDIR_H
10669606e3fSchristos #  include "vmsdir.h"
10769606e3fSchristos # endif /* HAVE_VMSDIR_H */
10869606e3fSchristos #endif
10969606e3fSchristos 
11069606e3fSchristos 
11169606e3fSchristos /* In GNU systems, <dirent.h> defines this macro for us.  */
11269606e3fSchristos #ifdef _D_NAMLEN
11369606e3fSchristos # undef NAMLEN
11469606e3fSchristos # define NAMLEN(d) _D_NAMLEN(d)
11569606e3fSchristos #endif
11669606e3fSchristos 
11769606e3fSchristos /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
11869606e3fSchristos    if the `d_type' member for `struct dirent' is available.  */
11969606e3fSchristos #ifdef _DIRENT_HAVE_D_TYPE
12069606e3fSchristos # define HAVE_D_TYPE	1
12169606e3fSchristos #endif
12269606e3fSchristos 
12369606e3fSchristos 
12469606e3fSchristos #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
12569606e3fSchristos /* Posix does not require that the d_ino field be present, and some
12669606e3fSchristos    systems do not provide it. */
12769606e3fSchristos # define REAL_DIR_ENTRY(dp) 1
12869606e3fSchristos #else
12969606e3fSchristos # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
13069606e3fSchristos #endif /* POSIX */
13169606e3fSchristos 
13269606e3fSchristos #if defined STDC_HEADERS || defined __GNU_LIBRARY__
13369606e3fSchristos # include <stdlib.h>
13469606e3fSchristos # include <string.h>
13569606e3fSchristos # define	ANSI_STRING
13669606e3fSchristos #else	/* No standard headers.  */
13769606e3fSchristos 
13869606e3fSchristos extern char *getenv ();
13969606e3fSchristos 
14069606e3fSchristos # ifdef HAVE_STRING_H
14169606e3fSchristos #  include <string.h>
14269606e3fSchristos #  define ANSI_STRING
14369606e3fSchristos # else
14469606e3fSchristos #  include <strings.h>
14569606e3fSchristos # endif
14669606e3fSchristos # ifdef	HAVE_MEMORY_H
14769606e3fSchristos #  include <memory.h>
14869606e3fSchristos # endif
14969606e3fSchristos 
15069606e3fSchristos extern char *malloc (), *realloc ();
15169606e3fSchristos extern void free ();
15269606e3fSchristos 
15369606e3fSchristos extern void qsort ();
15469606e3fSchristos extern void abort (), exit ();
15569606e3fSchristos 
15669606e3fSchristos #endif	/* Standard headers.  */
15769606e3fSchristos 
15869606e3fSchristos #ifndef	ANSI_STRING
15969606e3fSchristos 
16069606e3fSchristos # ifndef bzero
16169606e3fSchristos extern void bzero ();
16269606e3fSchristos # endif
16369606e3fSchristos # ifndef bcopy
16469606e3fSchristos extern void bcopy ();
16569606e3fSchristos # endif
16669606e3fSchristos 
16769606e3fSchristos # define memcpy(d, s, n)	bcopy ((s), (d), (n))
16869606e3fSchristos # define strrchr	rindex
16969606e3fSchristos /* memset is only used for zero here, but let's be paranoid.  */
17069606e3fSchristos # define memset(s, better_be_zero, n) \
17169606e3fSchristos   ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
17269606e3fSchristos #endif	/* Not ANSI_STRING.  */
17369606e3fSchristos 
17469606e3fSchristos #if !defined HAVE_STRCOLL && !defined _LIBC
17569606e3fSchristos # define strcoll	strcmp
17669606e3fSchristos #endif
17769606e3fSchristos 
17869606e3fSchristos #if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1
17969606e3fSchristos # define HAVE_MEMPCPY	1
18069606e3fSchristos # undef  mempcpy
18169606e3fSchristos # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
18269606e3fSchristos #endif
18369606e3fSchristos 
18469606e3fSchristos #ifndef	__GNU_LIBRARY__
18569606e3fSchristos # ifdef	__GNUC__
18669606e3fSchristos __inline
18769606e3fSchristos # endif
18869606e3fSchristos # ifndef __SASC
18969606e3fSchristos #  ifdef WINDOWS32
19069606e3fSchristos static void *
my_realloc(void * p,unsigned int n)19169606e3fSchristos my_realloc (void *p, unsigned int n)
19269606e3fSchristos #  else
19369606e3fSchristos static char *
19469606e3fSchristos my_realloc (p, n)
19569606e3fSchristos      char *p;
19669606e3fSchristos      unsigned int n;
19769606e3fSchristos # endif
19869606e3fSchristos {
19969606e3fSchristos   /* These casts are the for sake of the broken Ultrix compiler,
20069606e3fSchristos      which warns of illegal pointer combinations otherwise.  */
20169606e3fSchristos   if (p == NULL)
20269606e3fSchristos     return (char *) malloc (n);
20369606e3fSchristos   return (char *) realloc (p, n);
20469606e3fSchristos }
20569606e3fSchristos # define	realloc	my_realloc
20669606e3fSchristos # endif /* __SASC */
20769606e3fSchristos #endif /* __GNU_LIBRARY__ */
20869606e3fSchristos 
20969606e3fSchristos 
210*327f8a36Snonaka #if !defined __alloca
21169606e3fSchristos 
21269606e3fSchristos # ifdef	__GNUC__
21369606e3fSchristos #  undef alloca
21469606e3fSchristos #  define alloca(n)	__builtin_alloca (n)
21569606e3fSchristos # else	/* Not GCC.  */
21669606e3fSchristos #  ifdef HAVE_ALLOCA_H
21769606e3fSchristos #   include <alloca.h>
21869606e3fSchristos #  else	/* Not HAVE_ALLOCA_H.  */
21969606e3fSchristos #   ifndef _AIX
22069606e3fSchristos #    ifdef WINDOWS32
22169606e3fSchristos #     include <malloc.h>
22269606e3fSchristos #    else
22369606e3fSchristos extern char *alloca ();
22469606e3fSchristos #    endif /* WINDOWS32 */
22569606e3fSchristos #   endif /* Not _AIX.  */
22669606e3fSchristos #  endif /* sparc or HAVE_ALLOCA_H.  */
22769606e3fSchristos # endif	/* GCC.  */
22869606e3fSchristos 
22969606e3fSchristos # define __alloca	alloca
23069606e3fSchristos 
23169606e3fSchristos #endif
23269606e3fSchristos 
233*327f8a36Snonaka #if !defined __stat
23469606e3fSchristos # define __stat stat
23569606e3fSchristos # ifdef STAT_MACROS_BROKEN
23669606e3fSchristos #  undef S_ISDIR
23769606e3fSchristos # endif
23869606e3fSchristos # ifndef S_ISDIR
23969606e3fSchristos #  define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
24069606e3fSchristos # endif
24169606e3fSchristos #endif
24269606e3fSchristos 
24369606e3fSchristos #ifdef _LIBC
24469606e3fSchristos # undef strdup
24569606e3fSchristos # define strdup(str) __strdup (str)
24669606e3fSchristos # define sysconf(id) __sysconf (id)
24769606e3fSchristos # define closedir(dir) __closedir (dir)
24869606e3fSchristos # define opendir(name) __opendir (name)
24969606e3fSchristos # define readdir(str) __readdir (str)
25069606e3fSchristos # define getpwnam_r(name, bufp, buf, len, res) \
25169606e3fSchristos    __getpwnam_r (name, bufp, buf, len, res)
25269606e3fSchristos # ifndef __stat
25369606e3fSchristos #  define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
25469606e3fSchristos # endif
25569606e3fSchristos #endif
25669606e3fSchristos 
25769606e3fSchristos #if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
25869606e3fSchristos # undef	size_t
25969606e3fSchristos # define size_t	unsigned int
26069606e3fSchristos #endif
26169606e3fSchristos 
26269606e3fSchristos /* Some system header files erroneously define these.
26369606e3fSchristos    We want our own definitions from <fnmatch.h> to take precedence.  */
26469606e3fSchristos #ifndef __GNU_LIBRARY__
26569606e3fSchristos # undef	FNM_PATHNAME
26669606e3fSchristos # undef	FNM_NOESCAPE
26769606e3fSchristos # undef	FNM_PERIOD
26869606e3fSchristos #endif
26969606e3fSchristos #include <fnmatch.h>
27069606e3fSchristos 
27169606e3fSchristos /* Some system header files erroneously define these.
27269606e3fSchristos    We want our own definitions from <glob.h> to take precedence.  */
27369606e3fSchristos #ifndef __GNU_LIBRARY__
27469606e3fSchristos # undef	GLOB_ERR
27569606e3fSchristos # undef	GLOB_MARK
27669606e3fSchristos # undef	GLOB_NOSORT
27769606e3fSchristos # undef	GLOB_DOOFFS
27869606e3fSchristos # undef	GLOB_NOCHECK
27969606e3fSchristos # undef	GLOB_APPEND
28069606e3fSchristos # undef	GLOB_NOESCAPE
28169606e3fSchristos # undef	GLOB_PERIOD
28269606e3fSchristos #endif
28369606e3fSchristos #include <glob.h>
28469606e3fSchristos 
28569606e3fSchristos #ifdef HAVE_GETLOGIN_R
28669606e3fSchristos extern int getlogin_r __P ((char *, size_t));
28769606e3fSchristos #else
28869606e3fSchristos extern char *getlogin __P ((void));
28969606e3fSchristos #endif
29069606e3fSchristos 
29169606e3fSchristos static
29269606e3fSchristos #if __GNUC__ - 0 >= 2
29369606e3fSchristos inline
29469606e3fSchristos #endif
29569606e3fSchristos const char *next_brace_sub __P ((const char *begin));
29669606e3fSchristos static int glob_in_dir __P ((const char *pattern, const char *directory,
29769606e3fSchristos 			     int flags,
29869606e3fSchristos 			     int (*errfunc) (const char *, int),
29969606e3fSchristos 			     glob_t *pglob));
30069606e3fSchristos static int prefix_array __P ((const char *prefix, char **array, size_t n));
30169606e3fSchristos static int collated_compare __P ((const __ptr_t, const __ptr_t));
30269606e3fSchristos 
30369606e3fSchristos #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
30469606e3fSchristos int __glob_pattern_p __P ((const char *pattern, int quote));
30569606e3fSchristos #endif
30669606e3fSchristos 
30769606e3fSchristos /* Find the end of the sub-pattern in a brace expression.  We define
30869606e3fSchristos    this as an inline function if the compiler permits.  */
30969606e3fSchristos static
31069606e3fSchristos #if __GNUC__ - 0 >= 2
31169606e3fSchristos inline
31269606e3fSchristos #endif
31369606e3fSchristos const char *
next_brace_sub(begin)31469606e3fSchristos next_brace_sub (begin)
31569606e3fSchristos      const char *begin;
31669606e3fSchristos {
31769606e3fSchristos   unsigned int depth = 0;
31869606e3fSchristos   const char *cp = begin;
31969606e3fSchristos 
32069606e3fSchristos   while (1)
32169606e3fSchristos     {
32269606e3fSchristos       if (depth == 0)
32369606e3fSchristos 	{
32469606e3fSchristos 	  if (*cp != ',' && *cp != '}' && *cp != '\0')
32569606e3fSchristos 	    {
32669606e3fSchristos 	      if (*cp == '{')
32769606e3fSchristos 		++depth;
32869606e3fSchristos 	      ++cp;
32969606e3fSchristos 	      continue;
33069606e3fSchristos 	    }
33169606e3fSchristos 	}
33269606e3fSchristos       else
33369606e3fSchristos 	{
33469606e3fSchristos 	  while (*cp != '\0' && (*cp != '}' || depth > 0))
33569606e3fSchristos 	    {
33669606e3fSchristos 	      if (*cp == '}')
33769606e3fSchristos 		--depth;
33869606e3fSchristos 	      ++cp;
33969606e3fSchristos 	    }
34069606e3fSchristos 	  if (*cp == '\0')
34169606e3fSchristos 	    /* An incorrectly terminated brace expression.  */
34269606e3fSchristos 	    return NULL;
34369606e3fSchristos 
34469606e3fSchristos 	  continue;
34569606e3fSchristos 	}
34669606e3fSchristos       break;
34769606e3fSchristos     }
34869606e3fSchristos 
34969606e3fSchristos   return cp;
35069606e3fSchristos }
35169606e3fSchristos 
35269606e3fSchristos /* Do glob searching for PATTERN, placing results in PGLOB.
35369606e3fSchristos    The bits defined above may be set in FLAGS.
35469606e3fSchristos    If a directory cannot be opened or read and ERRFUNC is not nil,
35569606e3fSchristos    it is called with the pathname that caused the error, and the
35669606e3fSchristos    `errno' value from the failing call; if it returns non-zero
35769606e3fSchristos    `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
35869606e3fSchristos    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
35969606e3fSchristos    Otherwise, `glob' returns zero.  */
36069606e3fSchristos int
glob(pattern,flags,errfunc,pglob)36169606e3fSchristos glob (pattern, flags, errfunc, pglob)
36269606e3fSchristos      const char *pattern;
36369606e3fSchristos      int flags;
36469606e3fSchristos      int (*errfunc) __P ((const char *, int));
36569606e3fSchristos      glob_t *pglob;
36669606e3fSchristos {
36769606e3fSchristos   const char *filename;
36869606e3fSchristos   const char *dirname;
36969606e3fSchristos   size_t dirlen;
37069606e3fSchristos   int status;
37169606e3fSchristos   int oldcount;
37269606e3fSchristos 
37369606e3fSchristos   if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
37469606e3fSchristos     {
37569606e3fSchristos       __set_errno (EINVAL);
37669606e3fSchristos       return -1;
37769606e3fSchristos     }
37869606e3fSchristos 
37969606e3fSchristos   if (flags & GLOB_BRACE)
38069606e3fSchristos     {
38169606e3fSchristos       const char *begin = strchr (pattern, '{');
38269606e3fSchristos       if (begin != NULL)
38369606e3fSchristos 	{
38469606e3fSchristos 	  /* Allocate working buffer large enough for our work.  Note that
38569606e3fSchristos 	    we have at least an opening and closing brace.  */
38669606e3fSchristos 	  int firstc;
38769606e3fSchristos 	  char *alt_start;
38869606e3fSchristos 	  const char *p;
38969606e3fSchristos 	  const char *next;
39069606e3fSchristos 	  const char *rest;
39169606e3fSchristos 	  size_t rest_len;
39269606e3fSchristos #ifdef __GNUC__
39369606e3fSchristos 	  char onealt[strlen (pattern) - 1];
39469606e3fSchristos #else
39569606e3fSchristos 	  char *onealt = (char *) malloc (strlen (pattern) - 1);
39669606e3fSchristos 	  if (onealt == NULL)
39769606e3fSchristos 	    {
39869606e3fSchristos 	      if (!(flags & GLOB_APPEND))
39969606e3fSchristos 		globfree (pglob);
40069606e3fSchristos 	      return GLOB_NOSPACE;
40169606e3fSchristos 	    }
40269606e3fSchristos #endif
40369606e3fSchristos 
40469606e3fSchristos 	  /* We know the prefix for all sub-patterns.  */
40569606e3fSchristos #ifdef HAVE_MEMPCPY
40669606e3fSchristos 	  alt_start = mempcpy (onealt, pattern, begin - pattern);
40769606e3fSchristos #else
40869606e3fSchristos 	  memcpy (onealt, pattern, begin - pattern);
40969606e3fSchristos 	  alt_start = &onealt[begin - pattern];
41069606e3fSchristos #endif
41169606e3fSchristos 
41269606e3fSchristos 	  /* Find the first sub-pattern and at the same time find the
41369606e3fSchristos 	     rest after the closing brace.  */
41469606e3fSchristos 	  next = next_brace_sub (begin + 1);
41569606e3fSchristos 	  if (next == NULL)
41669606e3fSchristos 	    {
41769606e3fSchristos 	      /* It is an illegal expression.  */
41869606e3fSchristos #ifndef __GNUC__
41969606e3fSchristos 	      free (onealt);
42069606e3fSchristos #endif
42169606e3fSchristos 	      return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
42269606e3fSchristos 	    }
42369606e3fSchristos 
42469606e3fSchristos 	  /* Now find the end of the whole brace expression.  */
42569606e3fSchristos 	  rest = next;
42669606e3fSchristos 	  while (*rest != '}')
42769606e3fSchristos 	    {
42869606e3fSchristos 	      rest = next_brace_sub (rest + 1);
42969606e3fSchristos 	      if (rest == NULL)
43069606e3fSchristos 		{
43169606e3fSchristos 		  /* It is an illegal expression.  */
43269606e3fSchristos #ifndef __GNUC__
43369606e3fSchristos 		  free (onealt);
43469606e3fSchristos #endif
43569606e3fSchristos 		  return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
43669606e3fSchristos 		}
43769606e3fSchristos 	    }
43869606e3fSchristos 	  /* Please note that we now can be sure the brace expression
43969606e3fSchristos 	     is well-formed.  */
44069606e3fSchristos 	  rest_len = strlen (++rest) + 1;
44169606e3fSchristos 
44269606e3fSchristos 	  /* We have a brace expression.  BEGIN points to the opening {,
44369606e3fSchristos 	     NEXT points past the terminator of the first element, and END
44469606e3fSchristos 	     points past the final }.  We will accumulate result names from
44569606e3fSchristos 	     recursive runs for each brace alternative in the buffer using
44669606e3fSchristos 	     GLOB_APPEND.  */
44769606e3fSchristos 
44869606e3fSchristos 	  if (!(flags & GLOB_APPEND))
44969606e3fSchristos 	    {
45069606e3fSchristos 	      /* This call is to set a new vector, so clear out the
45169606e3fSchristos 		 vector so we can append to it.  */
45269606e3fSchristos 	      pglob->gl_pathc = 0;
45369606e3fSchristos 	      pglob->gl_pathv = NULL;
45469606e3fSchristos 	    }
45569606e3fSchristos 	  firstc = pglob->gl_pathc;
45669606e3fSchristos 
45769606e3fSchristos 	  p = begin + 1;
45869606e3fSchristos 	  while (1)
45969606e3fSchristos 	    {
46069606e3fSchristos 	      int result;
46169606e3fSchristos 
46269606e3fSchristos 	      /* Construct the new glob expression.  */
46369606e3fSchristos #ifdef HAVE_MEMPCPY
46469606e3fSchristos 	      mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
46569606e3fSchristos #else
46669606e3fSchristos 	      memcpy (alt_start, p, next - p);
46769606e3fSchristos 	      memcpy (&alt_start[next - p], rest, rest_len);
46869606e3fSchristos #endif
46969606e3fSchristos 
47069606e3fSchristos 	      result = glob (onealt,
47169606e3fSchristos 			     ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
47269606e3fSchristos 			      | GLOB_APPEND), errfunc, pglob);
47369606e3fSchristos 
47469606e3fSchristos 	      /* If we got an error, return it.  */
47569606e3fSchristos 	      if (result && result != GLOB_NOMATCH)
47669606e3fSchristos 		{
47769606e3fSchristos #ifndef __GNUC__
47869606e3fSchristos 		  free (onealt);
47969606e3fSchristos #endif
48069606e3fSchristos 		  if (!(flags & GLOB_APPEND))
48169606e3fSchristos 		    globfree (pglob);
48269606e3fSchristos 		  return result;
48369606e3fSchristos 		}
48469606e3fSchristos 
48569606e3fSchristos 	      if (*next == '}')
48669606e3fSchristos 		/* We saw the last entry.  */
48769606e3fSchristos 		break;
48869606e3fSchristos 
48969606e3fSchristos 	      p = next + 1;
49069606e3fSchristos 	      next = next_brace_sub (p);
49169606e3fSchristos 	      assert (next != NULL);
49269606e3fSchristos 	    }
49369606e3fSchristos 
49469606e3fSchristos #ifndef __GNUC__
49569606e3fSchristos 	  free (onealt);
49669606e3fSchristos #endif
49769606e3fSchristos 
49869606e3fSchristos 	  if (pglob->gl_pathc != firstc)
49969606e3fSchristos 	    /* We found some entries.  */
50069606e3fSchristos 	    return 0;
50169606e3fSchristos 	  else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
50269606e3fSchristos 	    return GLOB_NOMATCH;
50369606e3fSchristos 	}
50469606e3fSchristos     }
50569606e3fSchristos 
50669606e3fSchristos   /* Find the filename.  */
50769606e3fSchristos   filename = strrchr (pattern, '/');
50869606e3fSchristos #if defined __MSDOS__ || defined WINDOWS32
50969606e3fSchristos   /* The case of "d:pattern".  Since `:' is not allowed in
51069606e3fSchristos      file names, we can safely assume that wherever it
51169606e3fSchristos      happens in pattern, it signals the filename part.  This
51269606e3fSchristos      is so we could some day support patterns like "[a-z]:foo".  */
51369606e3fSchristos   if (filename == NULL)
51469606e3fSchristos     filename = strchr (pattern, ':');
51569606e3fSchristos #endif /* __MSDOS__ || WINDOWS32 */
51669606e3fSchristos   if (filename == NULL)
51769606e3fSchristos     {
51869606e3fSchristos       /* This can mean two things: a simple name or "~name".  The later
51969606e3fSchristos 	 case is nothing but a notation for a directory.  */
52069606e3fSchristos       if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
52169606e3fSchristos 	{
52269606e3fSchristos 	  dirname = pattern;
52369606e3fSchristos 	  dirlen = strlen (pattern);
52469606e3fSchristos 
52569606e3fSchristos 	  /* Set FILENAME to NULL as a special flag.  This is ugly but
52669606e3fSchristos 	     other solutions would require much more code.  We test for
52769606e3fSchristos 	     this special case below.  */
52869606e3fSchristos 	  filename = NULL;
52969606e3fSchristos 	}
53069606e3fSchristos       else
53169606e3fSchristos 	{
53269606e3fSchristos 	  filename = pattern;
53369606e3fSchristos #ifdef _AMIGA
53469606e3fSchristos 	  dirname = "";
53569606e3fSchristos #else
53669606e3fSchristos 	  dirname = ".";
53769606e3fSchristos #endif
53869606e3fSchristos 	  dirlen = 0;
53969606e3fSchristos 	}
54069606e3fSchristos     }
54169606e3fSchristos   else if (filename == pattern)
54269606e3fSchristos     {
54369606e3fSchristos       /* "/pattern".  */
54469606e3fSchristos       dirname = "/";
54569606e3fSchristos       dirlen = 1;
54669606e3fSchristos       ++filename;
54769606e3fSchristos     }
54869606e3fSchristos   else
54969606e3fSchristos     {
55069606e3fSchristos       char *newp;
55169606e3fSchristos       dirlen = filename - pattern;
55269606e3fSchristos #if defined __MSDOS__ || defined WINDOWS32
55369606e3fSchristos       if (*filename == ':'
55469606e3fSchristos 	  || (filename > pattern + 1 && filename[-1] == ':'))
55569606e3fSchristos 	{
55669606e3fSchristos 	  char *drive_spec;
55769606e3fSchristos 
55869606e3fSchristos 	  ++dirlen;
55969606e3fSchristos 	  drive_spec = (char *) __alloca (dirlen + 1);
56069606e3fSchristos #ifdef HAVE_MEMPCPY
56169606e3fSchristos 	  *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
56269606e3fSchristos #else
56369606e3fSchristos 	  memcpy (drive_spec, pattern, dirlen);
56469606e3fSchristos 	  drive_spec[dirlen] = '\0';
56569606e3fSchristos #endif
56669606e3fSchristos 	  /* For now, disallow wildcards in the drive spec, to
56769606e3fSchristos 	     prevent infinite recursion in glob.  */
56869606e3fSchristos 	  if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
56969606e3fSchristos 	    return GLOB_NOMATCH;
57069606e3fSchristos 	  /* If this is "d:pattern", we need to copy `:' to DIRNAME
57169606e3fSchristos 	     as well.  If it's "d:/pattern", don't remove the slash
57269606e3fSchristos 	     from "d:/", since "d:" and "d:/" are not the same.*/
57369606e3fSchristos 	}
57469606e3fSchristos #endif
57569606e3fSchristos       newp = (char *) __alloca (dirlen + 1);
57669606e3fSchristos #ifdef HAVE_MEMPCPY
57769606e3fSchristos       *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
57869606e3fSchristos #else
57969606e3fSchristos       memcpy (newp, pattern, dirlen);
58069606e3fSchristos       newp[dirlen] = '\0';
58169606e3fSchristos #endif
58269606e3fSchristos       dirname = newp;
58369606e3fSchristos       ++filename;
58469606e3fSchristos 
58569606e3fSchristos       if (filename[0] == '\0'
58669606e3fSchristos #if defined __MSDOS__ || defined WINDOWS32
58769606e3fSchristos           && dirname[dirlen - 1] != ':'
58869606e3fSchristos 	  && (dirlen < 3 || dirname[dirlen - 2] != ':'
58969606e3fSchristos 	      || dirname[dirlen - 1] != '/')
59069606e3fSchristos #endif
59169606e3fSchristos 	  && dirlen > 1)
59269606e3fSchristos 	/* "pattern/".  Expand "pattern", appending slashes.  */
59369606e3fSchristos 	{
59469606e3fSchristos 	  int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
59569606e3fSchristos 	  if (val == 0)
59669606e3fSchristos 	    pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
59769606e3fSchristos 			       | (flags & GLOB_MARK));
59869606e3fSchristos 	  return val;
59969606e3fSchristos 	}
60069606e3fSchristos     }
60169606e3fSchristos 
60269606e3fSchristos   if (!(flags & GLOB_APPEND))
60369606e3fSchristos     {
60469606e3fSchristos       pglob->gl_pathc = 0;
60569606e3fSchristos       pglob->gl_pathv = NULL;
60669606e3fSchristos     }
60769606e3fSchristos 
60869606e3fSchristos   oldcount = pglob->gl_pathc;
60969606e3fSchristos 
61069606e3fSchristos #ifndef VMS
61169606e3fSchristos   if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
61269606e3fSchristos     {
61369606e3fSchristos       if (dirname[1] == '\0' || dirname[1] == '/')
61469606e3fSchristos 	{
61569606e3fSchristos 	  /* Look up home directory.  */
61669606e3fSchristos #ifdef VMS
61769606e3fSchristos /* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */
61869606e3fSchristos           const char *home_dir = getenv ("SYS$LOGIN");
61969606e3fSchristos #else
62069606e3fSchristos           const char *home_dir = getenv ("HOME");
62169606e3fSchristos #endif
62269606e3fSchristos # ifdef _AMIGA
62369606e3fSchristos 	  if (home_dir == NULL || home_dir[0] == '\0')
62469606e3fSchristos 	    home_dir = "SYS:";
62569606e3fSchristos # else
62669606e3fSchristos #  ifdef WINDOWS32
62769606e3fSchristos 	  if (home_dir == NULL || home_dir[0] == '\0')
62869606e3fSchristos             home_dir = "c:/users/default"; /* poor default */
62969606e3fSchristos #  else
63069606e3fSchristos #   ifdef VMS
63169606e3fSchristos /* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */
63269606e3fSchristos 	  if (home_dir == NULL || home_dir[0] == '\0')
63369606e3fSchristos 	    home_dir = "SYS$DISK:[]";
63469606e3fSchristos #   else
63569606e3fSchristos 	  if (home_dir == NULL || home_dir[0] == '\0')
63669606e3fSchristos 	    {
63769606e3fSchristos 	      int success;
63869606e3fSchristos 	      char *name;
63969606e3fSchristos #   if defined HAVE_GETLOGIN_R || defined _LIBC
64069606e3fSchristos 	      size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
64169606e3fSchristos 
64269606e3fSchristos 	      if (buflen == 0)
64369606e3fSchristos 		/* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
64469606e3fSchristos 		   a moderate value.  */
64569606e3fSchristos 		buflen = 20;
64669606e3fSchristos 	      name = (char *) __alloca (buflen);
64769606e3fSchristos 
64869606e3fSchristos 	      success = getlogin_r (name, buflen) >= 0;
64969606e3fSchristos #   else
65069606e3fSchristos 	      success = (name = getlogin ()) != NULL;
65169606e3fSchristos #   endif
65269606e3fSchristos 	      if (success)
65369606e3fSchristos 		{
65469606e3fSchristos 		  struct passwd *p;
65569606e3fSchristos #   if defined HAVE_GETPWNAM_R || defined _LIBC
65669606e3fSchristos 		  size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
65769606e3fSchristos 		  char *pwtmpbuf;
65869606e3fSchristos 		  struct passwd pwbuf;
65969606e3fSchristos 		  int save = errno;
66069606e3fSchristos 
66169606e3fSchristos 		  if (pwbuflen == -1)
66269606e3fSchristos 		    /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
66369606e3fSchristos 		       Try a moderate value.  */
66469606e3fSchristos 		    pwbuflen = 1024;
66569606e3fSchristos 		  pwtmpbuf = (char *) __alloca (pwbuflen);
66669606e3fSchristos 
66769606e3fSchristos 		  while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
66869606e3fSchristos 			 != 0)
66969606e3fSchristos 		    {
67069606e3fSchristos 		      if (errno != ERANGE)
67169606e3fSchristos 			{
67269606e3fSchristos 			  p = NULL;
67369606e3fSchristos 			  break;
67469606e3fSchristos 			}
67569606e3fSchristos 		      pwbuflen *= 2;
67669606e3fSchristos 		      pwtmpbuf = (char *) __alloca (pwbuflen);
67769606e3fSchristos 		      __set_errno (save);
67869606e3fSchristos 		    }
67969606e3fSchristos #   else
68069606e3fSchristos 		  p = getpwnam (name);
68169606e3fSchristos #   endif
68269606e3fSchristos 		  if (p != NULL)
68369606e3fSchristos 		    home_dir = p->pw_dir;
68469606e3fSchristos 		}
68569606e3fSchristos 	    }
68669606e3fSchristos 	  if (home_dir == NULL || home_dir[0] == '\0')
68769606e3fSchristos 	    {
68869606e3fSchristos 	      if (flags & GLOB_TILDE_CHECK)
68969606e3fSchristos 		return GLOB_NOMATCH;
69069606e3fSchristos 	      else
69169606e3fSchristos 		home_dir = "~"; /* No luck.  */
69269606e3fSchristos 	    }
69369606e3fSchristos #   endif /* VMS */
69469606e3fSchristos #  endif /* WINDOWS32 */
69569606e3fSchristos # endif
69669606e3fSchristos 	  /* Now construct the full directory.  */
69769606e3fSchristos 	  if (dirname[1] == '\0')
69869606e3fSchristos 	    dirname = home_dir;
69969606e3fSchristos 	  else
70069606e3fSchristos 	    {
70169606e3fSchristos 	      char *newp;
70269606e3fSchristos 	      size_t home_len = strlen (home_dir);
70369606e3fSchristos 	      newp = (char *) __alloca (home_len + dirlen);
70469606e3fSchristos # ifdef HAVE_MEMPCPY
70569606e3fSchristos 	      mempcpy (mempcpy (newp, home_dir, home_len),
70669606e3fSchristos 		       &dirname[1], dirlen);
70769606e3fSchristos # else
70869606e3fSchristos 	      memcpy (newp, home_dir, home_len);
70969606e3fSchristos 	      memcpy (&newp[home_len], &dirname[1], dirlen);
71069606e3fSchristos # endif
71169606e3fSchristos 	      dirname = newp;
71269606e3fSchristos 	    }
71369606e3fSchristos 	}
71469606e3fSchristos # if !defined _AMIGA && !defined WINDOWS32 && !defined VMS
71569606e3fSchristos       else
71669606e3fSchristos 	{
71769606e3fSchristos 	  char *end_name = strchr (dirname, '/');
71869606e3fSchristos 	  const char *user_name;
71969606e3fSchristos 	  const char *home_dir;
72069606e3fSchristos 
72169606e3fSchristos 	  if (end_name == NULL)
72269606e3fSchristos 	    user_name = dirname + 1;
72369606e3fSchristos 	  else
72469606e3fSchristos 	    {
72569606e3fSchristos 	      char *newp;
72669606e3fSchristos 	      newp = (char *) __alloca (end_name - dirname);
72769606e3fSchristos # ifdef HAVE_MEMPCPY
72869606e3fSchristos 	      *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
72969606e3fSchristos 		= '\0';
73069606e3fSchristos # else
73169606e3fSchristos 	      memcpy (newp, dirname + 1, end_name - dirname);
73269606e3fSchristos 	      newp[end_name - dirname - 1] = '\0';
73369606e3fSchristos # endif
73469606e3fSchristos 	      user_name = newp;
73569606e3fSchristos 	    }
73669606e3fSchristos 
73769606e3fSchristos 	  /* Look up specific user's home directory.  */
73869606e3fSchristos 	  {
73969606e3fSchristos 	    struct passwd *p;
74069606e3fSchristos #  if defined HAVE_GETPWNAM_R || defined _LIBC
74169606e3fSchristos 	    size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
74269606e3fSchristos 	    char *pwtmpbuf;
74369606e3fSchristos 	    struct passwd pwbuf;
74469606e3fSchristos 	    int save = errno;
74569606e3fSchristos 
74669606e3fSchristos 	    if (buflen == -1)
74769606e3fSchristos 	      /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.  Try a
74869606e3fSchristos 		 moderate value.  */
74969606e3fSchristos 	      buflen = 1024;
75069606e3fSchristos 	    pwtmpbuf = (char *) __alloca (buflen);
75169606e3fSchristos 
75269606e3fSchristos 	    while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
75369606e3fSchristos 	      {
75469606e3fSchristos 		if (errno != ERANGE)
75569606e3fSchristos 		  {
75669606e3fSchristos 		    p = NULL;
75769606e3fSchristos 		    break;
75869606e3fSchristos 		  }
75969606e3fSchristos 		buflen *= 2;
76069606e3fSchristos 		pwtmpbuf = __alloca (buflen);
76169606e3fSchristos 		__set_errno (save);
76269606e3fSchristos 	      }
76369606e3fSchristos #  else
76469606e3fSchristos 	    p = getpwnam (user_name);
76569606e3fSchristos #  endif
76669606e3fSchristos 	    if (p != NULL)
76769606e3fSchristos 	      home_dir = p->pw_dir;
76869606e3fSchristos 	    else
76969606e3fSchristos 	      home_dir = NULL;
77069606e3fSchristos 	  }
77169606e3fSchristos 	  /* If we found a home directory use this.  */
77269606e3fSchristos 	  if (home_dir != NULL)
77369606e3fSchristos 	    {
77469606e3fSchristos 	      char *newp;
77569606e3fSchristos 	      size_t home_len = strlen (home_dir);
77669606e3fSchristos 	      size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
77769606e3fSchristos 	      newp = (char *) __alloca (home_len + rest_len + 1);
77869606e3fSchristos #  ifdef HAVE_MEMPCPY
77969606e3fSchristos 	      *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
78069606e3fSchristos 				  end_name, rest_len)) = '\0';
78169606e3fSchristos #  else
78269606e3fSchristos 	      memcpy (newp, home_dir, home_len);
78369606e3fSchristos 	      memcpy (&newp[home_len], end_name, rest_len);
78469606e3fSchristos 	      newp[home_len + rest_len] = '\0';
78569606e3fSchristos #  endif
78669606e3fSchristos 	      dirname = newp;
78769606e3fSchristos 	    }
78869606e3fSchristos 	  else
78969606e3fSchristos 	    if (flags & GLOB_TILDE_CHECK)
79069606e3fSchristos 	      /* We have to regard it as an error if we cannot find the
79169606e3fSchristos 		 home directory.  */
79269606e3fSchristos 	      return GLOB_NOMATCH;
79369606e3fSchristos 	}
79469606e3fSchristos # endif	/* Not Amiga && not WINDOWS32 && not VMS.  */
79569606e3fSchristos     }
79669606e3fSchristos #endif	/* Not VMS.  */
79769606e3fSchristos 
79869606e3fSchristos   /* Now test whether we looked for "~" or "~NAME".  In this case we
79969606e3fSchristos      can give the answer now.  */
80069606e3fSchristos   if (filename == NULL)
80169606e3fSchristos     {
80269606e3fSchristos       struct stat st;
80369606e3fSchristos 
80469606e3fSchristos       /* Return the directory if we don't check for error or if it exists.  */
80569606e3fSchristos       if ((flags & GLOB_NOCHECK)
80669606e3fSchristos 	  || (((flags & GLOB_ALTDIRFUNC)
80769606e3fSchristos 	       ? (*pglob->gl_stat) (dirname, &st)
80869606e3fSchristos 	       : __stat (dirname, &st)) == 0
80969606e3fSchristos 	      && S_ISDIR (st.st_mode)))
81069606e3fSchristos 	{
81169606e3fSchristos 	  pglob->gl_pathv
81269606e3fSchristos 	    = (char **) realloc (pglob->gl_pathv,
81369606e3fSchristos 				 (pglob->gl_pathc +
81469606e3fSchristos 				  ((flags & GLOB_DOOFFS) ?
81569606e3fSchristos 				   pglob->gl_offs : 0) +
81669606e3fSchristos 				  1 + 1) *
81769606e3fSchristos 				 sizeof (char *));
81869606e3fSchristos 	  if (pglob->gl_pathv == NULL)
81969606e3fSchristos 	    return GLOB_NOSPACE;
82069606e3fSchristos 
82169606e3fSchristos 	  if (flags & GLOB_DOOFFS)
82269606e3fSchristos 	    while (pglob->gl_pathc < pglob->gl_offs)
82369606e3fSchristos 	      pglob->gl_pathv[pglob->gl_pathc++] = NULL;
82469606e3fSchristos 
82569606e3fSchristos #if defined HAVE_STRDUP || defined _LIBC
82669606e3fSchristos 	  pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
82769606e3fSchristos #else
82869606e3fSchristos 	  {
82969606e3fSchristos 	    size_t len = strlen (dirname) + 1;
83069606e3fSchristos 	    char *dircopy = malloc (len);
83169606e3fSchristos 	    if (dircopy != NULL)
83269606e3fSchristos 	      pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
83369606e3fSchristos 							 len);
83469606e3fSchristos 	  }
83569606e3fSchristos #endif
83669606e3fSchristos 	  if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
83769606e3fSchristos 	    {
83869606e3fSchristos 	      free (pglob->gl_pathv);
83969606e3fSchristos 	      return GLOB_NOSPACE;
84069606e3fSchristos 	    }
84169606e3fSchristos 	  pglob->gl_pathv[++pglob->gl_pathc] = NULL;
84269606e3fSchristos 	  pglob->gl_flags = flags;
84369606e3fSchristos 
84469606e3fSchristos 	  return 0;
84569606e3fSchristos 	}
84669606e3fSchristos 
84769606e3fSchristos       /* Not found.  */
84869606e3fSchristos       return GLOB_NOMATCH;
84969606e3fSchristos     }
85069606e3fSchristos 
85169606e3fSchristos   if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
85269606e3fSchristos     {
85369606e3fSchristos       /* The directory name contains metacharacters, so we
85469606e3fSchristos 	 have to glob for the directory, and then glob for
85569606e3fSchristos 	 the pattern in each directory found.  */
85669606e3fSchristos       glob_t dirs;
85769606e3fSchristos       register int i;
85869606e3fSchristos 
85969606e3fSchristos       status = glob (dirname,
86069606e3fSchristos 		     ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
86169606e3fSchristos 		      | GLOB_NOSORT | GLOB_ONLYDIR),
86269606e3fSchristos 		     errfunc, &dirs);
86369606e3fSchristos       if (status != 0)
86469606e3fSchristos 	return status;
86569606e3fSchristos 
86669606e3fSchristos       /* We have successfully globbed the preceding directory name.
86769606e3fSchristos 	 For each name we found, call glob_in_dir on it and FILENAME,
86869606e3fSchristos 	 appending the results to PGLOB.  */
86969606e3fSchristos       for (i = 0; i < dirs.gl_pathc; ++i)
87069606e3fSchristos 	{
87169606e3fSchristos 	  int old_pathc;
87269606e3fSchristos 
87369606e3fSchristos #ifdef	SHELL
87469606e3fSchristos 	  {
87569606e3fSchristos 	    /* Make globbing interruptible in the bash shell. */
87669606e3fSchristos 	    extern int interrupt_state;
87769606e3fSchristos 
87869606e3fSchristos 	    if (interrupt_state)
87969606e3fSchristos 	      {
88069606e3fSchristos 		globfree (&dirs);
88169606e3fSchristos 		globfree (&files);
88269606e3fSchristos 		return GLOB_ABORTED;
88369606e3fSchristos 	      }
88469606e3fSchristos 	  }
88569606e3fSchristos #endif /* SHELL.  */
88669606e3fSchristos 
88769606e3fSchristos 	  old_pathc = pglob->gl_pathc;
88869606e3fSchristos 	  status = glob_in_dir (filename, dirs.gl_pathv[i],
88969606e3fSchristos 				((flags | GLOB_APPEND)
89069606e3fSchristos 				 & ~(GLOB_NOCHECK | GLOB_ERR)),
89169606e3fSchristos 				errfunc, pglob);
89269606e3fSchristos 	  if (status == GLOB_NOMATCH)
89369606e3fSchristos 	    /* No matches in this directory.  Try the next.  */
89469606e3fSchristos 	    continue;
89569606e3fSchristos 
89669606e3fSchristos 	  if (status != 0)
89769606e3fSchristos 	    {
89869606e3fSchristos 	      globfree (&dirs);
89969606e3fSchristos 	      globfree (pglob);
90069606e3fSchristos 	      return status;
90169606e3fSchristos 	    }
90269606e3fSchristos 
90369606e3fSchristos 	  /* Stick the directory on the front of each name.  */
90469606e3fSchristos 	  if (prefix_array (dirs.gl_pathv[i],
90569606e3fSchristos 			    &pglob->gl_pathv[old_pathc],
90669606e3fSchristos 			    pglob->gl_pathc - old_pathc))
90769606e3fSchristos 	    {
90869606e3fSchristos 	      globfree (&dirs);
90969606e3fSchristos 	      globfree (pglob);
91069606e3fSchristos 	      return GLOB_NOSPACE;
91169606e3fSchristos 	    }
91269606e3fSchristos 	}
91369606e3fSchristos 
91469606e3fSchristos       flags |= GLOB_MAGCHAR;
91569606e3fSchristos 
91669606e3fSchristos       /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
91769606e3fSchristos 	 But if we have not found any matching entry and thie GLOB_NOCHECK
91869606e3fSchristos 	 flag was set we must return the list consisting of the disrectory
91969606e3fSchristos 	 names followed by the filename.  */
92069606e3fSchristos       if (pglob->gl_pathc == oldcount)
92169606e3fSchristos 	{
92269606e3fSchristos 	  /* No matches.  */
92369606e3fSchristos 	  if (flags & GLOB_NOCHECK)
92469606e3fSchristos 	    {
92569606e3fSchristos 	      size_t filename_len = strlen (filename) + 1;
92669606e3fSchristos 	      char **new_pathv;
92769606e3fSchristos 	      struct stat st;
92869606e3fSchristos 
92969606e3fSchristos 	      /* This is an pessimistic guess about the size.  */
93069606e3fSchristos 	      pglob->gl_pathv
93169606e3fSchristos 		= (char **) realloc (pglob->gl_pathv,
93269606e3fSchristos 				     (pglob->gl_pathc +
93369606e3fSchristos 				      ((flags & GLOB_DOOFFS) ?
93469606e3fSchristos 				       pglob->gl_offs : 0) +
93569606e3fSchristos 				      dirs.gl_pathc + 1) *
93669606e3fSchristos 				     sizeof (char *));
93769606e3fSchristos 	      if (pglob->gl_pathv == NULL)
93869606e3fSchristos 		{
93969606e3fSchristos 		  globfree (&dirs);
94069606e3fSchristos 		  return GLOB_NOSPACE;
94169606e3fSchristos 		}
94269606e3fSchristos 
94369606e3fSchristos 	      if (flags & GLOB_DOOFFS)
94469606e3fSchristos 		while (pglob->gl_pathc < pglob->gl_offs)
94569606e3fSchristos 		  pglob->gl_pathv[pglob->gl_pathc++] = NULL;
94669606e3fSchristos 
94769606e3fSchristos 	      for (i = 0; i < dirs.gl_pathc; ++i)
94869606e3fSchristos 		{
94969606e3fSchristos 		  const char *dir = dirs.gl_pathv[i];
95069606e3fSchristos 		  size_t dir_len = strlen (dir);
95169606e3fSchristos 
95269606e3fSchristos 		  /* First check whether this really is a directory.  */
95369606e3fSchristos 		  if (((flags & GLOB_ALTDIRFUNC)
95469606e3fSchristos 		       ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
95569606e3fSchristos 		      || !S_ISDIR (st.st_mode))
95669606e3fSchristos 		    /* No directory, ignore this entry.  */
95769606e3fSchristos 		    continue;
95869606e3fSchristos 
95969606e3fSchristos 		  pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
96069606e3fSchristos 							     + filename_len);
96169606e3fSchristos 		  if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
96269606e3fSchristos 		    {
96369606e3fSchristos 		      globfree (&dirs);
96469606e3fSchristos 		      globfree (pglob);
96569606e3fSchristos 		      return GLOB_NOSPACE;
96669606e3fSchristos 		    }
96769606e3fSchristos 
96869606e3fSchristos #ifdef HAVE_MEMPCPY
96969606e3fSchristos 		  mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
97069606e3fSchristos 					     dir, dir_len),
97169606e3fSchristos 				    "/", 1),
97269606e3fSchristos 			   filename, filename_len);
97369606e3fSchristos #else
97469606e3fSchristos 		  memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
97569606e3fSchristos 		  pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
97669606e3fSchristos 		  memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
97769606e3fSchristos 			  filename, filename_len);
97869606e3fSchristos #endif
97969606e3fSchristos 		  ++pglob->gl_pathc;
98069606e3fSchristos 		}
98169606e3fSchristos 
98269606e3fSchristos 	      pglob->gl_pathv[pglob->gl_pathc] = NULL;
98369606e3fSchristos 	      pglob->gl_flags = flags;
98469606e3fSchristos 
98569606e3fSchristos 	      /* Now we know how large the gl_pathv vector must be.  */
98669606e3fSchristos 	      new_pathv = (char **) realloc (pglob->gl_pathv,
98769606e3fSchristos 					     ((pglob->gl_pathc + 1)
98869606e3fSchristos 					      * sizeof (char *)));
98969606e3fSchristos 	      if (new_pathv != NULL)
99069606e3fSchristos 		pglob->gl_pathv = new_pathv;
99169606e3fSchristos 	    }
99269606e3fSchristos 	  else
99369606e3fSchristos 	    return GLOB_NOMATCH;
99469606e3fSchristos 	}
99569606e3fSchristos 
99669606e3fSchristos       globfree (&dirs);
99769606e3fSchristos     }
99869606e3fSchristos   else
99969606e3fSchristos     {
100069606e3fSchristos       status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
100169606e3fSchristos       if (status != 0)
100269606e3fSchristos 	return status;
100369606e3fSchristos 
100469606e3fSchristos       if (dirlen > 0)
100569606e3fSchristos 	{
100669606e3fSchristos 	  /* Stick the directory on the front of each name.  */
100769606e3fSchristos 	  int ignore = oldcount;
100869606e3fSchristos 
100969606e3fSchristos 	  if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs)
101069606e3fSchristos 	    ignore = pglob->gl_offs;
101169606e3fSchristos 
101269606e3fSchristos 	  if (prefix_array (dirname,
101369606e3fSchristos 			    &pglob->gl_pathv[ignore],
101469606e3fSchristos 			    pglob->gl_pathc - ignore))
101569606e3fSchristos 	    {
101669606e3fSchristos 	      globfree (pglob);
101769606e3fSchristos 	      return GLOB_NOSPACE;
101869606e3fSchristos 	    }
101969606e3fSchristos 	}
102069606e3fSchristos     }
102169606e3fSchristos 
102269606e3fSchristos   if (flags & GLOB_MARK)
102369606e3fSchristos     {
102469606e3fSchristos       /* Append slashes to directory names.  */
102569606e3fSchristos       int i;
102669606e3fSchristos       struct stat st;
102769606e3fSchristos       for (i = oldcount; i < pglob->gl_pathc; ++i)
102869606e3fSchristos 	if (((flags & GLOB_ALTDIRFUNC)
102969606e3fSchristos 	     ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
103069606e3fSchristos 	     : __stat (pglob->gl_pathv[i], &st)) == 0
103169606e3fSchristos 	    && S_ISDIR (st.st_mode))
103269606e3fSchristos 	  {
103369606e3fSchristos  	    size_t len = strlen (pglob->gl_pathv[i]) + 2;
103469606e3fSchristos 	    char *new = realloc (pglob->gl_pathv[i], len);
103569606e3fSchristos  	    if (new == NULL)
103669606e3fSchristos 	      {
103769606e3fSchristos 		globfree (pglob);
103869606e3fSchristos 		return GLOB_NOSPACE;
103969606e3fSchristos 	      }
104069606e3fSchristos 	    strcpy (&new[len - 2], "/");
104169606e3fSchristos 	    pglob->gl_pathv[i] = new;
104269606e3fSchristos 	  }
104369606e3fSchristos     }
104469606e3fSchristos 
104569606e3fSchristos   if (!(flags & GLOB_NOSORT))
104669606e3fSchristos     {
104769606e3fSchristos       /* Sort the vector.  */
104869606e3fSchristos       int non_sort = oldcount;
104969606e3fSchristos 
105069606e3fSchristos       if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount)
105169606e3fSchristos 	non_sort = pglob->gl_offs;
105269606e3fSchristos 
105369606e3fSchristos       qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
105469606e3fSchristos 	     pglob->gl_pathc - non_sort,
105569606e3fSchristos 	     sizeof (char *), collated_compare);
105669606e3fSchristos     }
105769606e3fSchristos 
105869606e3fSchristos   return 0;
105969606e3fSchristos }
106069606e3fSchristos 
106169606e3fSchristos 
106269606e3fSchristos /* Free storage allocated in PGLOB by a previous `glob' call.  */
106369606e3fSchristos void
globfree(pglob)106469606e3fSchristos globfree (pglob)
106569606e3fSchristos      register glob_t *pglob;
106669606e3fSchristos {
106769606e3fSchristos   if (pglob->gl_pathv != NULL)
106869606e3fSchristos     {
106969606e3fSchristos       register int i;
107069606e3fSchristos       for (i = 0; i < pglob->gl_pathc; ++i)
107169606e3fSchristos 	if (pglob->gl_pathv[i] != NULL)
107269606e3fSchristos 	  free ((__ptr_t) pglob->gl_pathv[i]);
107369606e3fSchristos       free ((__ptr_t) pglob->gl_pathv);
107469606e3fSchristos     }
107569606e3fSchristos }
107669606e3fSchristos 
107769606e3fSchristos 
107869606e3fSchristos /* Do a collated comparison of A and B.  */
107969606e3fSchristos static int
collated_compare(a,b)108069606e3fSchristos collated_compare (a, b)
108169606e3fSchristos      const __ptr_t a;
108269606e3fSchristos      const __ptr_t b;
108369606e3fSchristos {
108469606e3fSchristos   const char *const s1 = *(const char *const * const) a;
108569606e3fSchristos   const char *const s2 = *(const char *const * const) b;
108669606e3fSchristos 
108769606e3fSchristos   if (s1 == s2)
108869606e3fSchristos     return 0;
108969606e3fSchristos   if (s1 == NULL)
109069606e3fSchristos     return 1;
109169606e3fSchristos   if (s2 == NULL)
109269606e3fSchristos     return -1;
109369606e3fSchristos   return strcoll (s1, s2);
109469606e3fSchristos }
109569606e3fSchristos 
109669606e3fSchristos 
109769606e3fSchristos /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
109869606e3fSchristos    elements in place.  Return nonzero if out of memory, zero if successful.
109969606e3fSchristos    A slash is inserted between DIRNAME and each elt of ARRAY,
110069606e3fSchristos    unless DIRNAME is just "/".  Each old element of ARRAY is freed.  */
110169606e3fSchristos static int
prefix_array(dirname,array,n)110269606e3fSchristos prefix_array (dirname, array, n)
110369606e3fSchristos      const char *dirname;
110469606e3fSchristos      char **array;
110569606e3fSchristos      size_t n;
110669606e3fSchristos {
110769606e3fSchristos   register size_t i;
110869606e3fSchristos   size_t dirlen = strlen (dirname);
110969606e3fSchristos #if defined __MSDOS__ || defined WINDOWS32
111069606e3fSchristos   int sep_char = '/';
111169606e3fSchristos # define DIRSEP_CHAR sep_char
111269606e3fSchristos #else
111369606e3fSchristos # define DIRSEP_CHAR '/'
111469606e3fSchristos #endif
111569606e3fSchristos 
111669606e3fSchristos   if (dirlen == 1 && dirname[0] == '/')
111769606e3fSchristos     /* DIRNAME is just "/", so normal prepending would get us "//foo".
111869606e3fSchristos        We want "/foo" instead, so don't prepend any chars from DIRNAME.  */
111969606e3fSchristos     dirlen = 0;
112069606e3fSchristos #if defined __MSDOS__ || defined WINDOWS32
112169606e3fSchristos   else if (dirlen > 1)
112269606e3fSchristos     {
112369606e3fSchristos       if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
112469606e3fSchristos 	/* DIRNAME is "d:/".  Don't prepend the slash from DIRNAME.  */
112569606e3fSchristos 	--dirlen;
112669606e3fSchristos       else if (dirname[dirlen - 1] == ':')
112769606e3fSchristos 	{
112869606e3fSchristos 	  /* DIRNAME is "d:".  Use `:' instead of `/'.  */
112969606e3fSchristos 	  --dirlen;
113069606e3fSchristos 	  sep_char = ':';
113169606e3fSchristos 	}
113269606e3fSchristos     }
113369606e3fSchristos #endif
113469606e3fSchristos 
113569606e3fSchristos   for (i = 0; i < n; ++i)
113669606e3fSchristos     {
113769606e3fSchristos       size_t eltlen = strlen (array[i]) + 1;
113869606e3fSchristos       char *new = (char *) malloc (dirlen + 1 + eltlen);
113969606e3fSchristos       if (new == NULL)
114069606e3fSchristos 	{
114169606e3fSchristos 	  while (i > 0)
114269606e3fSchristos 	    free ((__ptr_t) array[--i]);
114369606e3fSchristos 	  return 1;
114469606e3fSchristos 	}
114569606e3fSchristos 
114669606e3fSchristos #ifdef HAVE_MEMPCPY
114769606e3fSchristos       {
114869606e3fSchristos 	char *endp = (char *) mempcpy (new, dirname, dirlen);
114969606e3fSchristos 	*endp++ = DIRSEP_CHAR;
115069606e3fSchristos 	mempcpy (endp, array[i], eltlen);
115169606e3fSchristos       }
115269606e3fSchristos #else
115369606e3fSchristos       memcpy (new, dirname, dirlen);
115469606e3fSchristos       new[dirlen] = DIRSEP_CHAR;
115569606e3fSchristos       memcpy (&new[dirlen + 1], array[i], eltlen);
115669606e3fSchristos #endif
115769606e3fSchristos       free ((__ptr_t) array[i]);
115869606e3fSchristos       array[i] = new;
115969606e3fSchristos     }
116069606e3fSchristos 
116169606e3fSchristos   return 0;
116269606e3fSchristos }
116369606e3fSchristos 
116469606e3fSchristos 
116569606e3fSchristos /* We must not compile this function twice.  */
116669606e3fSchristos #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
116769606e3fSchristos /* Return nonzero if PATTERN contains any metacharacters.
116869606e3fSchristos    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
116969606e3fSchristos int
__glob_pattern_p(pattern,quote)117069606e3fSchristos __glob_pattern_p (pattern, quote)
117169606e3fSchristos      const char *pattern;
117269606e3fSchristos      int quote;
117369606e3fSchristos {
117469606e3fSchristos   register const char *p;
117569606e3fSchristos   int open = 0;
117669606e3fSchristos 
117769606e3fSchristos   for (p = pattern; *p != '\0'; ++p)
117869606e3fSchristos     switch (*p)
117969606e3fSchristos       {
118069606e3fSchristos       case '?':
118169606e3fSchristos       case '*':
118269606e3fSchristos 	return 1;
118369606e3fSchristos 
118469606e3fSchristos       case '\\':
118569606e3fSchristos 	if (quote && p[1] != '\0')
118669606e3fSchristos 	  ++p;
118769606e3fSchristos 	break;
118869606e3fSchristos 
118969606e3fSchristos       case '[':
119069606e3fSchristos 	open = 1;
119169606e3fSchristos 	break;
119269606e3fSchristos 
119369606e3fSchristos       case ']':
119469606e3fSchristos 	if (open)
119569606e3fSchristos 	  return 1;
119669606e3fSchristos 	break;
119769606e3fSchristos       }
119869606e3fSchristos 
119969606e3fSchristos   return 0;
120069606e3fSchristos }
120169606e3fSchristos # ifdef _LIBC
120269606e3fSchristos weak_alias (__glob_pattern_p, glob_pattern_p)
120369606e3fSchristos # endif
120469606e3fSchristos #endif
120569606e3fSchristos 
120669606e3fSchristos 
120769606e3fSchristos /* Like `glob', but PATTERN is a final pathname component,
120869606e3fSchristos    and matches are searched for in DIRECTORY.
120969606e3fSchristos    The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
121069606e3fSchristos    The GLOB_APPEND flag is assumed to be set (always appends).  */
121169606e3fSchristos static int
121269606e3fSchristos glob_in_dir (pattern, directory, flags, errfunc, pglob)
121369606e3fSchristos      const char *pattern;
121469606e3fSchristos      const char *directory;
121569606e3fSchristos      int flags;
121669606e3fSchristos      int (*errfunc) __P ((const char *, int));
121769606e3fSchristos      glob_t *pglob;
121869606e3fSchristos {
121969606e3fSchristos   __ptr_t stream = NULL;
122069606e3fSchristos 
122169606e3fSchristos   struct globlink
122269606e3fSchristos     {
122369606e3fSchristos       struct globlink *next;
122469606e3fSchristos       char *name;
122569606e3fSchristos     };
122669606e3fSchristos   struct globlink *names = NULL;
122769606e3fSchristos   size_t nfound;
122869606e3fSchristos   int meta;
122969606e3fSchristos   int save;
123069606e3fSchristos 
123169606e3fSchristos #ifdef VMS
123269606e3fSchristos   if (*directory == 0)
123369606e3fSchristos     directory = "[]";
123469606e3fSchristos #endif
123569606e3fSchristos   meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
123669606e3fSchristos   if (meta == 0)
123769606e3fSchristos     {
123869606e3fSchristos       if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
123969606e3fSchristos 	/* We need not do any tests.  The PATTERN contains no meta
124069606e3fSchristos 	   characters and we must not return an error therefore the
124169606e3fSchristos 	   result will always contain exactly one name.  */
124269606e3fSchristos 	flags |= GLOB_NOCHECK;
124369606e3fSchristos       else
124469606e3fSchristos 	{
124569606e3fSchristos 	  /* Since we use the normal file functions we can also use stat()
124669606e3fSchristos 	     to verify the file is there.  */
124769606e3fSchristos 	  struct stat st;
124869606e3fSchristos 	  size_t patlen = strlen (pattern);
124969606e3fSchristos 	  size_t dirlen = strlen (directory);
125069606e3fSchristos 	  char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
125169606e3fSchristos 
125269606e3fSchristos # ifdef HAVE_MEMPCPY
125369606e3fSchristos 	  mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
125469606e3fSchristos 			    "/", 1),
125569606e3fSchristos 		   pattern, patlen + 1);
125669606e3fSchristos # else
125769606e3fSchristos 	  memcpy (fullname, directory, dirlen);
125869606e3fSchristos 	  fullname[dirlen] = '/';
125969606e3fSchristos 	  memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
126069606e3fSchristos # endif
126169606e3fSchristos 	  if (((flags & GLOB_ALTDIRFUNC)
126269606e3fSchristos 	       ? (*pglob->gl_stat) (fullname, &st)
126369606e3fSchristos 	       : __stat (fullname, &st)) == 0)
126469606e3fSchristos 	    /* We found this file to be existing.  Now tell the rest
126569606e3fSchristos 	       of the function to copy this name into the result.  */
126669606e3fSchristos 	    flags |= GLOB_NOCHECK;
126769606e3fSchristos 	}
126869606e3fSchristos 
126969606e3fSchristos       nfound = 0;
127069606e3fSchristos     }
127169606e3fSchristos   else
127269606e3fSchristos     {
127369606e3fSchristos       if (pattern[0] == '\0')
127469606e3fSchristos 	{
127569606e3fSchristos 	  /* This is a special case for matching directories like in
127669606e3fSchristos 	     "*a/".  */
127769606e3fSchristos 	  names = (struct globlink *) __alloca (sizeof (struct globlink));
127869606e3fSchristos 	  names->name = (char *) malloc (1);
127969606e3fSchristos 	  if (names->name == NULL)
128069606e3fSchristos 	    goto memory_error;
128169606e3fSchristos 	  names->name[0] = '\0';
128269606e3fSchristos 	  names->next = NULL;
128369606e3fSchristos 	  nfound = 1;
128469606e3fSchristos 	  meta = 0;
128569606e3fSchristos 	}
128669606e3fSchristos       else
128769606e3fSchristos 	{
128869606e3fSchristos 	  stream = ((flags & GLOB_ALTDIRFUNC)
128969606e3fSchristos 		    ? (*pglob->gl_opendir) (directory)
129069606e3fSchristos 		    : (__ptr_t) opendir (directory));
129169606e3fSchristos 	  if (stream == NULL)
129269606e3fSchristos 	    {
129369606e3fSchristos 	      if (errno != ENOTDIR
129469606e3fSchristos 		  && ((errfunc != NULL && (*errfunc) (directory, errno))
129569606e3fSchristos 		      || (flags & GLOB_ERR)))
129669606e3fSchristos 		return GLOB_ABORTED;
129769606e3fSchristos 	      nfound = 0;
129869606e3fSchristos 	      meta = 0;
129969606e3fSchristos 	    }
130069606e3fSchristos 	  else
130169606e3fSchristos 	    {
130269606e3fSchristos 	      int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
130369606e3fSchristos 			       | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
130469606e3fSchristos #if defined HAVE_CASE_INSENSITIVE_FS
130569606e3fSchristos 				   | FNM_CASEFOLD
130669606e3fSchristos #endif
130769606e3fSchristos 				   );
130869606e3fSchristos 	      nfound = 0;
130969606e3fSchristos 	      flags |= GLOB_MAGCHAR;
131069606e3fSchristos 
131169606e3fSchristos 	      while (1)
131269606e3fSchristos 		{
131369606e3fSchristos 		  const char *name;
131469606e3fSchristos 		  size_t len;
131569606e3fSchristos 		  struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
131669606e3fSchristos 				      ? (*pglob->gl_readdir) (stream)
131769606e3fSchristos 				      : readdir ((DIR *) stream));
131869606e3fSchristos 		  if (d == NULL)
131969606e3fSchristos 		    break;
132069606e3fSchristos 		  if (! REAL_DIR_ENTRY (d))
132169606e3fSchristos 		    continue;
132269606e3fSchristos 
132369606e3fSchristos #ifdef HAVE_D_TYPE
132469606e3fSchristos 		  /* If we shall match only directories use the information
132569606e3fSchristos 		     provided by the dirent call if possible.  */
132669606e3fSchristos 		  if ((flags & GLOB_ONLYDIR)
132769606e3fSchristos 		      && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
132869606e3fSchristos 		    continue;
132969606e3fSchristos #endif
133069606e3fSchristos 
133169606e3fSchristos 		  name = d->d_name;
133269606e3fSchristos 
133369606e3fSchristos 		  if (fnmatch (pattern, name, fnm_flags) == 0)
133469606e3fSchristos 		    {
133569606e3fSchristos 		      struct globlink *new = (struct globlink *)
133669606e3fSchristos 			__alloca (sizeof (struct globlink));
133769606e3fSchristos 		      len = NAMLEN (d);
133869606e3fSchristos 		      new->name = (char *) malloc (len + 1);
133969606e3fSchristos 		      if (new->name == NULL)
134069606e3fSchristos 			goto memory_error;
134169606e3fSchristos #ifdef HAVE_MEMPCPY
134269606e3fSchristos 		      *((char *) mempcpy ((__ptr_t) new->name, name, len))
134369606e3fSchristos 			= '\0';
134469606e3fSchristos #else
134569606e3fSchristos 		      memcpy ((__ptr_t) new->name, name, len);
134669606e3fSchristos 		      new->name[len] = '\0';
134769606e3fSchristos #endif
134869606e3fSchristos 		      new->next = names;
134969606e3fSchristos 		      names = new;
135069606e3fSchristos 		      ++nfound;
135169606e3fSchristos 		    }
135269606e3fSchristos 		}
135369606e3fSchristos 	    }
135469606e3fSchristos 	}
135569606e3fSchristos     }
135669606e3fSchristos 
135769606e3fSchristos   if (nfound == 0 && (flags & GLOB_NOCHECK))
135869606e3fSchristos     {
135969606e3fSchristos       size_t len = strlen (pattern);
136069606e3fSchristos       nfound = 1;
136169606e3fSchristos       names = (struct globlink *) __alloca (sizeof (struct globlink));
136269606e3fSchristos       names->next = NULL;
136369606e3fSchristos       names->name = (char *) malloc (len + 1);
136469606e3fSchristos       if (names->name == NULL)
136569606e3fSchristos 	goto memory_error;
136669606e3fSchristos #ifdef HAVE_MEMPCPY
136769606e3fSchristos       *((char *) mempcpy (names->name, pattern, len)) = '\0';
136869606e3fSchristos #else
136969606e3fSchristos       memcpy (names->name, pattern, len);
137069606e3fSchristos       names->name[len] = '\0';
137169606e3fSchristos #endif
137269606e3fSchristos     }
137369606e3fSchristos 
137469606e3fSchristos   if (nfound != 0)
137569606e3fSchristos     {
137669606e3fSchristos       pglob->gl_pathv
137769606e3fSchristos 	= (char **) realloc (pglob->gl_pathv,
137869606e3fSchristos 			     (pglob->gl_pathc +
137969606e3fSchristos 			      ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
138069606e3fSchristos 			      nfound + 1) *
138169606e3fSchristos 			     sizeof (char *));
138269606e3fSchristos       if (pglob->gl_pathv == NULL)
138369606e3fSchristos 	goto memory_error;
138469606e3fSchristos 
138569606e3fSchristos       if (flags & GLOB_DOOFFS)
138669606e3fSchristos 	while (pglob->gl_pathc < pglob->gl_offs)
138769606e3fSchristos 	  pglob->gl_pathv[pglob->gl_pathc++] = NULL;
138869606e3fSchristos 
138969606e3fSchristos       for (; names != NULL; names = names->next)
139069606e3fSchristos 	pglob->gl_pathv[pglob->gl_pathc++] = names->name;
139169606e3fSchristos       pglob->gl_pathv[pglob->gl_pathc] = NULL;
139269606e3fSchristos 
139369606e3fSchristos       pglob->gl_flags = flags;
139469606e3fSchristos     }
139569606e3fSchristos 
139669606e3fSchristos   save = errno;
139769606e3fSchristos   if (stream != NULL)
139869606e3fSchristos     {
139969606e3fSchristos       if (flags & GLOB_ALTDIRFUNC)
140069606e3fSchristos 	(*pglob->gl_closedir) (stream);
140169606e3fSchristos       else
140269606e3fSchristos 	closedir ((DIR *) stream);
140369606e3fSchristos     }
140469606e3fSchristos   __set_errno (save);
140569606e3fSchristos 
140669606e3fSchristos   return nfound == 0 ? GLOB_NOMATCH : 0;
140769606e3fSchristos 
140869606e3fSchristos  memory_error:
140969606e3fSchristos   {
141069606e3fSchristos     int save = errno;
141169606e3fSchristos     if (flags & GLOB_ALTDIRFUNC)
141269606e3fSchristos       (*pglob->gl_closedir) (stream);
141369606e3fSchristos     else
141469606e3fSchristos       closedir ((DIR *) stream);
141569606e3fSchristos     __set_errno (save);
141669606e3fSchristos   }
141769606e3fSchristos   while (names != NULL)
141869606e3fSchristos     {
141969606e3fSchristos       if (names->name != NULL)
142069606e3fSchristos 	free ((__ptr_t) names->name);
142169606e3fSchristos       names = names->next;
142269606e3fSchristos     }
142369606e3fSchristos   return GLOB_NOSPACE;
142469606e3fSchristos }
142569606e3fSchristos 
142669606e3fSchristos #endif	/* Not ELIDE_CODE.  */
1427