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