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