Built win.arm64 against r3658
[kbuild-mirror.git] / src / kmk / glob / glob.c
blob98827cd6d79560afdf0ad945b15c23168bae5306
1 /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 Free
2 Software Foundation, Inc.
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the Free
16 Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
17 USA. */
19 /* AIX requires this to be the first thing in the file. */
20 #if defined _AIX && !defined __GNUC__
21 #pragma alloca
22 #endif
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
28 /* Enable GNU extensions in glob.h. */
29 #ifndef _GNU_SOURCE
30 # define _GNU_SOURCE 1
31 #endif
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
37 /* Outcomment the following line for production quality code. */
38 /* #define NDEBUG 1 */
39 #include <assert.h>
41 #include <stdio.h> /* Needed on stupid SunOS for assert. */
44 /* Comment out all this code if we are using the GNU C Library, and are not
45 actually compiling the library itself. This code is part of the GNU C
46 Library, but also included in many other GNU distributions. Compiling
47 and linking in this code is a waste when using the GNU C library
48 (especially if it is a shared library). Rather than having every GNU
49 program understand `configure --with-gnu-libc' and omit the object files,
50 it is simpler to just do this in the source for each such file. */
52 #define GLOB_INTERFACE_VERSION 1
53 #if 0 /* bird: Apparently this causes trouble for some debian builds. */
54 #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
55 # include <gnu-versions.h>
56 # if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
57 # define ELIDE_CODE
58 # endif
59 #endif
60 #endif
62 #ifndef ELIDE_CODE
64 #if defined STDC_HEADERS || defined __GNU_LIBRARY__
65 # include <stddef.h>
66 #endif
68 #if defined HAVE_UNISTD_H || defined _LIBC
69 # include <unistd.h>
70 # ifndef POSIX
71 # ifdef _POSIX_VERSION
72 # define POSIX
73 # endif
74 # endif
75 #endif
77 #if !defined _AMIGA && !defined VMS && !defined WINDOWS32
78 # include <pwd.h>
79 #endif
81 #if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS
82 extern int errno;
83 #endif
84 #ifndef __set_errno
85 # define __set_errno(val) errno = (val)
86 #endif
88 #ifndef NULL
89 # define NULL 0
90 #endif
93 #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
94 # include <dirent.h>
95 # define NAMLEN(dirent) strlen((dirent)->d_name)
96 #else
97 # define dirent direct
98 # define NAMLEN(dirent) (dirent)->d_namlen
99 # ifdef HAVE_SYS_NDIR_H
100 # include <sys/ndir.h>
101 # endif
102 # ifdef HAVE_SYS_DIR_H
103 # include <sys/dir.h>
104 # endif
105 # ifdef HAVE_NDIR_H
106 # include <ndir.h>
107 # endif
108 # ifdef HAVE_VMSDIR_H
109 # include "vmsdir.h"
110 # endif /* HAVE_VMSDIR_H */
111 #endif
114 /* In GNU systems, <dirent.h> defines this macro for us. */
115 #ifdef _D_NAMLEN
116 # undef NAMLEN
117 # define NAMLEN(d) _D_NAMLEN(d)
118 #endif
120 /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
121 if the `d_type' member for `struct dirent' is available. */
122 #ifdef _DIRENT_HAVE_D_TYPE
123 # define HAVE_D_TYPE 1
124 #endif
127 #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
128 /* Posix does not require that the d_ino field be present, and some
129 systems do not provide it. */
130 # define REAL_DIR_ENTRY(dp) 1
131 #else
132 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
133 #endif /* POSIX */
135 #if defined STDC_HEADERS || defined __GNU_LIBRARY__
136 # include <stdlib.h>
137 # include <string.h>
138 # define ANSI_STRING
139 #else /* No standard headers. */
141 extern char *getenv ();
143 # ifdef HAVE_STRING_H
144 # include <string.h>
145 # define ANSI_STRING
146 # else
147 # include <strings.h>
148 # endif
149 # ifdef HAVE_MEMORY_H
150 # include <memory.h>
151 # endif
153 extern char *malloc (), *realloc ();
154 extern void free ();
156 extern void qsort ();
157 extern void abort (), exit ();
159 #endif /* Standard headers. */
161 #ifndef ANSI_STRING
163 # ifndef bzero
164 extern void bzero ();
165 # endif
166 # ifndef bcopy
167 extern void bcopy ();
168 # endif
170 # define memcpy(d, s, n) bcopy ((s), (d), (n))
171 # define strrchr rindex
172 /* memset is only used for zero here, but let's be paranoid. */
173 # define memset(s, better_be_zero, n) \
174 ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
175 #endif /* Not ANSI_STRING. */
177 #if !defined HAVE_STRCOLL && !defined _LIBC
178 # define strcoll strcmp
179 #endif
181 #if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1
182 # define HAVE_MEMPCPY 1
183 #if 0 /* bird: This messes with the electric.c heap (linux/amd64). Probably missing prototype, so int return. */
184 # undef mempcpy
185 # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
186 #endif
187 #endif
189 #if !defined __GNU_LIBRARY__ && !defined __DJGPP__ && !defined ELECTRIC_HEAP && !defined __APPLE__ /* bird (last two) */
190 # ifdef __GNUC__
191 __inline
192 # endif
193 # ifndef __SASC
194 # ifdef WINDOWS32
195 # include <malloc.h>
196 static void *
197 my_realloc (void *p, unsigned int n)
198 # else
199 static char *
200 my_realloc (p, n)
201 char *p;
202 unsigned int n;
203 # endif
205 /* These casts are the for sake of the broken Ultrix compiler,
206 which warns of illegal pointer combinations otherwise. */
207 if (p == NULL)
208 return (char *) malloc (n);
209 return (char *) realloc (p, n);
211 # define realloc my_realloc
212 # endif /* __SASC */
213 #endif /* __GNU_LIBRARY__ || __DJGPP__ */
216 #if !defined __alloca /*&& !defined __GNU_LIBRARY__ - bird: unresolved __alloca symbol if skipping this for gnu libc. duh. */
218 # ifdef __GNUC__
219 # undef alloca
220 # define alloca(n) __builtin_alloca (n)
221 # else /* Not GCC. */
222 # ifdef HAVE_ALLOCA_H
223 # include <alloca.h>
224 # else /* Not HAVE_ALLOCA_H. */
225 # ifndef _AIX
226 # ifdef WINDOWS32
227 # include <malloc.h>
228 # else
229 extern char *alloca ();
230 # endif /* WINDOWS32 */
231 # endif /* Not _AIX. */
232 # endif /* sparc or HAVE_ALLOCA_H. */
233 # endif /* Not GCC. */
235 # define __alloca alloca
237 #endif
239 #if 1 /*bird: sigh. ndef __GNU_LIBRARY__*/
240 # define __stat stat
241 # ifdef STAT_MACROS_BROKEN
242 # undef S_ISDIR
243 # endif
244 # ifndef S_ISDIR
245 # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
246 # endif
247 #endif
249 #ifdef _LIBC
250 # ifdef KMK
251 # error "_LIBC better not be defined!"
252 # endif
253 # undef strdup
254 # define strdup(str) __strdup (str)
255 # define sysconf(id) __sysconf (id)
256 # define closedir(dir) __closedir (dir)
257 # define opendir(name) __opendir (name)
258 # define readdir(str) __readdir (str)
259 # define getpwnam_r(name, bufp, buf, len, res) \
260 __getpwnam_r (name, bufp, buf, len, res)
261 # ifndef __stat
262 # define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
263 # endif
264 #endif
266 #if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
267 # undef size_t
268 # define size_t unsigned int
269 #endif
271 /* Some system header files erroneously define these.
272 We want our own definitions from <fnmatch.h> to take precedence. */
273 #ifndef __GNU_LIBRARY__
274 # undef FNM_PATHNAME
275 # undef FNM_NOESCAPE
276 # undef FNM_PERIOD
277 #endif
278 #include <fnmatch.h>
280 /* Some system header files erroneously define these.
281 We want our own definitions from <glob.h> to take precedence. */
282 #ifndef __GNU_LIBRARY__
283 # undef GLOB_ERR
284 # undef GLOB_MARK
285 # undef GLOB_NOSORT
286 # undef GLOB_DOOFFS
287 # undef GLOB_NOCHECK
288 # undef GLOB_APPEND
289 # undef GLOB_NOESCAPE
290 # undef GLOB_PERIOD
291 #endif
292 #include <glob.h>
294 #ifdef HAVE_GETLOGIN_R
295 extern int getlogin_r __P ((char *, size_t));
296 #else
297 extern char *getlogin __P ((void));
298 #endif
300 static
301 #if __GNUC__ - 0 >= 2
302 inline
303 #endif
304 const char *next_brace_sub __P ((const char *begin));
305 static int glob_in_dir __P ((const char *pattern, const char *directory,
306 int flags,
307 int (*errfunc) (const char *, int),
308 glob_t *pglob));
309 static int prefix_array __P ((const char *prefix, char **array, size_t n));
310 static int collated_compare __P ((const __ptr_t, const __ptr_t));
312 #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
313 int __glob_pattern_p __P ((const char *pattern, int quote));
314 #endif
316 /* Find the end of the sub-pattern in a brace expression. We define
317 this as an inline function if the compiler permits. */
318 static
319 #if __GNUC__ - 0 >= 2
320 inline
321 #endif
322 const char *
323 next_brace_sub (begin)
324 const char *begin;
326 unsigned int depth = 0;
327 const char *cp = begin;
329 while (1)
331 if (depth == 0)
333 if (*cp != ',' && *cp != '}' && *cp != '\0')
335 if (*cp == '{')
336 ++depth;
337 ++cp;
338 continue;
341 else
343 while (*cp != '\0' && (*cp != '}' || depth > 0))
345 if (*cp == '}')
346 --depth;
347 ++cp;
349 if (*cp == '\0')
350 /* An incorrectly terminated brace expression. */
351 return NULL;
353 continue;
355 break;
358 return cp;
361 /* Do glob searching for PATTERN, placing results in PGLOB.
362 The bits defined above may be set in FLAGS.
363 If a directory cannot be opened or read and ERRFUNC is not nil,
364 it is called with the pathname that caused the error, and the
365 `errno' value from the failing call; if it returns non-zero
366 `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
367 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
368 Otherwise, `glob' returns zero. */
370 glob (pattern, flags, errfunc, pglob)
371 const char *pattern;
372 int flags;
373 int (*errfunc) __P ((const char *, int));
374 glob_t *pglob;
376 const char *filename;
377 const char *dirname;
378 size_t dirlen;
379 int status;
380 __size_t oldcount; /* bird: correct type. */
382 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
384 __set_errno (EINVAL);
385 return -1;
388 /* POSIX requires all slashes to be matched. This means that with
389 a trailing slash we must match only directories. */
390 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
391 flags |= GLOB_ONLYDIR;
393 if (flags & GLOB_BRACE)
395 const char *begin = strchr (pattern, '{');
396 if (begin != NULL)
398 /* Allocate working buffer large enough for our work. Note that
399 we have at least an opening and closing brace. */
400 size_t firstc; /* bird: correct type. */
401 char *alt_start;
402 const char *p;
403 const char *next;
404 const char *rest;
405 size_t rest_len;
406 #ifdef __GNUC__
407 char onealt[strlen (pattern) - 1];
408 #else
409 char *onealt = (char *) malloc (strlen (pattern) - 1);
410 if (onealt == NULL)
412 if (!(flags & GLOB_APPEND))
413 globfree (pglob);
414 return GLOB_NOSPACE;
416 #endif
418 /* We know the prefix for all sub-patterns. */
419 #ifdef HAVE_MEMPCPY
420 alt_start = mempcpy (onealt, pattern, begin - pattern);
421 #else
422 memcpy (onealt, pattern, begin - pattern);
423 alt_start = &onealt[begin - pattern];
424 #endif
426 /* Find the first sub-pattern and at the same time find the
427 rest after the closing brace. */
428 next = next_brace_sub (begin + 1);
429 if (next == NULL)
431 /* It is an illegal expression. */
432 #ifndef __GNUC__
433 free (onealt);
434 #endif
435 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
438 /* Now find the end of the whole brace expression. */
439 rest = next;
440 while (*rest != '}')
442 rest = next_brace_sub (rest + 1);
443 if (rest == NULL)
445 /* It is an illegal expression. */
446 #ifndef __GNUC__
447 free (onealt);
448 #endif
449 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
452 /* Please note that we now can be sure the brace expression
453 is well-formed. */
454 rest_len = strlen (++rest) + 1;
456 /* We have a brace expression. BEGIN points to the opening {,
457 NEXT points past the terminator of the first element, and END
458 points past the final }. We will accumulate result names from
459 recursive runs for each brace alternative in the buffer using
460 GLOB_APPEND. */
462 if (!(flags & GLOB_APPEND))
464 /* This call is to set a new vector, so clear out the
465 vector so we can append to it. */
466 pglob->gl_pathc = 0;
467 pglob->gl_pathv = NULL;
469 firstc = pglob->gl_pathc;
471 p = begin + 1;
472 while (1)
474 int result;
476 /* Construct the new glob expression. */
477 #ifdef HAVE_MEMPCPY
478 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
479 #else
480 memcpy (alt_start, p, next - p);
481 memcpy (&alt_start[next - p], rest, rest_len);
482 #endif
484 result = glob (onealt,
485 ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
486 | GLOB_APPEND), errfunc, pglob);
488 /* If we got an error, return it. */
489 if (result && result != GLOB_NOMATCH)
491 #ifndef __GNUC__
492 free (onealt);
493 #endif
494 if (!(flags & GLOB_APPEND))
495 globfree (pglob);
496 return result;
499 if (*next == '}')
500 /* We saw the last entry. */
501 break;
503 p = next + 1;
504 next = next_brace_sub (p);
505 assert (next != NULL);
508 #ifndef __GNUC__
509 free (onealt);
510 #endif
512 if (pglob->gl_pathc != firstc)
513 /* We found some entries. */
514 return 0;
515 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
516 return GLOB_NOMATCH;
520 /* Find the filename. */
521 filename = strrchr (pattern, '/');
522 #if defined __MSDOS__ || defined WINDOWS32
523 /* The case of "d:pattern". Since `:' is not allowed in
524 file names, we can safely assume that wherever it
525 happens in pattern, it signals the filename part. This
526 is so we could some day support patterns like "[a-z]:foo". */
527 if (filename == NULL)
528 filename = strchr (pattern, ':');
529 #endif /* __MSDOS__ || WINDOWS32 */
530 if (filename == NULL)
532 /* This can mean two things: a simple name or "~name". The later
533 case is nothing but a notation for a directory. */
534 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
536 dirname = pattern;
537 dirlen = strlen (pattern);
539 /* Set FILENAME to NULL as a special flag. This is ugly but
540 other solutions would require much more code. We test for
541 this special case below. */
542 filename = NULL;
544 else
546 filename = pattern;
547 #ifdef _AMIGA
548 dirname = "";
549 #else
550 dirname = ".";
551 #endif
552 dirlen = 0;
555 else if (filename == pattern)
557 /* "/pattern". */
558 dirname = "/";
559 dirlen = 1;
560 ++filename;
562 else
564 char *newp;
565 dirlen = filename - pattern;
566 #if defined __MSDOS__ || defined WINDOWS32
567 if (*filename == ':'
568 || (filename > pattern + 1 && filename[-1] == ':'))
570 char *drive_spec;
572 ++dirlen;
573 drive_spec = (char *) __alloca (dirlen + 1);
574 #ifdef HAVE_MEMPCPY
575 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
576 #else
577 memcpy (drive_spec, pattern, dirlen);
578 drive_spec[dirlen] = '\0';
579 #endif
580 /* For now, disallow wildcards in the drive spec, to
581 prevent infinite recursion in glob. */
582 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
583 return GLOB_NOMATCH;
584 /* If this is "d:pattern", we need to copy `:' to DIRNAME
585 as well. If it's "d:/pattern", don't remove the slash
586 from "d:/", since "d:" and "d:/" are not the same.*/
588 #endif
589 newp = (char *) __alloca (dirlen + 1);
590 #ifdef HAVE_MEMPCPY
591 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
592 #else
593 memcpy (newp, pattern, dirlen);
594 newp[dirlen] = '\0';
595 #endif
596 dirname = newp;
597 ++filename;
599 if (filename[0] == '\0'
600 #if defined __MSDOS__ || defined WINDOWS32
601 && dirname[dirlen - 1] != ':'
602 && (dirlen < 3 || dirname[dirlen - 2] != ':'
603 || dirname[dirlen - 1] != '/')
604 #endif
605 && dirlen > 1)
606 /* "pattern/". Expand "pattern", appending slashes. */
608 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
609 if (val == 0)
610 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
611 | (flags & GLOB_MARK));
612 return val;
616 if (!(flags & GLOB_APPEND))
618 pglob->gl_pathc = 0;
619 pglob->gl_pathv = NULL;
622 oldcount = pglob->gl_pathc;
624 #ifndef VMS
625 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
627 if (dirname[1] == '\0' || dirname[1] == '/')
629 /* Look up home directory. */
630 #ifdef VMS
631 /* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */
632 const char *home_dir = getenv ("SYS$LOGIN");
633 #else
634 const char *home_dir = getenv ("HOME");
635 #endif
636 # ifdef _AMIGA
637 if (home_dir == NULL || home_dir[0] == '\0')
638 home_dir = "SYS:";
639 # else
640 # ifdef WINDOWS32
641 if (home_dir == NULL || home_dir[0] == '\0')
642 home_dir = "c:/users/default"; /* poor default */
643 # else
644 # ifdef VMS
645 /* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */
646 if (home_dir == NULL || home_dir[0] == '\0')
647 home_dir = "SYS$DISK:[]";
648 # else
649 if (home_dir == NULL || home_dir[0] == '\0')
651 int success;
652 char *name;
653 # if defined HAVE_GETLOGIN_R || defined _LIBC
654 size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
656 if (buflen == 0)
657 /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
658 a moderate value. */
659 buflen = 20;
660 name = (char *) __alloca (buflen);
662 success = getlogin_r (name, buflen) >= 0;
663 # else
664 success = (name = getlogin ()) != NULL;
665 # endif
666 if (success)
668 struct passwd *p;
669 # if defined HAVE_GETPWNAM_R || defined _LIBC
670 size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
671 char *pwtmpbuf;
672 struct passwd pwbuf;
673 int save = errno;
675 if (pwbuflen == -1)
676 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
677 Try a moderate value. */
678 pwbuflen = 1024;
679 pwtmpbuf = (char *) __alloca (pwbuflen);
681 while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
682 != 0)
684 if (errno != ERANGE)
686 p = NULL;
687 break;
689 pwbuflen *= 2;
690 pwtmpbuf = (char *) __alloca (pwbuflen);
691 __set_errno (save);
693 # else
694 p = getpwnam (name);
695 # endif
696 if (p != NULL)
697 home_dir = p->pw_dir;
700 if (home_dir == NULL || home_dir[0] == '\0')
702 if (flags & GLOB_TILDE_CHECK)
703 return GLOB_NOMATCH;
704 else
705 home_dir = "~"; /* No luck. */
707 # endif /* VMS */
708 # endif /* WINDOWS32 */
709 # endif
710 /* Now construct the full directory. */
711 if (dirname[1] == '\0')
712 dirname = home_dir;
713 else
715 char *newp;
716 size_t home_len = strlen (home_dir);
717 newp = (char *) __alloca (home_len + dirlen);
718 # ifdef HAVE_MEMPCPY
719 mempcpy (mempcpy (newp, home_dir, home_len),
720 &dirname[1], dirlen);
721 # else
722 memcpy (newp, home_dir, home_len);
723 memcpy (&newp[home_len], &dirname[1], dirlen);
724 # endif
725 dirname = newp;
728 # if !defined _AMIGA && !defined WINDOWS32 && !defined VMS
729 else
731 char *end_name = strchr (dirname, '/');
732 const char *user_name;
733 const char *home_dir;
735 if (end_name == NULL)
736 user_name = dirname + 1;
737 else
739 char *newp;
740 newp = (char *) __alloca (end_name - dirname);
741 # ifdef HAVE_MEMPCPY
742 *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
743 = '\0';
744 # else
745 memcpy (newp, dirname + 1, end_name - dirname);
746 newp[end_name - dirname - 1] = '\0';
747 # endif
748 user_name = newp;
751 /* Look up specific user's home directory. */
753 struct passwd *p;
754 # if defined HAVE_GETPWNAM_R || defined _LIBC
755 size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
756 char *pwtmpbuf;
757 struct passwd pwbuf;
758 int save = errno;
760 if (buflen == -1)
761 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
762 moderate value. */
763 buflen = 1024;
764 pwtmpbuf = (char *) __alloca (buflen);
766 while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
768 if (errno != ERANGE)
770 p = NULL;
771 break;
773 buflen *= 2;
774 pwtmpbuf = __alloca (buflen);
775 __set_errno (save);
777 # else
778 p = getpwnam (user_name);
779 # endif
780 if (p != NULL)
781 home_dir = p->pw_dir;
782 else
783 home_dir = NULL;
785 /* If we found a home directory use this. */
786 if (home_dir != NULL)
788 char *newp;
789 size_t home_len = strlen (home_dir);
790 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
791 newp = (char *) __alloca (home_len + rest_len + 1);
792 # ifdef HAVE_MEMPCPY
793 *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
794 end_name, rest_len)) = '\0';
795 # else
796 memcpy (newp, home_dir, home_len);
797 memcpy (&newp[home_len], end_name, rest_len);
798 newp[home_len + rest_len] = '\0';
799 # endif
800 dirname = newp;
802 else
803 if (flags & GLOB_TILDE_CHECK)
804 /* We have to regard it as an error if we cannot find the
805 home directory. */
806 return GLOB_NOMATCH;
808 # endif /* Not Amiga && not WINDOWS32 && not VMS. */
810 #endif /* Not VMS. */
812 /* Now test whether we looked for "~" or "~NAME". In this case we
813 can give the answer now. */
814 if (filename == NULL)
816 struct stat st;
818 /* Return the directory if we don't check for error or if it exists. */
819 if ((flags & GLOB_NOCHECK)
820 #ifdef KMK
821 || (flags & GLOB_ALTDIRFUNC
822 ? (*pglob->gl_isdir) (dirname)
823 : __stat (dirname, &st) == 0 && S_ISDIR (st.st_mode))
824 #else
825 || (((flags & GLOB_ALTDIRFUNC)
826 ? (*pglob->gl_stat) (dirname, &st)
827 : __stat (dirname, &st)) == 0
828 && S_ISDIR (st.st_mode))
829 #endif
832 pglob->gl_pathv
833 = (char **) realloc (pglob->gl_pathv,
834 (pglob->gl_pathc +
835 ((flags & GLOB_DOOFFS) ?
836 pglob->gl_offs : 0) +
837 1 + 1) *
838 sizeof (char *));
839 if (pglob->gl_pathv == NULL)
840 return GLOB_NOSPACE;
842 if (flags & GLOB_DOOFFS)
843 while (pglob->gl_pathc < pglob->gl_offs)
844 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
846 #if defined HAVE_STRDUP || defined _LIBC
847 pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
848 #else
850 size_t len = strlen (dirname) + 1;
851 char *dircopy = malloc (len);
852 if (dircopy != NULL)
853 pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
854 len);
856 #endif
857 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
859 free (pglob->gl_pathv);
860 return GLOB_NOSPACE;
862 pglob->gl_pathv[++pglob->gl_pathc] = NULL;
863 pglob->gl_flags = flags;
865 return 0;
868 /* Not found. */
869 return GLOB_NOMATCH;
872 if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
874 /* The directory name contains metacharacters, so we
875 have to glob for the directory, and then glob for
876 the pattern in each directory found. */
877 glob_t dirs;
878 register __size_t i; /* bird: correct type. */
880 status = glob (dirname,
881 ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
882 | GLOB_NOSORT | GLOB_ONLYDIR),
883 errfunc, &dirs);
884 if (status != 0)
885 return status;
887 /* We have successfully globbed the preceding directory name.
888 For each name we found, call glob_in_dir on it and FILENAME,
889 appending the results to PGLOB. */
890 for (i = 0; i < dirs.gl_pathc; ++i)
892 int old_pathc;
894 #ifdef SHELL
896 /* Make globbing interruptible in the bash shell. */
897 extern int interrupt_state;
899 if (interrupt_state)
901 globfree (&dirs);
902 globfree (&files);
903 return GLOB_ABORTED;
906 #endif /* SHELL. */
908 old_pathc = pglob->gl_pathc;
909 status = glob_in_dir (filename, dirs.gl_pathv[i],
910 ((flags | GLOB_APPEND)
911 & ~(GLOB_NOCHECK | GLOB_ERR)),
912 errfunc, pglob);
913 if (status == GLOB_NOMATCH)
914 /* No matches in this directory. Try the next. */
915 continue;
917 if (status != 0)
919 globfree (&dirs);
920 globfree (pglob);
921 return status;
924 /* Stick the directory on the front of each name. */
925 if (prefix_array (dirs.gl_pathv[i],
926 &pglob->gl_pathv[old_pathc],
927 pglob->gl_pathc - old_pathc))
929 globfree (&dirs);
930 globfree (pglob);
931 return GLOB_NOSPACE;
935 flags |= GLOB_MAGCHAR;
937 /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
938 But if we have not found any matching entry and thie GLOB_NOCHECK
939 flag was set we must return the list consisting of the disrectory
940 names followed by the filename. */
941 if (pglob->gl_pathc == oldcount)
943 /* No matches. */
944 if (flags & GLOB_NOCHECK)
946 size_t filename_len = strlen (filename) + 1;
947 char **new_pathv;
948 struct stat st;
950 /* This is an pessimistic guess about the size. */
951 pglob->gl_pathv
952 = (char **) realloc (pglob->gl_pathv,
953 (pglob->gl_pathc +
954 ((flags & GLOB_DOOFFS) ?
955 pglob->gl_offs : 0) +
956 dirs.gl_pathc + 1) *
957 sizeof (char *));
958 if (pglob->gl_pathv == NULL)
960 globfree (&dirs);
961 return GLOB_NOSPACE;
964 if (flags & GLOB_DOOFFS)
965 while (pglob->gl_pathc < pglob->gl_offs)
966 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
968 for (i = 0; i < dirs.gl_pathc; ++i)
970 const char *dir = dirs.gl_pathv[i];
971 size_t dir_len = strlen (dir);
973 /* First check whether this really is a directory. */
974 #ifdef KMK
975 if (flags & GLOB_ALTDIRFUNC
976 ? !pglob->gl_isdir (dir)
977 : __stat (dir, &st) != 0 || !S_ISDIR (st.st_mode))
978 #else
979 if (((flags & GLOB_ALTDIRFUNC)
980 ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
981 || !S_ISDIR (st.st_mode))
982 #endif
983 /* No directory, ignore this entry. */
984 continue;
986 pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
987 + filename_len);
988 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
990 globfree (&dirs);
991 globfree (pglob);
992 return GLOB_NOSPACE;
995 #ifdef HAVE_MEMPCPY
996 mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
997 dir, dir_len),
998 "/", 1),
999 filename, filename_len);
1000 #else
1001 memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
1002 pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
1003 memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
1004 filename, filename_len);
1005 #endif
1006 ++pglob->gl_pathc;
1009 pglob->gl_pathv[pglob->gl_pathc] = NULL;
1010 pglob->gl_flags = flags;
1012 /* Now we know how large the gl_pathv vector must be. */
1013 new_pathv = (char **) realloc (pglob->gl_pathv,
1014 ((pglob->gl_pathc + 1)
1015 * sizeof (char *)));
1016 if (new_pathv != NULL)
1017 pglob->gl_pathv = new_pathv;
1019 else
1020 return GLOB_NOMATCH;
1023 globfree (&dirs);
1025 else
1027 status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
1028 if (status != 0)
1029 return status;
1031 if (dirlen > 0)
1033 /* Stick the directory on the front of each name. */
1034 __size_t ignore = oldcount; /* bird: correct type. */
1036 if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs)
1037 ignore = pglob->gl_offs;
1039 if (prefix_array (dirname,
1040 &pglob->gl_pathv[ignore],
1041 pglob->gl_pathc - ignore))
1043 globfree (pglob);
1044 return GLOB_NOSPACE;
1049 if (flags & GLOB_MARK)
1051 /* Append slashes to directory names. */
1052 __size_t i; /* bird: correct type. */
1053 struct stat st;
1054 for (i = oldcount; i < pglob->gl_pathc; ++i)
1055 #ifdef KMK
1056 if (flags & GLOB_ALTDIRFUNC
1057 ? pglob->gl_isdir (pglob->gl_pathv[i])
1058 : __stat (pglob->gl_pathv[i], &st) == 0 && S_ISDIR (st.st_mode) )
1059 #else
1060 if (((flags & GLOB_ALTDIRFUNC)
1061 ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
1062 : __stat (pglob->gl_pathv[i], &st)) == 0
1063 && S_ISDIR (st.st_mode))
1064 #endif
1066 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1067 char *new = realloc (pglob->gl_pathv[i], len);
1068 if (new == NULL)
1070 globfree (pglob);
1071 return GLOB_NOSPACE;
1073 strcpy (&new[len - 2], "/");
1074 pglob->gl_pathv[i] = new;
1078 if (!(flags & GLOB_NOSORT))
1080 /* Sort the vector. */
1081 int non_sort = oldcount;
1083 if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount)
1084 non_sort = pglob->gl_offs;
1086 qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
1087 pglob->gl_pathc - non_sort,
1088 sizeof (char *), collated_compare);
1091 return 0;
1095 /* Free storage allocated in PGLOB by a previous `glob' call. */
1096 void
1097 globfree (pglob)
1098 register glob_t *pglob;
1100 if (pglob->gl_pathv != NULL)
1102 register __size_t i; /* bird: correct type */
1103 for (i = 0; i < pglob->gl_pathc; ++i)
1104 if (pglob->gl_pathv[i] != NULL)
1105 free ((__ptr_t) pglob->gl_pathv[i]);
1106 free ((__ptr_t) pglob->gl_pathv);
1111 /* Do a collated comparison of A and B. */
1112 static int
1113 collated_compare (a, b)
1114 const __ptr_t a;
1115 const __ptr_t b;
1117 const char *const s1 = *(const char *const * const) a;
1118 const char *const s2 = *(const char *const * const) b;
1120 if (s1 == s2)
1121 return 0;
1122 if (s1 == NULL)
1123 return 1;
1124 if (s2 == NULL)
1125 return -1;
1126 return strcoll (s1, s2);
1130 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1131 elements in place. Return nonzero if out of memory, zero if successful.
1132 A slash is inserted between DIRNAME and each elt of ARRAY,
1133 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1134 static int
1135 prefix_array (dirname, array, n)
1136 const char *dirname;
1137 char **array;
1138 size_t n;
1140 register size_t i;
1141 size_t dirlen = strlen (dirname);
1142 #if defined __MSDOS__ || defined WINDOWS32
1143 int sep_char = '/';
1144 # define DIRSEP_CHAR sep_char
1145 #else
1146 # define DIRSEP_CHAR '/'
1147 #endif
1149 if (dirlen == 1 && dirname[0] == '/')
1150 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1151 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1152 dirlen = 0;
1153 #if defined __MSDOS__ || defined WINDOWS32
1154 else if (dirlen > 1)
1156 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1157 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1158 --dirlen;
1159 else if (dirname[dirlen - 1] == ':')
1161 /* DIRNAME is "d:". Use `:' instead of `/'. */
1162 --dirlen;
1163 sep_char = ':';
1166 #endif
1168 for (i = 0; i < n; ++i)
1170 size_t eltlen = strlen (array[i]) + 1;
1171 char *new = (char *) malloc (dirlen + 1 + eltlen);
1172 if (new == NULL)
1174 while (i > 0)
1175 free ((__ptr_t) array[--i]);
1176 return 1;
1179 #ifdef HAVE_MEMPCPY
1181 char *endp = (char *) mempcpy (new, dirname, dirlen);
1182 *endp++ = DIRSEP_CHAR;
1183 mempcpy (endp, array[i], eltlen);
1185 #else
1186 memcpy (new, dirname, dirlen);
1187 new[dirlen] = DIRSEP_CHAR;
1188 memcpy (&new[dirlen + 1], array[i], eltlen);
1189 #endif
1190 free ((__ptr_t) array[i]);
1191 array[i] = new;
1194 return 0;
1198 /* We must not compile this function twice. */
1199 #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
1200 /* Return nonzero if PATTERN contains any metacharacters.
1201 Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
1203 __glob_pattern_p (pattern, quote)
1204 const char *pattern;
1205 int quote;
1207 register const char *p;
1208 int open = 0;
1210 for (p = pattern; *p != '\0'; ++p)
1211 switch (*p)
1213 case '?':
1214 case '*':
1215 return 1;
1217 case '\\':
1218 if (quote && p[1] != '\0')
1219 ++p;
1220 break;
1222 case '[':
1223 open = 1;
1224 break;
1226 case ']':
1227 if (open)
1228 return 1;
1229 break;
1232 return 0;
1234 # ifdef _LIBC
1235 weak_alias (__glob_pattern_p, glob_pattern_p)
1236 # endif
1237 #endif
1240 /* Like `glob', but PATTERN is a final pathname component,
1241 and matches are searched for in DIRECTORY.
1242 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1243 The GLOB_APPEND flag is assumed to be set (always appends). */
1244 static int
1245 glob_in_dir (pattern, directory, flags, errfunc, pglob)
1246 const char *pattern;
1247 const char *directory;
1248 int flags;
1249 int (*errfunc) __P ((const char *, int));
1250 glob_t *pglob;
1252 __ptr_t stream = NULL;
1254 struct globlink
1256 struct globlink *next;
1257 char *name;
1259 struct globlink *names = NULL;
1260 size_t nfound;
1261 int meta;
1262 int save;
1264 #ifdef VMS
1265 if (*directory == 0)
1266 directory = "[]";
1267 #endif
1268 meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
1269 if (meta == 0)
1271 if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
1272 /* We need not do any tests. The PATTERN contains no meta
1273 characters and we must not return an error therefore the
1274 result will always contain exactly one name. */
1275 flags |= GLOB_NOCHECK;
1276 else
1278 /* Since we use the normal file functions we can also use stat()
1279 to verify the file is there. */
1280 struct stat st;
1281 size_t patlen = strlen (pattern);
1282 size_t dirlen = strlen (directory);
1283 char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
1285 # ifdef HAVE_MEMPCPY
1286 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1287 "/", 1),
1288 pattern, patlen + 1);
1289 # else
1290 memcpy (fullname, directory, dirlen);
1291 fullname[dirlen] = '/';
1292 memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
1293 # endif
1294 # ifdef KMK
1295 if (flags & GLOB_ALTDIRFUNC ? pglob->gl_exists (fullname) : __stat (fullname, &st) == 0)
1296 # else
1297 if (((flags & GLOB_ALTDIRFUNC)
1298 ? (*pglob->gl_stat) (fullname, &st)
1299 : __stat (fullname, &st)) == 0)
1300 # endif
1301 /* We found this file to be existing. Now tell the rest
1302 of the function to copy this name into the result. */
1303 flags |= GLOB_NOCHECK;
1306 nfound = 0;
1308 else
1310 if (pattern[0] == '\0')
1312 /* This is a special case for matching directories like in
1313 "*a/". */
1314 names = (struct globlink *) __alloca (sizeof (struct globlink));
1315 names->name = (char *) malloc (1);
1316 if (names->name == NULL)
1317 goto memory_error;
1318 names->name[0] = '\0';
1319 names->next = NULL;
1320 nfound = 1;
1321 meta = 0;
1323 else
1325 stream = ((flags & GLOB_ALTDIRFUNC)
1326 ? (*pglob->gl_opendir) (directory)
1327 : (__ptr_t) opendir (directory));
1328 if (stream == NULL)
1330 if (errno != ENOTDIR
1331 && ((errfunc != NULL && (*errfunc) (directory, errno))
1332 || (flags & GLOB_ERR)))
1333 return GLOB_ABORTED;
1334 nfound = 0;
1335 meta = 0;
1337 else
1339 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1340 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1341 #if defined HAVE_CASE_INSENSITIVE_FS
1342 | FNM_CASEFOLD
1343 #endif
1345 nfound = 0;
1346 flags |= GLOB_MAGCHAR;
1348 while (1)
1350 const char *name;
1351 size_t len;
1352 struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
1353 ? (*pglob->gl_readdir) (stream)
1354 : readdir ((DIR *) stream));
1355 if (d == NULL)
1356 break;
1357 if (! REAL_DIR_ENTRY (d))
1358 continue;
1360 #ifdef HAVE_D_TYPE
1361 /* If we shall match only directories use the information
1362 provided by the dirent call if possible. */
1363 if ((flags & GLOB_ONLYDIR)
1364 && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
1365 continue;
1366 #endif
1368 name = d->d_name;
1370 if (fnmatch (pattern, name, fnm_flags) == 0)
1372 struct globlink *new = (struct globlink *)
1373 __alloca (sizeof (struct globlink));
1374 len = NAMLEN (d);
1375 new->name = (char *) malloc (len + 1);
1376 if (new->name == NULL)
1377 goto memory_error;
1378 #ifdef HAVE_MEMPCPY
1379 *((char *) mempcpy ((__ptr_t) new->name, name, len))
1380 = '\0';
1381 #else
1382 memcpy ((__ptr_t) new->name, name, len);
1383 new->name[len] = '\0';
1384 #endif
1385 new->next = names;
1386 names = new;
1387 ++nfound;
1394 if (nfound == 0 && (flags & GLOB_NOCHECK))
1396 size_t len = strlen (pattern);
1397 nfound = 1;
1398 names = (struct globlink *) __alloca (sizeof (struct globlink));
1399 names->next = NULL;
1400 names->name = (char *) malloc (len + 1);
1401 if (names->name == NULL)
1402 goto memory_error;
1403 #ifdef HAVE_MEMPCPY
1404 *((char *) mempcpy (names->name, pattern, len)) = '\0';
1405 #else
1406 memcpy (names->name, pattern, len);
1407 names->name[len] = '\0';
1408 #endif
1411 if (nfound != 0)
1413 pglob->gl_pathv
1414 = (char **) realloc (pglob->gl_pathv,
1415 (pglob->gl_pathc +
1416 ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
1417 nfound + 1) *
1418 sizeof (char *));
1419 if (pglob->gl_pathv == NULL)
1420 goto memory_error;
1422 if (flags & GLOB_DOOFFS)
1423 while (pglob->gl_pathc < pglob->gl_offs)
1424 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
1426 for (; names != NULL; names = names->next)
1427 pglob->gl_pathv[pglob->gl_pathc++] = names->name;
1428 pglob->gl_pathv[pglob->gl_pathc] = NULL;
1430 pglob->gl_flags = flags;
1433 save = errno;
1434 if (stream != NULL)
1436 if (flags & GLOB_ALTDIRFUNC)
1437 (*pglob->gl_closedir) (stream);
1438 else
1439 closedir ((DIR *) stream);
1441 __set_errno (save);
1443 return nfound == 0 ? GLOB_NOMATCH : 0;
1445 memory_error:
1447 /*int*/ save = errno;
1448 if (flags & GLOB_ALTDIRFUNC)
1449 (*pglob->gl_closedir) (stream);
1450 else
1451 closedir ((DIR *) stream);
1452 __set_errno (save);
1454 while (names != NULL)
1456 if (names->name != NULL)
1457 free ((__ptr_t) names->name);
1458 names = names->next;
1460 return GLOB_NOSPACE;
1463 #endif /* Not ELIDE_CODE. */