Fri Mar 1 10:09:46 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
[platform/upstream/glibc.git] / posix / glob.c
1 /* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
2
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Library General Public License as
5 published by the Free Software Foundation; either version 2 of the
6 License, or (at your option) any later version.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public
14 License along with this library; see the file COPYING.LIB.  If
15 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
16 Cambridge, MA 02139, USA.  */
17
18 /* AIX requires this to be the first thing in the file.  */
19 #if defined (_AIX) && !defined (__GNUC__)
20  #pragma alloca
21 #endif
22
23 #ifdef  HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 /* Enable GNU extensions in glob.h.  */
28 #ifndef _GNU_SOURCE
29 #define _GNU_SOURCE     1
30 #endif
31
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35
36
37 /* Comment out all this code if we are using the GNU C Library, and are not
38    actually compiling the library itself.  This code is part of the GNU C
39    Library, but also included in many other GNU distributions.  Compiling
40    and linking in this code is a waste when using the GNU C library
41    (especially if it is a shared library).  Rather than having every GNU
42    program understand `configure --with-gnu-libc' and omit the object files,
43    it is simpler to just do this in the source for each such file.  */
44
45 #define GLOB_INTERFACE_VERSION 1
46 #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
47 #include <gnu-versions.h>
48 #if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
49 #define ELIDE_CODE
50 #endif
51 #endif
52
53 #ifndef ELIDE_CODE
54
55 #ifdef  STDC_HEADERS
56 #include <stddef.h>
57 #endif
58
59 #ifdef  HAVE_UNISTD_H
60 #include <unistd.h>
61 #ifndef POSIX
62 #ifdef  _POSIX_VERSION
63 #define POSIX
64 #endif
65 #endif
66 #endif
67
68 #include <pwd.h>
69
70 #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
71 extern int errno;
72 #endif
73
74 #ifndef NULL
75 #define NULL    0
76 #endif
77
78
79 #if defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__)
80 # include <dirent.h>
81 # define NAMLEN(dirent) strlen((dirent)->d_name)
82 #else
83 # define dirent direct
84 # define NAMLEN(dirent) (dirent)->d_namlen
85 # ifdef HAVE_SYS_NDIR_H
86 #  include <sys/ndir.h>
87 # endif
88 # ifdef HAVE_SYS_DIR_H
89 #  include <sys/dir.h>
90 # endif
91 # ifdef HAVE_NDIR_H
92 #  include <ndir.h>
93 # endif
94 #endif
95
96
97 /* In GNU systems, <dirent.h> defines this macro for us.  */
98 #ifdef _D_NAMLEN
99 #undef NAMLEN
100 #define NAMLEN(d) _D_NAMLEN(d)
101 #endif
102
103
104 #if defined (POSIX) && !defined (__GNU_LIBRARY__)
105 /* Posix does not require that the d_ino field be present, and some
106    systems do not provide it. */
107 #define REAL_DIR_ENTRY(dp) 1
108 #else
109 #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
110 #endif /* POSIX */
111
112 #if     (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
113 #include <stdlib.h>
114 #include <string.h>
115 #define ANSI_STRING
116 #else   /* No standard headers.  */
117
118 extern char *getenv ();
119
120 #ifdef HAVE_STRING_H
121 #include <string.h>
122 #define ANSI_STRING
123 #else
124 #include <strings.h>
125 #endif
126 #ifdef  HAVE_MEMORY_H
127 #include <memory.h>
128 #endif
129
130 extern char *malloc (), *realloc ();
131 extern void free ();
132
133 extern void qsort ();
134 extern void abort (), exit ();
135
136 #endif  /* Standard headers.  */
137
138 #ifndef ANSI_STRING
139
140 #ifndef bzero
141 extern void bzero ();
142 #endif
143 #ifndef bcopy
144 extern void bcopy ();
145 #endif
146
147 #define memcpy(d, s, n) bcopy ((s), (d), (n))
148 #define strrchr rindex
149 /* memset is only used for zero here, but let's be paranoid.  */
150 #define memset(s, better_be_zero, n) \
151   ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
152 #endif  /* Not ANSI_STRING.  */
153
154 #ifndef HAVE_STRCOLL
155 #define strcoll strcmp
156 #endif
157
158
159 #ifndef __GNU_LIBRARY__
160 #ifdef  __GNUC__
161 __inline
162 #endif
163 static char *
164 my_realloc (p, n)
165      char *p;
166      unsigned int n;
167 {
168   /* These casts are the for sake of the broken Ultrix compiler,
169      which warns of illegal pointer combinations otherwise.  */
170   if (p == NULL)
171     return (char *) malloc (n);
172   return (char *) realloc (p, n);
173 }
174 #define realloc my_realloc
175 #endif
176
177
178 #if     !defined(__alloca) && !defined(__GNU_LIBRARY__)
179
180 #ifdef  __GNUC__
181 #undef  alloca
182 #define alloca(n)       __builtin_alloca (n)
183 #else   /* Not GCC.  */
184 #if     defined (sparc) || defined (HAVE_ALLOCA_H)
185 #include <alloca.h>
186 #else   /* Not sparc or HAVE_ALLOCA_H.  */
187 #ifndef _AIX
188 extern char *alloca ();
189 #endif  /* Not _AIX.  */
190 #endif  /* sparc or HAVE_ALLOCA_H.  */
191 #endif  /* GCC.  */
192
193 #define __alloca        alloca
194
195 #endif
196
197 #ifndef __GNU_LIBRARY__
198 #define __stat stat
199 #ifdef STAT_MACROS_BROKEN
200 #undef S_ISDIR
201 #endif
202 #ifndef S_ISDIR
203 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
204 #endif
205 #endif
206
207 #ifndef STDC_HEADERS
208 #undef  size_t
209 #define size_t  unsigned int
210 #endif
211
212 /* Some system header files erroneously define these.
213    We want our own definitions from <fnmatch.h> to take precedence.  */
214 #undef  FNM_PATHNAME
215 #undef  FNM_NOESCAPE
216 #undef  FNM_PERIOD
217 #include <fnmatch.h>
218
219 /* Some system header files erroneously define these.
220    We want our own definitions from <glob.h> to take precedence.  */
221 #undef  GLOB_ERR
222 #undef  GLOB_MARK
223 #undef  GLOB_NOSORT
224 #undef  GLOB_DOOFFS
225 #undef  GLOB_NOCHECK
226 #undef  GLOB_APPEND
227 #undef  GLOB_NOESCAPE
228 #undef  GLOB_PERIOD
229 #include <glob.h>
230 \f
231 static int glob_pattern_p __P ((const char *pattern, int quote));
232 static int glob_in_dir __P ((const char *pattern, const char *directory,
233                              int flags,
234                              int (*errfunc) __P ((const char *, int)),
235                              glob_t *pglob));
236 static int prefix_array __P ((const char *prefix, char **array, size_t n));
237 static int collated_compare __P ((const __ptr_t, const __ptr_t));
238
239 /* Do glob searching for PATTERN, placing results in PGLOB.
240    The bits defined above may be set in FLAGS.
241    If a directory cannot be opened or read and ERRFUNC is not nil,
242    it is called with the pathname that caused the error, and the
243    `errno' value from the failing call; if it returns non-zero
244    `glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
245    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
246    Otherwise, `glob' returns zero.  */
247 int
248 glob (pattern, flags, errfunc, pglob)
249      const char *pattern;
250      int flags;
251      int (*errfunc) __P ((const char *, int));
252      glob_t *pglob;
253 {
254   const char *filename;
255   char *dirname;
256   size_t dirlen;
257   int status;
258   int oldcount;
259
260   if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
261     {
262       errno = EINVAL;
263       return -1;
264     }
265
266   if (flags & GLOB_BRACE)
267     {
268       const char *begin = strchr (pattern, '{');
269       if (begin != NULL)
270         {
271           const char *end = strchr (begin + 1, '}');
272           if (end != NULL && end != begin + 1)
273             {
274               size_t restlen = strlen (end + 1) + 1;
275               const char *p, *comma;
276               char *buf;
277               size_t bufsz = 0;
278               int firstc;
279               if (!(flags & GLOB_APPEND))
280                 {
281                   pglob->gl_pathc = 0;
282                   pglob->gl_pathv = NULL;
283                 }
284               firstc = pglob->gl_pathc;
285               for (p = begin + 1;; p = comma + 1)
286                 {
287                   int result;
288                   comma = strchr (p, ',');
289                   if (comma == NULL)
290                     comma = strchr (p, '\0');
291                   if ((begin - pattern) + (comma - p) + 1 > bufsz)
292                     {
293                       if (bufsz * 2 < comma - p + 1)
294                         bufsz *= 2;
295                       else
296                         bufsz = comma - p + 1;
297                       buf = __alloca (bufsz);
298                     }
299                   memcpy (buf, pattern, begin - pattern);
300                   memcpy (buf + (begin - pattern), p, comma - p);
301                   memcpy (buf + (begin - pattern) + (comma - p), end, restlen);
302                   result = glob (buf, ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) |
303                                        GLOB_APPEND), errfunc, pglob);
304                   if (result && result != GLOB_NOMATCH)
305                     return result;
306                   if (*comma == '\0')
307                     break;
308                 }
309               if (pglob->gl_pathc == firstc &&
310                   !(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
311                 return GLOB_NOMATCH;
312             }
313         }
314     }
315
316   /* Find the filename.  */
317   filename = strrchr (pattern, '/');
318   if (filename == NULL)
319     {
320       filename = pattern;
321       dirname = (char *) ".";
322       dirlen = 0;
323     }
324   else if (filename == pattern)
325     {
326       /* "/pattern".  */
327       dirname = (char *) "/";
328       dirlen = 1;
329       ++filename;
330     }
331   else
332     {
333       dirlen = filename - pattern;
334       dirname = (char *) __alloca (dirlen + 1);
335       memcpy (dirname, pattern, dirlen);
336       dirname[dirlen] = '\0';
337       ++filename;
338     }
339
340   if (filename[0] == '\0' && dirlen > 1)
341     /* "pattern/".  Expand "pattern", appending slashes.  */
342     {
343       int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
344       if (val == 0)
345         pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK);
346       return val;
347     }
348
349   if (!(flags & GLOB_APPEND))
350     {
351       pglob->gl_pathc = 0;
352       pglob->gl_pathv = NULL;
353     }
354
355   oldcount = pglob->gl_pathc;
356
357   if ((flags & GLOB_TILDE) && dirname[0] == '~')
358     {
359       if (dirname[1] == '\0')
360         {
361           /* Look up home directory.  */
362           dirname = getenv ("HOME");
363           if (dirname == NULL || dirname[0] == '\0')
364             {
365               extern char *getlogin __P ((void));
366               char *name = getlogin ();
367               if (name != NULL)
368                 {
369                   struct passwd *p = getpwnam (name);
370                   if (p != NULL)
371                     dirname = p->pw_dir;
372                 }
373             }
374           if (dirname == NULL || dirname[0] == '\0')
375             dirname = (char *) "~"; /* No luck.  */
376         }
377       else
378         {
379           /* Look up specific user's home directory.  */
380           struct passwd *p = getpwnam (dirname + 1);
381           if (p != NULL)
382             dirname = p->pw_dir;
383         }
384     }
385
386   if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
387     {
388       /* The directory name contains metacharacters, so we
389          have to glob for the directory, and then glob for
390          the pattern in each directory found.  */
391       glob_t dirs;
392       register int i;
393
394       status = glob (dirname,
395                      ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) |
396                       GLOB_NOSORT),
397                      errfunc, &dirs);
398       if (status != 0)
399         return status;
400
401       /* We have successfully globbed the preceding directory name.
402          For each name we found, call glob_in_dir on it and FILENAME,
403          appending the results to PGLOB.  */
404       for (i = 0; i < dirs.gl_pathc; ++i)
405         {
406           int oldcount;
407
408 #ifdef  SHELL
409           {
410             /* Make globbing interruptible in the bash shell. */
411             extern int interrupt_state;
412
413             if (interrupt_state)
414               {
415                 globfree (&dirs);
416                 globfree (&files);
417                 return GLOB_ABEND;
418               }
419           }
420 #endif /* SHELL.  */
421
422           oldcount = pglob->gl_pathc;
423           status = glob_in_dir (filename, dirs.gl_pathv[i],
424                                 (flags | GLOB_APPEND) & ~GLOB_NOCHECK,
425                                 errfunc, pglob);
426           if (status == GLOB_NOMATCH)
427             /* No matches in this directory.  Try the next.  */
428             continue;
429
430           if (status != 0)
431             {
432               globfree (&dirs);
433               globfree (pglob);
434               return status;
435             }
436
437           /* Stick the directory on the front of each name.  */
438           if (prefix_array (dirs.gl_pathv[i],
439                             &pglob->gl_pathv[oldcount],
440                             pglob->gl_pathc - oldcount))
441             {
442               globfree (&dirs);
443               globfree (pglob);
444               return GLOB_NOSPACE;
445             }
446         }
447
448       flags |= GLOB_MAGCHAR;
449
450       if (pglob->gl_pathc == oldcount)
451         /* No matches.  */
452         if (flags & GLOB_NOCHECK)
453           {
454             size_t len = strlen (pattern) + 1;
455             char *patcopy = (char *) malloc (len);
456             if (patcopy == NULL)
457               return GLOB_NOSPACE;
458             memcpy (patcopy, pattern, len);
459
460             pglob->gl_pathv
461               = (char **) realloc (pglob->gl_pathv,
462                                    (pglob->gl_pathc +
463                                     ((flags & GLOB_DOOFFS) ?
464                                      pglob->gl_offs : 0) +
465                                     1 + 1) *
466                                    sizeof (char *));
467             if (pglob->gl_pathv == NULL)
468               {
469                 free (patcopy);
470                 return GLOB_NOSPACE;
471               }
472
473             if (flags & GLOB_DOOFFS)
474               while (pglob->gl_pathc < pglob->gl_offs)
475                 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
476
477             pglob->gl_pathv[pglob->gl_pathc++] = patcopy;
478             pglob->gl_pathv[pglob->gl_pathc] = NULL;
479             pglob->gl_flags = flags;
480           }
481         else
482           return GLOB_NOMATCH;
483     }
484   else
485     {
486       status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
487       if (status != 0)
488         return status;
489
490       if (dirlen > 0)
491         {
492           /* Stick the directory on the front of each name.  */
493           if (prefix_array (dirname,
494                             &pglob->gl_pathv[oldcount],
495                             pglob->gl_pathc - oldcount))
496             {
497               globfree (pglob);
498               return GLOB_NOSPACE;
499             }
500         }
501     }
502
503   if (flags & GLOB_MARK)
504     {
505       /* Append slashes to directory names.  */
506       int i;
507       struct stat st;
508       for (i = oldcount; i < pglob->gl_pathc; ++i)
509         if (((flags & GLOB_ALTDIRFUNC) ?
510              (*pglob->gl_stat) (pglob->gl_pathv[i], &st) :
511              __stat (pglob->gl_pathv[i], &st)) == 0 &&
512             S_ISDIR (st.st_mode))
513           {
514             size_t len = strlen (pglob->gl_pathv[i]) + 2;
515             char *new = realloc (pglob->gl_pathv[i], len);
516             if (new == NULL)
517               {
518                 globfree (pglob);
519                 return GLOB_NOSPACE;
520               }
521             strcpy (&new[len - 2], "/");
522             pglob->gl_pathv[i] = new;
523           }
524     }
525
526   if (!(flags & GLOB_NOSORT))
527     /* Sort the vector.  */
528     qsort ((__ptr_t) &pglob->gl_pathv[oldcount],
529            pglob->gl_pathc - oldcount,
530            sizeof (char *), collated_compare);
531
532   return 0;
533 }
534
535
536 /* Free storage allocated in PGLOB by a previous `glob' call.  */
537 void
538 globfree (pglob)
539      register glob_t *pglob;
540 {
541   if (pglob->gl_pathv != NULL)
542     {
543       register int i;
544       for (i = 0; i < pglob->gl_pathc; ++i)
545         if (pglob->gl_pathv[i] != NULL)
546           free ((__ptr_t) pglob->gl_pathv[i]);
547       free ((__ptr_t) pglob->gl_pathv);
548     }
549 }
550
551
552 /* Do a collated comparison of A and B.  */
553 static int
554 collated_compare (a, b)
555      const __ptr_t a;
556      const __ptr_t b;
557 {
558   const char *const s1 = *(const char *const * const) a;
559   const char *const s2 = *(const char *const * const) b;
560
561   if (s1 == s2)
562     return 0;
563   if (s1 == NULL)
564     return 1;
565   if (s2 == NULL)
566     return -1;
567   return strcoll (s1, s2);
568 }
569
570
571 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
572    elements in place.  Return nonzero if out of memory, zero if successful.
573    A slash is inserted between DIRNAME and each elt of ARRAY,
574    unless DIRNAME is just "/".  Each old element of ARRAY is freed.  */
575 static int
576 prefix_array (dirname, array, n)
577      const char *dirname;
578      char **array;
579      size_t n;
580 {
581   register size_t i;
582   size_t dirlen = strlen (dirname);
583
584   if (dirlen == 1 && dirname[0] == '/')
585     /* DIRNAME is just "/", so normal prepending would get us "//foo".
586        We want "/foo" instead, so don't prepend any chars from DIRNAME.  */
587     dirlen = 0;
588
589   for (i = 0; i < n; ++i)
590     {
591       size_t eltlen = strlen (array[i]) + 1;
592       char *new = (char *) malloc (dirlen + 1 + eltlen);
593       if (new == NULL)
594         {
595           while (i > 0)
596             free ((__ptr_t) array[--i]);
597           return 1;
598         }
599
600       memcpy (new, dirname, dirlen);
601       new[dirlen] = '/';
602       memcpy (&new[dirlen + 1], array[i], eltlen);
603       free ((__ptr_t) array[i]);
604       array[i] = new;
605     }
606
607   return 0;
608 }
609
610
611 /* Return nonzero if PATTERN contains any metacharacters.
612    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
613 static int
614 glob_pattern_p (pattern, quote)
615      const char *pattern;
616      int quote;
617 {
618   register const char *p;
619   int open = 0;
620
621   for (p = pattern; *p != '\0'; ++p)
622     switch (*p)
623       {
624       case '?':
625       case '*':
626         return 1;
627
628       case '\\':
629         if (quote)
630           ++p;
631         break;
632
633       case '[':
634         open = 1;
635         break;
636
637       case ']':
638         if (open)
639           return 1;
640         break;
641       }
642
643   return 0;
644 }
645
646
647 /* Like `glob', but PATTERN is a final pathname component,
648    and matches are searched for in DIRECTORY.
649    The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
650    The GLOB_APPEND flag is assumed to be set (always appends).  */
651 static int
652 glob_in_dir (pattern, directory, flags, errfunc, pglob)
653      const char *pattern;
654      const char *directory;
655      int flags;
656      int (*errfunc) __P ((const char *, int));
657      glob_t *pglob;
658 {
659   __ptr_t stream;
660
661   struct globlink
662     {
663       struct globlink *next;
664       char *name;
665     };
666   struct globlink *names = NULL;
667   size_t nfound = 0;
668
669   if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))
670     {
671       stream = NULL;
672       flags |= GLOB_NOCHECK;
673     }
674   else
675     {
676       flags |= GLOB_MAGCHAR;
677
678       stream = ((flags & GLOB_ALTDIRFUNC) ?
679                 (*pglob->gl_opendir) (directory) :
680                 (__ptr_t) opendir (directory));
681       if (stream == NULL)
682         {
683           if ((errfunc != NULL && (*errfunc) (directory, errno)) ||
684               (flags & GLOB_ERR))
685             return GLOB_ABEND;
686         }
687       else
688         while (1)
689           {
690             const char *name;
691             size_t len;
692             struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ?
693                                 (*pglob->gl_readdir) (stream) :
694                                 readdir ((DIR *) stream));
695             if (d == NULL)
696               break;
697             if (! REAL_DIR_ENTRY (d))
698               continue;
699
700             name = d->d_name;
701
702             if (fnmatch (pattern, name,
703                          (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |
704                          ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)) == 0)
705               {
706                 struct globlink *new
707                   = (struct globlink *) __alloca (sizeof (struct globlink));
708                 len = NAMLEN (d);
709                 new->name
710                   = (char *) malloc (len + 1);
711                 if (new->name == NULL)
712                   goto memory_error;
713                 memcpy ((__ptr_t) new->name, name, len);
714                 new->name[len] = '\0';
715                 new->next = names;
716                 names = new;
717                 ++nfound;
718               }
719           }
720     }
721
722   if (nfound == 0 && (flags & GLOB_NOMAGIC) &&
723       ! glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))
724     flags |= GLOB_NOCHECK;
725
726   if (nfound == 0 && (flags & GLOB_NOCHECK))
727     {
728       size_t len = strlen (pattern);
729       nfound = 1;
730       names = (struct globlink *) __alloca (sizeof (struct globlink));
731       names->next = NULL;
732       names->name = (char *) malloc (len + 1);
733       if (names->name == NULL)
734         goto memory_error;
735       memcpy (names->name, pattern, len);
736       names->name[len] = '\0';
737     }
738
739   pglob->gl_pathv
740     = (char **) realloc (pglob->gl_pathv,
741                          (pglob->gl_pathc +
742                           ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
743                           nfound + 1) *
744                          sizeof (char *));
745   if (pglob->gl_pathv == NULL)
746     goto memory_error;
747
748   if (flags & GLOB_DOOFFS)
749     while (pglob->gl_pathc < pglob->gl_offs)
750       pglob->gl_pathv[pglob->gl_pathc++] = NULL;
751
752   for (; names != NULL; names = names->next)
753     pglob->gl_pathv[pglob->gl_pathc++] = names->name;
754   pglob->gl_pathv[pglob->gl_pathc] = NULL;
755
756   pglob->gl_flags = flags;
757
758   if (stream != NULL)
759     {
760       int save = errno;
761       if (flags & GLOB_ALTDIRFUNC)
762         (*pglob->gl_closedir) (stream);
763       else
764         closedir ((DIR *) stream);
765       errno = save;
766     }
767   return nfound == 0 ? GLOB_NOMATCH : 0;
768
769  memory_error:
770   {
771     int save = errno;
772     if (flags & GLOB_ALTDIRFUNC)
773       (*pglob->gl_closedir) (stream);
774     else
775       closedir ((DIR *) stream);
776     errno = save;
777   }
778   while (names != NULL)
779     {
780       if (names->name != NULL)
781         free ((__ptr_t) names->name);
782       names = names->next;
783     }
784   return GLOB_NOSPACE;
785 }
786
787 #endif  /* Not ELIDE_CODE.  */
788