]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/generic/glob.c
Update.
[thirdparty/glibc.git] / sysdeps / generic / glob.c
CommitLineData
fb973e7f 1/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc.
28f540f4 2
47707456
UD
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.
28f540f4 7
47707456
UD
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.
28f540f4 12
47707456
UD
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 not,
15 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA. */
28f540f4
RM
17
18/* AIX requires this to be the first thing in the file. */
dd7d45e8 19#if defined _AIX && !defined __GNUC__
28f540f4
RM
20 #pragma alloca
21#endif
22
23#ifdef HAVE_CONFIG_H
61eb22d3 24# include <config.h>
28f540f4
RM
25#endif
26
97aa195c
RM
27/* Enable GNU extensions in glob.h. */
28#ifndef _GNU_SOURCE
61eb22d3 29# define _GNU_SOURCE 1
97aa195c
RM
30#endif
31
28f540f4
RM
32#include <errno.h>
33#include <sys/types.h>
bf3ccd1a 34#include <sys/stat.h>
28f540f4 35
5ae9d168
UD
36/* Outcomment the following line for production quality code. */
37/* #define NDEBUG 1 */
38#include <assert.h>
39
ca34d7a7
UD
40#include <stdio.h> /* Needed on stupid SunOS for assert. */
41
28f540f4
RM
42
43/* Comment out all this code if we are using the GNU C Library, and are not
44 actually compiling the library itself. This code is part of the GNU C
45 Library, but also included in many other GNU distributions. Compiling
46 and linking in this code is a waste when using the GNU C library
47 (especially if it is a shared library). Rather than having every GNU
48 program understand `configure --with-gnu-libc' and omit the object files,
49 it is simpler to just do this in the source for each such file. */
50
787e4db9 51#define GLOB_INTERFACE_VERSION 1
61eb22d3
UD
52#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
53# include <gnu-versions.h>
54# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
55# define ELIDE_CODE
56# endif
787e4db9 57#endif
28f540f4 58
787e4db9 59#ifndef ELIDE_CODE
28f540f4 60
61eb22d3
UD
61#if defined STDC_HEADERS || defined __GNU_LIBRARY__
62# include <stddef.h>
28f540f4
RM
63#endif
64
e4cf5070 65#if defined HAVE_UNISTD_H || defined _LIBC
61eb22d3
UD
66# include <unistd.h>
67# ifndef POSIX
68# ifdef _POSIX_VERSION
69# define POSIX
70# endif
71# endif
28f540f4
RM
72#endif
73
61eb22d3
UD
74#if !defined _AMIGA && !defined VMS && !defined WINDOWS32
75# include <pwd.h>
9fb16eea 76#endif
787e4db9 77
61eb22d3 78#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS
28f540f4
RM
79extern int errno;
80#endif
c4029823 81#ifndef __set_errno
61eb22d3 82# define __set_errno(val) errno = (val)
c4029823 83#endif
28f540f4
RM
84
85#ifndef NULL
61eb22d3 86# define NULL 0
28f540f4
RM
87#endif
88
89
61eb22d3 90#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
e9607dbe
RM
91# include <dirent.h>
92# define NAMLEN(dirent) strlen((dirent)->d_name)
93#else
94# define dirent direct
95# define NAMLEN(dirent) (dirent)->d_namlen
96# ifdef HAVE_SYS_NDIR_H
97# include <sys/ndir.h>
98# endif
99# ifdef HAVE_SYS_DIR_H
100# include <sys/dir.h>
101# endif
102# ifdef HAVE_NDIR_H
103# include <ndir.h>
104# endif
0efef8fc
RM
105# ifdef HAVE_VMSDIR_H
106# include "vmsdir.h"
107# endif /* HAVE_VMSDIR_H */
e9607dbe
RM
108#endif
109
110
111/* In GNU systems, <dirent.h> defines this macro for us. */
112#ifdef _D_NAMLEN
61eb22d3
UD
113# undef NAMLEN
114# define NAMLEN(d) _D_NAMLEN(d)
e9607dbe
RM
115#endif
116
1cab5444
UD
117/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
118 if the `d_type' member for `struct dirent' is available. */
119#ifdef _DIRENT_HAVE_D_TYPE
120# define HAVE_D_TYPE 1
121#endif
122
28f540f4 123
61eb22d3 124#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
28f540f4
RM
125/* Posix does not require that the d_ino field be present, and some
126 systems do not provide it. */
61eb22d3 127# define REAL_DIR_ENTRY(dp) 1
28f540f4 128#else
61eb22d3 129# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
28f540f4
RM
130#endif /* POSIX */
131
61eb22d3
UD
132#if defined STDC_HEADERS || defined __GNU_LIBRARY__
133# include <stdlib.h>
134# include <string.h>
135# define ANSI_STRING
28f540f4
RM
136#else /* No standard headers. */
137
3be01400
RM
138extern char *getenv ();
139
61eb22d3
UD
140# ifdef HAVE_STRING_H
141# include <string.h>
142# define ANSI_STRING
143# else
144# include <strings.h>
145# endif
146# ifdef HAVE_MEMORY_H
147# include <memory.h>
148# endif
28f540f4
RM
149
150extern char *malloc (), *realloc ();
151extern void free ();
152
153extern void qsort ();
154extern void abort (), exit ();
155
156#endif /* Standard headers. */
157
ec986e23
UD
158#ifdef HAVE_GETLOGIN_R
159extern int getlogin_r __P ((char *, size_t));
160#else
161extern char *getlogin __P ((void));
162#endif
163
28f540f4
RM
164#ifndef ANSI_STRING
165
61eb22d3 166# ifndef bzero
28f540f4 167extern void bzero ();
61eb22d3
UD
168# endif
169# ifndef bcopy
28f540f4 170extern void bcopy ();
61eb22d3 171# endif
28f540f4 172
61eb22d3
UD
173# define memcpy(d, s, n) bcopy ((s), (d), (n))
174# define strrchr rindex
28f540f4 175/* memset is only used for zero here, but let's be paranoid. */
61eb22d3 176# define memset(s, better_be_zero, n) \
28f540f4
RM
177 ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
178#endif /* Not ANSI_STRING. */
179
5ae9d168 180#if !defined HAVE_STRCOLL && !defined _LIBC
61eb22d3 181# define strcoll strcmp
28f540f4
RM
182#endif
183
dd7d45e8
UD
184#if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1
185# define HAVE_MEMPCPY 1
1f5d369d 186# undef mempcpy
dd7d45e8
UD
187# define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
188#endif
189
28f540f4 190#ifndef __GNU_LIBRARY__
61eb22d3 191# ifdef __GNUC__
28f540f4 192__inline
61eb22d3
UD
193# endif
194# ifndef __SASC
195# ifdef WINDOWS32
ed30638a 196static void *
61eb22d3 197# else
28f540f4 198static char *
61eb22d3 199# endif
28f540f4
RM
200my_realloc (p, n)
201 char *p;
202 unsigned int n;
203{
204 /* These casts are the for sake of the broken Ultrix compiler,
205 which warns of illegal pointer combinations otherwise. */
206 if (p == NULL)
207 return (char *) malloc (n);
208 return (char *) realloc (p, n);
209}
61eb22d3
UD
210# define realloc my_realloc
211# endif /* __SASC */
9fb16eea 212#endif /* __GNU_LIBRARY__ */
28f540f4
RM
213
214
61eb22d3 215#if !defined __alloca && !defined __GNU_LIBRARY__
28f540f4 216
61eb22d3
UD
217# ifdef __GNUC__
218# undef alloca
219# define alloca(n) __builtin_alloca (n)
220# else /* Not GCC. */
221# ifdef HAVE_ALLOCA_H
222# include <alloca.h>
223# else /* Not HAVE_ALLOCA_H. */
224# ifndef _AIX
225# ifdef WINDOWS32
226# include <malloc.h>
227# else
28f540f4 228extern char *alloca ();
61eb22d3
UD
229# endif /* WINDOWS32 */
230# endif /* Not _AIX. */
231# endif /* sparc or HAVE_ALLOCA_H. */
232# endif /* GCC. */
28f540f4 233
61eb22d3 234# define __alloca alloca
28f540f4
RM
235
236#endif
237
bf3ccd1a 238#ifndef __GNU_LIBRARY__
61eb22d3
UD
239# define __stat stat
240# ifdef STAT_MACROS_BROKEN
241# undef S_ISDIR
242# endif
243# ifndef S_ISDIR
244# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
245# endif
bf3ccd1a
RM
246#endif
247
50304ef0 248#ifdef _LIBC
c3966b88 249# undef strdup
c9243dac 250# define strdup(str) __strdup (str)
50304ef0
UD
251# define sysconf(id) __sysconf (id)
252# define closedir(dir) __closedir (dir)
253# define opendir(name) __opendir (name)
254# define readdir(str) __readdir (str)
ec986e23
UD
255# define getpwnam_r(name, bufp, buf, len, res) \
256 __getpwnam_r (name, bufp, buf, len, res)
df777c40
UD
257# ifndef __stat
258# define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
259# endif
50304ef0
UD
260#endif
261
61eb22d3
UD
262#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
263# undef size_t
264# define size_t unsigned int
28f540f4
RM
265#endif
266
267/* Some system header files erroneously define these.
268 We want our own definitions from <fnmatch.h> to take precedence. */
d47aac39
UD
269#ifndef __GNU_LIBRARY__
270# undef FNM_PATHNAME
271# undef FNM_NOESCAPE
272# undef FNM_PERIOD
273#endif
28f540f4
RM
274#include <fnmatch.h>
275
276/* Some system header files erroneously define these.
277 We want our own definitions from <glob.h> to take precedence. */
a53bad16
UD
278#ifndef __GNU_LIBRARY__
279# undef GLOB_ERR
280# undef GLOB_MARK
281# undef GLOB_NOSORT
282# undef GLOB_DOOFFS
283# undef GLOB_NOCHECK
284# undef GLOB_APPEND
285# undef GLOB_NOESCAPE
286# undef GLOB_PERIOD
287#endif
28f540f4
RM
288#include <glob.h>
289\f
f41c8091
UD
290static
291#if __GNUC__ - 0 >= 2
292inline
293#endif
294const char *next_brace_sub __P ((const char *begin));
28f540f4
RM
295static int glob_in_dir __P ((const char *pattern, const char *directory,
296 int flags,
df777c40 297 int (*errfunc) (const char *, int),
28f540f4
RM
298 glob_t *pglob));
299static int prefix_array __P ((const char *prefix, char **array, size_t n));
300static int collated_compare __P ((const __ptr_t, const __ptr_t));
301
5ae9d168
UD
302
303/* Find the end of the sub-pattern in a brace expression. We define
304 this as an inline function if the compiler permits. */
305static
306#if __GNUC__ - 0 >= 2
307inline
308#endif
309const char *
ca34d7a7
UD
310next_brace_sub (begin)
311 const char *begin;
5ae9d168
UD
312{
313 unsigned int depth = 0;
314 const char *cp = begin;
315
316 while (1)
317 {
318 if (depth == 0)
319 {
320 if (*cp != ',' && *cp != '}' && *cp != '\0')
321 {
322 if (*cp == '{')
323 ++depth;
324 ++cp;
325 continue;
326 }
327 }
328 else
329 {
330 while (*cp != '\0' && (*cp != '}' || depth > 0))
331 {
332 if (*cp == '}')
e7fd8a39 333 --depth;
5ae9d168
UD
334 ++cp;
335 }
336 if (*cp == '\0')
337 /* An incorrectly terminated brace expression. */
338 return NULL;
339
340 continue;
341 }
342 break;
343 }
344
345 return cp;
346}
347
28f540f4
RM
348/* Do glob searching for PATTERN, placing results in PGLOB.
349 The bits defined above may be set in FLAGS.
350 If a directory cannot be opened or read and ERRFUNC is not nil,
351 it is called with the pathname that caused the error, and the
352 `errno' value from the failing call; if it returns non-zero
714a562f 353 `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
28f540f4
RM
354 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
355 Otherwise, `glob' returns zero. */
356int
357glob (pattern, flags, errfunc, pglob)
358 const char *pattern;
359 int flags;
360 int (*errfunc) __P ((const char *, int));
361 glob_t *pglob;
362{
363 const char *filename;
ec986e23 364 const char *dirname;
28f540f4
RM
365 size_t dirlen;
366 int status;
367 int oldcount;
368
369 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
370 {
c4029823 371 __set_errno (EINVAL);
28f540f4
RM
372 return -1;
373 }
374
787e4db9
RM
375 if (flags & GLOB_BRACE)
376 {
377 const char *begin = strchr (pattern, '{');
378 if (begin != NULL)
379 {
5ae9d168
UD
380 /* Allocate working buffer large enough for our work. Note that
381 we have at least an opening and closing brace. */
6025c399 382 int firstc;
5ae9d168
UD
383 char *alt_start;
384 const char *p;
385 const char *next;
386 const char *rest;
387 size_t rest_len;
388#ifdef __GNUC__
389 char onealt[strlen (pattern) - 1];
390#else
391 char *onealt = (char *) malloc (strlen (pattern) - 1);
392 if (onealt == NULL)
393 {
394 if (!(flags & GLOB_APPEND))
395 globfree (pglob);
396 return GLOB_NOSPACE;
397 }
398#endif
399
400 /* We know the prefix for all sub-patterns. */
86187531
UD
401#ifdef HAVE_MEMPCPY
402 alt_start = mempcpy (onealt, pattern, begin - pattern);
403#else
5ae9d168
UD
404 memcpy (onealt, pattern, begin - pattern);
405 alt_start = &onealt[begin - pattern];
86187531 406#endif
5ae9d168
UD
407
408 /* Find the first sub-pattern and at the same time find the
409 rest after the closing brace. */
410 next = next_brace_sub (begin + 1);
411 if (next == NULL)
787e4db9 412 {
5ae9d168
UD
413 /* It is an illegal expression. */
414#ifndef __GNUC__
415 free (onealt);
416#endif
417 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
418 }
419
420 /* Now find the end of the whole brace expression. */
421 rest = next;
422 while (*rest != '}')
423 {
424 rest = next_brace_sub (rest + 1);
425 if (rest == NULL)
787e4db9 426 {
5ae9d168
UD
427 /* It is an illegal expression. */
428#ifndef __GNUC__
429 free (onealt);
430#endif
431 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
6025c399 432 }
6025c399 433 }
5ae9d168
UD
434 /* Please note that we now can be sure the brace expression
435 is well-formed. */
436 rest_len = strlen (++rest) + 1;
6025c399
RM
437
438 /* We have a brace expression. BEGIN points to the opening {,
439 NEXT points past the terminator of the first element, and END
440 points past the final }. We will accumulate result names from
441 recursive runs for each brace alternative in the buffer using
442 GLOB_APPEND. */
443
444 if (!(flags & GLOB_APPEND))
445 {
446 /* This call is to set a new vector, so clear out the
447 vector so we can append to it. */
448 pglob->gl_pathc = 0;
449 pglob->gl_pathv = NULL;
450 }
451 firstc = pglob->gl_pathc;
452
6025c399
RM
453 p = begin + 1;
454 while (1)
455 {
6025c399 456 int result;
5ae9d168
UD
457
458 /* Construct the new glob expression. */
dd7d45e8
UD
459#ifdef HAVE_MEMPCPY
460 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
461#else
5ae9d168
UD
462 memcpy (alt_start, p, next - p);
463 memcpy (&alt_start[next - p], rest, rest_len);
dd7d45e8 464#endif
5ae9d168 465
6025c399 466 result = glob (onealt,
5ae9d168
UD
467 ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
468 | GLOB_APPEND), errfunc, pglob);
6025c399
RM
469
470 /* If we got an error, return it. */
471 if (result && result != GLOB_NOMATCH)
787e4db9 472 {
5ae9d168
UD
473#ifndef __GNUC__
474 free (onealt);
475#endif
6025c399
RM
476 if (!(flags & GLOB_APPEND))
477 globfree (pglob);
478 return result;
479 }
480
5ae9d168
UD
481 if (*next == '}')
482 /* We saw the last entry. */
483 break;
484
485 p = next + 1;
486 next = next_brace_sub (p);
487 assert (next != NULL);
787e4db9 488 }
6025c399 489
5ae9d168
UD
490#ifndef __GNUC__
491 free (onealt);
492#endif
493
494 if (pglob->gl_pathc != firstc)
495 /* We found some entries. */
496 return 0;
497 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
6025c399 498 return GLOB_NOMATCH;
787e4db9
RM
499 }
500 }
501
28f540f4
RM
502 /* Find the filename. */
503 filename = strrchr (pattern, '/');
786a5421
UD
504#if defined __MSDOS__ || defined WINDOWS32
505 /* The case of "d:pattern". Since `:' is not allowed in
506 file names, we can safely assume that wherever it
507 happens in pattern, it signals the filename part. This
508 is so we could some day support patterns like "[a-z]:foo". */
509 if (filename == NULL)
510 filename = strchr (pattern, ':');
511#endif /* __MSDOS__ || WINDOWS32 */
28f540f4
RM
512 if (filename == NULL)
513 {
6c202c68
UD
514 /* This can mean two things: a simple name or "~name". The later
515 case is nothing but a notation for a directory. */
1bc21e7a 516 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
6c202c68 517 {
7cabd57c 518 dirname = pattern;
6c202c68
UD
519 dirlen = strlen (pattern);
520
c9243dac 521 /* Set FILENAME to NULL as a special flag. This is ugly but
786a5421 522 other solutions would require much more code. We test for
c9243dac
UD
523 this special case below. */
524 filename = NULL;
6c202c68
UD
525 }
526 else
527 {
528 filename = pattern;
9fb16eea 529#ifdef _AMIGA
ec986e23 530 dirname = "";
9fb16eea 531#else
ec986e23 532 dirname = ".";
9fb16eea 533#endif
6c202c68
UD
534 dirlen = 0;
535 }
28f540f4
RM
536 }
537 else if (filename == pattern)
538 {
539 /* "/pattern". */
ec986e23 540 dirname = "/";
28f540f4
RM
541 dirlen = 1;
542 ++filename;
543 }
544 else
545 {
ec986e23 546 char *newp;
28f540f4 547 dirlen = filename - pattern;
786a5421
UD
548#if defined __MSDOS__ || defined WINDOWS32
549 if (*filename == ':'
550 || (filename > pattern + 1 && filename[-1] == ':'))
551 {
552 char *drive_spec;
553
554 ++dirlen;
555 drive_spec = (char *) __alloca (dirlen + 1);
556#ifdef HAVE_MEMPCPY
557 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
558#else
559 memcpy (drive_spec, pattern, dirlen);
560 drive_spec[dirlen] = '\0';
561#endif
562 /* For now, disallow wildcards in the drive spec, to
563 prevent infinite recursion in glob. */
564 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
565 return GLOB_NOMATCH;
566 /* If this is "d:pattern", we need to copy `:' to DIRNAME
567 as well. If it's "d:/pattern", don't remove the slash
568 from "d:/", since "d:" and "d:/" are not the same.*/
569 }
570#endif
ec986e23 571 newp = (char *) __alloca (dirlen + 1);
dd7d45e8 572#ifdef HAVE_MEMPCPY
ec986e23 573 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
dd7d45e8 574#else
ec986e23
UD
575 memcpy (newp, pattern, dirlen);
576 newp[dirlen] = '\0';
dd7d45e8 577#endif
ec986e23 578 dirname = newp;
28f540f4 579 ++filename;
28f540f4 580
786a5421
UD
581 if (filename[0] == '\0'
582#if defined __MSDOS__ || defined WINDOWS32
583 && dirname[dirlen - 1] != ':'
584 && (dirlen < 3 || dirname[dirlen - 2] != ':'
585 || dirname[dirlen - 1] != '/')
586#endif
587 && dirlen > 1)
6c202c68
UD
588 /* "pattern/". Expand "pattern", appending slashes. */
589 {
590 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
591 if (val == 0)
592 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
593 | (flags & GLOB_MARK));
594 return val;
595 }
28f540f4
RM
596 }
597
598 if (!(flags & GLOB_APPEND))
599 {
600 pglob->gl_pathc = 0;
601 pglob->gl_pathv = NULL;
602 }
603
604 oldcount = pglob->gl_pathc;
605
0efef8fc 606#ifndef VMS
1bc21e7a 607 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
787e4db9 608 {
5ae9d168 609 if (dirname[1] == '\0' || dirname[1] == '/')
787e4db9
RM
610 {
611 /* Look up home directory. */
ec986e23 612 const char *home_dir = getenv ("HOME");
61eb22d3 613# ifdef _AMIGA
5ae9d168
UD
614 if (home_dir == NULL || home_dir[0] == '\0')
615 home_dir = "SYS:";
61eb22d3
UD
616# else
617# ifdef WINDOWS32
5ae9d168
UD
618 if (home_dir == NULL || home_dir[0] == '\0')
619 home_dir = "c:/users/default"; /* poor default */
61eb22d3 620# else
5ae9d168 621 if (home_dir == NULL || home_dir[0] == '\0')
787e4db9 622 {
e4cf5070 623 int success;
ec986e23 624 char *name;
61eb22d3 625# if defined HAVE_GETLOGIN_R || defined _LIBC
e4cf5070 626 size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
e4cf5070
UD
627
628 if (buflen == 0)
629 /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
630 a moderate value. */
ec986e23 631 buflen = 20;
ca34d7a7 632 name = (char *) __alloca (buflen);
e4cf5070
UD
633
634 success = getlogin_r (name, buflen) >= 0;
61eb22d3 635# else
e4cf5070 636 success = (name = getlogin ()) != NULL;
61eb22d3 637# endif
e4cf5070 638 if (success)
787e4db9 639 {
ec986e23 640 struct passwd *p;
61eb22d3 641# if defined HAVE_GETPWNAM_R || defined _LIBC
e4cf5070
UD
642 size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
643 char *pwtmpbuf;
ec986e23 644 struct passwd pwbuf;
e4cf5070 645
ec986e23
UD
646 if (pwbuflen == -1)
647 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
648 Try a moderate value. */
649 pwbuflen = 1024;
ca34d7a7 650 pwtmpbuf = (char *) __alloca (pwbuflen);
e4cf5070 651
ec986e23
UD
652 success = (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
653 >= 0);
61eb22d3 654# else
ec986e23 655 p = getpwnam (name);
e4cf5070 656 success = p != NULL;
61eb22d3 657# endif
e4cf5070 658 if (success)
5ae9d168 659 home_dir = p->pw_dir;
787e4db9
RM
660 }
661 }
5ae9d168 662 if (home_dir == NULL || home_dir[0] == '\0')
6e4c40ba
UD
663 {
664 if (flags & GLOB_TILDE_CHECK)
665 return GLOB_NOMATCH;
666 else
667 home_dir = "~"; /* No luck. */
668 }
61eb22d3
UD
669# endif /* WINDOWS32 */
670# endif
5ae9d168
UD
671 /* Now construct the full directory. */
672 if (dirname[1] == '\0')
673 dirname = home_dir;
674 else
675 {
676 char *newp;
677 size_t home_len = strlen (home_dir);
ca34d7a7 678 newp = (char *) __alloca (home_len + dirlen);
dd7d45e8
UD
679# ifdef HAVE_MEMPCPY
680 mempcpy (mempcpy (newp, home_dir, home_len),
681 &dirname[1], dirlen);
682# else
5ae9d168
UD
683 memcpy (newp, home_dir, home_len);
684 memcpy (&newp[home_len], &dirname[1], dirlen);
dd7d45e8 685# endif
5ae9d168
UD
686 dirname = newp;
687 }
787e4db9 688 }
61eb22d3 689# if !defined _AMIGA && !defined WINDOWS32
787e4db9
RM
690 else
691 {
5ae9d168 692 char *end_name = strchr (dirname, '/');
ec986e23
UD
693 const char *user_name;
694 const char *home_dir;
5ae9d168
UD
695
696 if (end_name == NULL)
697 user_name = dirname + 1;
698 else
699 {
ec986e23
UD
700 char *newp;
701 newp = (char *) __alloca (end_name - dirname);
dd7d45e8 702# ifdef HAVE_MEMPCPY
ec986e23 703 *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
dd7d45e8
UD
704 = '\0';
705# else
ec986e23
UD
706 memcpy (newp, dirname + 1, end_name - dirname);
707 newp[end_name - dirname - 1] = '\0';
dd7d45e8 708# endif
ec986e23 709 user_name = newp;
5ae9d168
UD
710 }
711
787e4db9 712 /* Look up specific user's home directory. */
5ae9d168 713 {
ec986e23 714 struct passwd *p;
61eb22d3 715# if defined HAVE_GETPWNAM_R || defined _LIBC
5ae9d168 716 size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
ec986e23
UD
717 char *pwtmpbuf;
718 struct passwd pwbuf;
719
720 if (buflen == -1)
721 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
722 moderate value. */
723 buflen = 1024;
724 pwtmpbuf = (char *) __alloca (buflen);
725
726 if (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0)
5ae9d168
UD
727 home_dir = p->pw_dir;
728 else
729 home_dir = NULL;
61eb22d3 730# else
ec986e23 731 p = getpwnam (user_name);
5ae9d168
UD
732 if (p != NULL)
733 home_dir = p->pw_dir;
734 else
735 home_dir = NULL;
61eb22d3 736# endif
5ae9d168
UD
737 }
738 /* If we found a home directory use this. */
739 if (home_dir != NULL)
740 {
741 char *newp;
742 size_t home_len = strlen (home_dir);
743 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
ca34d7a7 744 newp = (char *) __alloca (home_len + rest_len + 1);
dd7d45e8
UD
745# ifdef HAVE_MEMPCPY
746 *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
747 end_name, rest_len)) = '\0';
748# else
5ae9d168
UD
749 memcpy (newp, home_dir, home_len);
750 memcpy (&newp[home_len], end_name, rest_len);
751 newp[home_len + rest_len] = '\0';
dd7d45e8 752# endif
5ae9d168
UD
753 dirname = newp;
754 }
1bc21e7a
UD
755 else
756 if (flags & GLOB_TILDE_CHECK)
757 /* We have to regard it as an error if we cannot find the
758 home directory. */
759 return GLOB_NOMATCH;
787e4db9 760 }
61eb22d3 761# endif /* Not Amiga && not WINDOWS32. */
787e4db9 762 }
0efef8fc 763#endif /* Not VMS. */
787e4db9 764
c9243dac
UD
765 /* Now test whether we looked for "~" or "~NAME". In this case we
766 can give the answer now. */
767 if (filename == NULL)
768 {
769 struct stat st;
770
771 /* Return the directory if we don't check for error or if it exists. */
772 if ((flags & GLOB_NOCHECK)
773 || (((flags & GLOB_ALTDIRFUNC)
774 ? (*pglob->gl_stat) (dirname, &st)
775 : __stat (dirname, &st)) == 0
776 && S_ISDIR (st.st_mode)))
777 {
778 pglob->gl_pathv
779 = (char **) realloc (pglob->gl_pathv,
780 (pglob->gl_pathc +
781 ((flags & GLOB_DOOFFS) ?
782 pglob->gl_offs : 0) +
783 1 + 1) *
784 sizeof (char *));
785 if (pglob->gl_pathv == NULL)
786 return GLOB_NOSPACE;
787
788 if (flags & GLOB_DOOFFS)
789 while (pglob->gl_pathc < pglob->gl_offs)
790 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
791
792#if defined HAVE_STRDUP || defined _LIBC
793 pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
794#else
795 {
796 size_t len = strlen (dirname) + 1;
797 char *dircopy = malloc (len);
798 if (dircopy != NULL)
799 pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
800 len);
801 }
802#endif
803 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
804 {
805 free (pglob->gl_pathv);
806 return GLOB_NOSPACE;
807 }
808 pglob->gl_pathv[++pglob->gl_pathc] = NULL;
809 pglob->gl_flags = flags;
810
811 return 0;
812 }
813
814 /* Not found. */
815 return GLOB_NOMATCH;
816 }
817
e7fd8a39 818 if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
28f540f4
RM
819 {
820 /* The directory name contains metacharacters, so we
821 have to glob for the directory, and then glob for
822 the pattern in each directory found. */
823 glob_t dirs;
824 register int i;
825
826 status = glob (dirname,
1cab5444
UD
827 ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
828 | GLOB_NOSORT | GLOB_ONLYDIR),
28f540f4
RM
829 errfunc, &dirs);
830 if (status != 0)
831 return status;
832
833 /* We have successfully globbed the preceding directory name.
834 For each name we found, call glob_in_dir on it and FILENAME,
835 appending the results to PGLOB. */
836 for (i = 0; i < dirs.gl_pathc; ++i)
837 {
cc60175e 838 int old_pathc;
28f540f4
RM
839
840#ifdef SHELL
841 {
842 /* Make globbing interruptible in the bash shell. */
843 extern int interrupt_state;
844
845 if (interrupt_state)
846 {
847 globfree (&dirs);
848 globfree (&files);
714a562f 849 return GLOB_ABORTED;
28f540f4
RM
850 }
851 }
852#endif /* SHELL. */
853
cc60175e 854 old_pathc = pglob->gl_pathc;
28f540f4 855 status = glob_in_dir (filename, dirs.gl_pathv[i],
1cab5444
UD
856 ((flags | GLOB_APPEND)
857 & ~(GLOB_NOCHECK | GLOB_ERR)),
28f540f4
RM
858 errfunc, pglob);
859 if (status == GLOB_NOMATCH)
860 /* No matches in this directory. Try the next. */
861 continue;
862
863 if (status != 0)
864 {
865 globfree (&dirs);
866 globfree (pglob);
867 return status;
868 }
869
870 /* Stick the directory on the front of each name. */
871 if (prefix_array (dirs.gl_pathv[i],
cc60175e
UD
872 &pglob->gl_pathv[old_pathc],
873 pglob->gl_pathc - old_pathc))
28f540f4
RM
874 {
875 globfree (&dirs);
876 globfree (pglob);
877 return GLOB_NOSPACE;
878 }
879 }
880
881 flags |= GLOB_MAGCHAR;
882
e852e889
UD
883 /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
884 But if we have not found any matching entry and thie GLOB_NOCHECK
885 flag was set we must return the list consisting of the disrectory
886 names followed by the filename. */
28f540f4 887 if (pglob->gl_pathc == oldcount)
6e4c40ba
UD
888 {
889 /* No matches. */
890 if (flags & GLOB_NOCHECK)
891 {
892 size_t filename_len = strlen (filename) + 1;
893 char **new_pathv;
894 struct stat st;
895
896 /* This is an pessimistic guess about the size. */
897 pglob->gl_pathv
898 = (char **) realloc (pglob->gl_pathv,
899 (pglob->gl_pathc +
900 ((flags & GLOB_DOOFFS) ?
901 pglob->gl_offs : 0) +
902 dirs.gl_pathc + 1) *
903 sizeof (char *));
904 if (pglob->gl_pathv == NULL)
905 {
906 globfree (&dirs);
907 return GLOB_NOSPACE;
908 }
28f540f4 909
6e4c40ba
UD
910 if (flags & GLOB_DOOFFS)
911 while (pglob->gl_pathc < pglob->gl_offs)
912 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
28f540f4 913
6e4c40ba
UD
914 for (i = 0; i < dirs.gl_pathc; ++i)
915 {
916 const char *dir = dirs.gl_pathv[i];
917 size_t dir_len = strlen (dir);
918
919 /* First check whether this really is a directory. */
920 if (((flags & GLOB_ALTDIRFUNC)
921 ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
922 || !S_ISDIR (st.st_mode))
923 /* No directory, ignore this entry. */
924 continue;
925
926 pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
927 + filename_len);
928 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
929 {
930 globfree (&dirs);
931 globfree (pglob);
932 return GLOB_NOSPACE;
933 }
e852e889
UD
934
935#ifdef HAVE_MEMPCPY
6e4c40ba
UD
936 mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
937 dir, dir_len),
938 "/", 1),
939 filename, filename_len);
e852e889 940#else
6e4c40ba
UD
941 memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
942 pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
943 memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
944 filename, filename_len);
e852e889 945#endif
6e4c40ba
UD
946 ++pglob->gl_pathc;
947 }
e852e889 948
6e4c40ba
UD
949 pglob->gl_pathv[pglob->gl_pathc] = NULL;
950 pglob->gl_flags = flags;
e852e889 951
6e4c40ba
UD
952 /* Now we know how large the gl_pathv vector must be. */
953 new_pathv = (char **) realloc (pglob->gl_pathv,
954 ((pglob->gl_pathc + 1)
955 * sizeof (char *)));
956 if (new_pathv != NULL)
957 pglob->gl_pathv = new_pathv;
958 }
959 else
960 return GLOB_NOMATCH;
961 }
e852e889
UD
962
963 globfree (&dirs);
28f540f4
RM
964 }
965 else
966 {
967 status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
968 if (status != 0)
969 return status;
970
971 if (dirlen > 0)
972 {
973 /* Stick the directory on the front of each name. */
cc60175e
UD
974 int ignore = oldcount;
975
976 if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs)
977 ignore = pglob->gl_offs;
978
28f540f4 979 if (prefix_array (dirname,
cc60175e
UD
980 &pglob->gl_pathv[ignore],
981 pglob->gl_pathc - ignore))
28f540f4
RM
982 {
983 globfree (pglob);
984 return GLOB_NOSPACE;
985 }
986 }
987 }
988
bf3ccd1a
RM
989 if (flags & GLOB_MARK)
990 {
c043db7a 991 /* Append slashes to directory names. */
bf3ccd1a
RM
992 int i;
993 struct stat st;
994 for (i = oldcount; i < pglob->gl_pathc; ++i)
a9ddb793
UD
995 if (((flags & GLOB_ALTDIRFUNC)
996 ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
997 : __stat (pglob->gl_pathv[i], &st)) == 0
998 && S_ISDIR (st.st_mode))
a993273c
RM
999 {
1000 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1001 char *new = realloc (pglob->gl_pathv[i], len);
1002 if (new == NULL)
1003 {
1004 globfree (pglob);
1005 return GLOB_NOSPACE;
1006 }
1007 strcpy (&new[len - 2], "/");
1008 pglob->gl_pathv[i] = new;
1009 }
bf3ccd1a
RM
1010 }
1011
28f540f4 1012 if (!(flags & GLOB_NOSORT))
cc60175e
UD
1013 {
1014 /* Sort the vector. */
1015 int non_sort = oldcount;
1016
1017 if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount)
1018 non_sort = pglob->gl_offs;
1019
1020 qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
1021 pglob->gl_pathc - non_sort,
1022 sizeof (char *), collated_compare);
1023 }
28f540f4
RM
1024
1025 return 0;
1026}
1027
1028
1029/* Free storage allocated in PGLOB by a previous `glob' call. */
1030void
1031globfree (pglob)
1032 register glob_t *pglob;
1033{
1034 if (pglob->gl_pathv != NULL)
1035 {
1036 register int i;
1037 for (i = 0; i < pglob->gl_pathc; ++i)
1038 if (pglob->gl_pathv[i] != NULL)
1039 free ((__ptr_t) pglob->gl_pathv[i]);
1040 free ((__ptr_t) pglob->gl_pathv);
1041 }
1042}
1043
1044
1045/* Do a collated comparison of A and B. */
1046static int
1047collated_compare (a, b)
1048 const __ptr_t a;
1049 const __ptr_t b;
1050{
1051 const char *const s1 = *(const char *const * const) a;
1052 const char *const s2 = *(const char *const * const) b;
1053
1054 if (s1 == s2)
1055 return 0;
1056 if (s1 == NULL)
1057 return 1;
1058 if (s2 == NULL)
1059 return -1;
1060 return strcoll (s1, s2);
1061}
1062
1063
1064/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1065 elements in place. Return nonzero if out of memory, zero if successful.
1066 A slash is inserted between DIRNAME and each elt of ARRAY,
1067 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1068static int
1069prefix_array (dirname, array, n)
1070 const char *dirname;
1071 char **array;
1072 size_t n;
1073{
1074 register size_t i;
1075 size_t dirlen = strlen (dirname);
786a5421
UD
1076#if defined __MSDOS__ || defined WINDOWS32
1077 int sep_char = '/';
1078# define DIRSEP_CHAR sep_char
1079#else
1080# define DIRSEP_CHAR '/'
1081#endif
28f540f4
RM
1082
1083 if (dirlen == 1 && dirname[0] == '/')
1084 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1085 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1086 dirlen = 0;
786a5421
UD
1087#if defined __MSDOS__ || defined WINDOWS32
1088 else if (dirlen > 1)
1089 {
1090 if (dirname[dirlen - 1] == '/')
1091 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1092 --dirlen;
1093 else if (dirname[dirlen - 1] == ':')
1094 {
1095 /* DIRNAME is "d:". Use `:' instead of `/'. */
1096 --dirlen;
1097 sep_char = ':';
1098 }
1099 }
1100#endif
28f540f4
RM
1101
1102 for (i = 0; i < n; ++i)
1103 {
1104 size_t eltlen = strlen (array[i]) + 1;
1105 char *new = (char *) malloc (dirlen + 1 + eltlen);
1106 if (new == NULL)
1107 {
1108 while (i > 0)
1109 free ((__ptr_t) array[--i]);
1110 return 1;
1111 }
1112
dd7d45e8
UD
1113#ifdef HAVE_MEMPCPY
1114 {
1115 char *endp = (char *) mempcpy (new, dirname, dirlen);
786a5421 1116 *endp++ = DIRSEP_CHAR;
dd7d45e8
UD
1117 mempcpy (endp, array[i], eltlen);
1118 }
1119#else
28f540f4 1120 memcpy (new, dirname, dirlen);
786a5421 1121 new[dirlen] = DIRSEP_CHAR;
28f540f4 1122 memcpy (&new[dirlen + 1], array[i], eltlen);
dd7d45e8 1123#endif
28f540f4
RM
1124 free ((__ptr_t) array[i]);
1125 array[i] = new;
1126 }
1127
1128 return 0;
1129}
1130
1131
a5f4e34a 1132/* We must not compile this function twice. */
1f539fd1 1133#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
28f540f4
RM
1134/* Return nonzero if PATTERN contains any metacharacters.
1135 Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
e7fd8a39
UD
1136int
1137__glob_pattern_p (pattern, quote)
28f540f4
RM
1138 const char *pattern;
1139 int quote;
1140{
1141 register const char *p;
1142 int open = 0;
1143
1144 for (p = pattern; *p != '\0'; ++p)
1145 switch (*p)
1146 {
1147 case '?':
1148 case '*':
1149 return 1;
1150
1151 case '\\':
299a95b9 1152 if (quote && p[1] != '\0')
28f540f4
RM
1153 ++p;
1154 break;
1155
1156 case '[':
1157 open = 1;
1158 break;
1159
1160 case ']':
1161 if (open)
1162 return 1;
1163 break;
1164 }
1165
1166 return 0;
1167}
a5f4e34a 1168# ifdef _LIBC
e7fd8a39 1169weak_alias (__glob_pattern_p, glob_pattern_p)
a5f4e34a 1170# endif
e7fd8a39 1171#endif
28f540f4
RM
1172
1173
1174/* Like `glob', but PATTERN is a final pathname component,
1175 and matches are searched for in DIRECTORY.
1176 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1177 The GLOB_APPEND flag is assumed to be set (always appends). */
1178static int
1179glob_in_dir (pattern, directory, flags, errfunc, pglob)
1180 const char *pattern;
1181 const char *directory;
1182 int flags;
1183 int (*errfunc) __P ((const char *, int));
1184 glob_t *pglob;
1185{
a9ddb793 1186 __ptr_t stream = NULL;
28f540f4
RM
1187
1188 struct globlink
1189 {
1190 struct globlink *next;
1191 char *name;
1192 };
1193 struct globlink *names = NULL;
86187531
UD
1194 size_t nfound;
1195 int meta;
1196 int save;
1197
a9ddb793
UD
1198 meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
1199 if (meta == 0)
28f540f4 1200 {
a9ddb793
UD
1201 if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
1202 /* We need not do any tests. The PATTERN contains no meta
1203 characters and we must not return an error therefore the
786a5421 1204 result will always contain exactly one name. */
a9ddb793
UD
1205 flags |= GLOB_NOCHECK;
1206 else
1207 {
1208 /* Since we use the normal file functions we can also use stat()
1209 to verify the file is there. */
1210 struct stat st;
1211 size_t patlen = strlen (pattern);
1212 size_t dirlen = strlen (directory);
786a5421 1213 char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
a9ddb793
UD
1214
1215# ifdef HAVE_MEMPCPY
1216 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1217 "/", 1),
1218 pattern, patlen + 1);
1219# else
1220 memcpy (fullname, directory, dirlen);
1221 fullname[dirlen] = '/';
1222 memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
1223# endif
1224 if (((flags & GLOB_ALTDIRFUNC)
1225 ? (*pglob->gl_stat) (fullname, &st)
1226 : __stat (fullname, &st)) == 0)
786a5421 1227 /* We found this file to be existing. Now tell the rest
a9ddb793
UD
1228 of the function to copy this name into the result. */
1229 flags |= GLOB_NOCHECK;
1230 }
1231
86187531 1232 nfound = 0;
28f540f4
RM
1233 }
1234 else
1235 {
a9ddb793 1236 if (pattern[0] == '\0')
28f540f4 1237 {
a9ddb793
UD
1238 /* This is a special case for matching directories like in
1239 "*a/". */
1240 names = (struct globlink *) __alloca (sizeof (struct globlink));
1241 names->name = (char *) malloc (1);
1242 if (names->name == NULL)
1243 goto memory_error;
1244 names->name[0] = '\0';
1245 names->next = NULL;
1246 nfound = 1;
1247 meta = 0;
1248 }
1249 else
1250 {
1251 stream = ((flags & GLOB_ALTDIRFUNC)
1252 ? (*pglob->gl_opendir) (directory)
1253 : (__ptr_t) opendir (directory));
1254 if (stream == NULL)
1255 {
1256 if ((errfunc != NULL && (*errfunc) (directory, errno))
1257 || (flags & GLOB_ERR))
1258 return GLOB_ABORTED;
1259 nfound = 0;
1260 meta = 0;
1261 }
1262 else
1263 {
1264 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1265 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1266#if defined _AMIGA || defined VMS
1267 | FNM_CASEFOLD
1268#endif
1269 );
1270 nfound = 0;
1271 flags |= GLOB_MAGCHAR;
1272
1273 while (1)
1274 {
1275 const char *name;
1276 size_t len;
1277 struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
1278 ? (*pglob->gl_readdir) (stream)
1279 : readdir ((DIR *) stream));
1280 if (d == NULL)
1281 break;
1282 if (! REAL_DIR_ENTRY (d))
1283 continue;
787e4db9 1284
1cab5444 1285#ifdef HAVE_D_TYPE
a9ddb793
UD
1286 /* If we shall match only directories use the information
1287 provided by the dirent call if possible. */
1288 if ((flags & GLOB_ONLYDIR)
1289 && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
1290 continue;
1cab5444
UD
1291#endif
1292
a9ddb793 1293 name = d->d_name;
86187531 1294
a9ddb793
UD
1295 if (fnmatch (pattern, name, fnm_flags) == 0)
1296 {
1297 struct globlink *new = (struct globlink *)
1298 __alloca (sizeof (struct globlink));
1299 len = NAMLEN (d);
1300 new->name = (char *) malloc (len + 1);
1301 if (new->name == NULL)
1302 goto memory_error;
dd7d45e8 1303#ifdef HAVE_MEMPCPY
a9ddb793
UD
1304 *((char *) mempcpy ((__ptr_t) new->name, name, len))
1305 = '\0';
dd7d45e8 1306#else
a9ddb793
UD
1307 memcpy ((__ptr_t) new->name, name, len);
1308 new->name[len] = '\0';
dd7d45e8 1309#endif
a9ddb793
UD
1310 new->next = names;
1311 names = new;
1312 ++nfound;
1313 }
1314 }
86187531
UD
1315 }
1316 }
28f540f4
RM
1317 }
1318
1319 if (nfound == 0 && (flags & GLOB_NOCHECK))
1320 {
1321 size_t len = strlen (pattern);
1322 nfound = 1;
1323 names = (struct globlink *) __alloca (sizeof (struct globlink));
1324 names->next = NULL;
a993273c 1325 names->name = (char *) malloc (len + 1);
28f540f4
RM
1326 if (names->name == NULL)
1327 goto memory_error;
dd7d45e8
UD
1328#ifdef HAVE_MEMPCPY
1329 *((char *) mempcpy (names->name, pattern, len)) = '\0';
1330#else
28f540f4 1331 memcpy (names->name, pattern, len);
28f540f4 1332 names->name[len] = '\0';
dd7d45e8 1333#endif
28f540f4
RM
1334 }
1335
61eb22d3
UD
1336 if (nfound != 0)
1337 {
1338 pglob->gl_pathv
1339 = (char **) realloc (pglob->gl_pathv,
1340 (pglob->gl_pathc +
1341 ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
1342 nfound + 1) *
1343 sizeof (char *));
1344 if (pglob->gl_pathv == NULL)
1345 goto memory_error;
28f540f4 1346
61eb22d3
UD
1347 if (flags & GLOB_DOOFFS)
1348 while (pglob->gl_pathc < pglob->gl_offs)
1349 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
28f540f4 1350
61eb22d3
UD
1351 for (; names != NULL; names = names->next)
1352 pglob->gl_pathv[pglob->gl_pathc++] = names->name;
1353 pglob->gl_pathv[pglob->gl_pathc] = NULL;
28f540f4 1354
61eb22d3
UD
1355 pglob->gl_flags = flags;
1356 }
28f540f4 1357
86187531 1358 save = errno;
a9ddb793 1359 if (stream != NULL)
6e4c40ba
UD
1360 {
1361 if (flags & GLOB_ALTDIRFUNC)
1362 (*pglob->gl_closedir) (stream);
1363 else
1364 closedir ((DIR *) stream);
1365 }
86187531
UD
1366 __set_errno (save);
1367
28f540f4
RM
1368 return nfound == 0 ? GLOB_NOMATCH : 0;
1369
1370 memory_error:
1371 {
1372 int save = errno;
787e4db9
RM
1373 if (flags & GLOB_ALTDIRFUNC)
1374 (*pglob->gl_closedir) (stream);
28f540f4 1375 else
faf92f2a 1376 closedir ((DIR *) stream);
c4029823 1377 __set_errno (save);
28f540f4
RM
1378 }
1379 while (names != NULL)
1380 {
1381 if (names->name != NULL)
1382 free ((__ptr_t) names->name);
1383 names = names->next;
1384 }
1385 return GLOB_NOSPACE;
1386}
1387
787e4db9 1388#endif /* Not ELIDE_CODE. */