VirtualBox

source: kBuild/vendor/gnumake/current/glob/glob.c

最後變更 在這個檔案是 3138,由 bird 提交於 7 年 前

Imported make 4.2.1 (2e55f5e4abdc0e38c1d64be703b446695e70b3b6) from https://git.savannah.gnu.org/git/make.git.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette