From: jbj Date: Sat, 11 Mar 2000 20:14:07 +0000 (+0000) Subject: fix: use glibc 2.1 glob/fnmatch everywhere. X-Git-Tag: rpm-4.4-release~2303 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bed2a465fe49ce05f9678e619d016a2d26649c98;p=platform%2Fupstream%2Frpm.git fix: use glibc 2.1 glob/fnmatch everywhere. CVS patchset: 3621 CVS date: 2000/03/11 20:14:07 --- diff --git a/CHANGES b/CHANGES index f8f881b..14a4802 100644 --- a/CHANGES +++ b/CHANGES @@ -69,8 +69,9 @@ - portability: always include arpa/inet.h (HP-UX). - portability: don't use id -u (Brandon Allbery). - portability: don't chown/chgrp -h w/o lchown. - - portability: splats in rpm.spec to find /usr/{share,local}/locale/* + - portability: splats in rpm.spec to find /usr/{share,lib}/locale/* . - fix: better filter in linux.req to avoid ARM specific objdump output. + - fix: use glibc 2.1 glob/fnmatch everywhere. 3.0.2 -> 3.0.3 - add --eval to find result of macro expansion. diff --git a/configure.in b/configure.in index 4b43dcd..3d6ef44 100644 --- a/configure.in +++ b/configure.in @@ -404,7 +404,7 @@ dnl whether or not we should try to build rpmgettext/rpmputtext. if test X"$USE_NLS" = Xyes; then BUILD_RPMNLSTOOLS="rpmgettext rpmputtext" if test X"$USE_INCLUDED_LIBINTL" = Xyes; then - INCPATH="$INCPATH -I\$(top_builddir)/intl" + INCPATH="-I\$(top_builddir)/intl $INCPATH" fi else BUILD_RPMNLSTOOLS= @@ -644,23 +644,26 @@ dnl LIBOBJS="$LIBOBJS regex.o" dnl fi dnl -dnl XXX Glob may be broken on solaris and aix when %files gets something like -dnl /usr/share/locale/*/LC_MESSAGES/*.mo -dnl (Note: two asterisks in glob pattern.) +dnl XXX Glob *is* broken on linux with libc5, solaris and possibly aix when +dnl %files gets something like +dnl /usr/*/locale/*/LC_MESSAGES/*.mo +dnl (Note: more than one asterisk in glob pattern.) +dnl The next version of rpm is going to need GNU extensions anyways, so ... dnl AC_ARG_WITH(glob, [ --with-glob use the internal GNU glob ], [rpm_cv_glob=yes], [AC_CHECK_FUNCS(glob, rpm_cv_glob=no, rpm_cv_glob=yes)]) if test $rpm_cv_glob = no ; then - AC_MSG_CHECKING(whether the glob library is broken) + AC_MSG_CHECKING(for GNU extensions to glob) AC_TRY_RUN([ #include +#include #include -main() { glob_t blah ; exit(glob("doc/*/*.8", 0, NULL, &blah) || blah.gl_pathc < 1); } ], - rpm_cv_glob_broken=no, rpm_cv_glob_broken=yes, rpm_cv_glob_broken=yes) - AC_MSG_RESULT([$rpm_cv_glob_broken]) - if test $rpm_cv_glob_broken = yes ; then +main() { glob_t blah ; blah.stat = stat; exit(glob("doc/*/*.8", 0, NULL, &blah) || blah.gl_pathc < 1); } ], + rpm_cv_glob_ext=yes, rpm_cv_glob_ext=no, rpm_cv_glob_ext=no) + AC_MSG_RESULT([$rpm_cv_glob_ext]) + if test $rpm_cv_glob_ext = no ; then echo " --> using the included GNU glob instead." >&AC_FD_MSG rpm_cv_glob=yes fi @@ -668,7 +671,7 @@ fi if test $rpm_cv_glob = yes; then AC_DEFINE(USE_GNU_GLOB) - LIBOBJS="$LIBOBJS glob.o" + LIBOBJS="$LIBOBJS glob.o fnmatch.o" fi AC_CHECK_FUNCS(setlocale) @@ -912,7 +915,7 @@ dnl AC_DEFINE_UNQUOTED(testdir, "$testdir") AC_SUBST(testdir) if test -n "$LIBOBJS"; then - INCPATH="$INCPATH -I\$(top_builddir)/misc" + INCPATH="-I\$(top_builddir)/misc $INCPATH" fi AC_SUBST(INCPATH) diff --git a/lib/stubs.c b/lib/stubs.c index 0908cb8..9a89691 100644 --- a/lib/stubs.c +++ b/lib/stubs.c @@ -71,5 +71,6 @@ #endif #if defined(USE_GNU_GLOB) +#include "misc/fnmatch.c" #include "misc/glob.c" #endif diff --git a/misc/fnmatch.c b/misc/fnmatch.c index e5570c2..7774bb4 100644 --- a/misc/fnmatch.c +++ b/misc/fnmatch.c @@ -16,28 +16,145 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if HAVE_CONFIG_H -# include -#endif +# include "system.h" -/* Enable GNU extensions in fnmatch.h. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif +/* Find the first occurrence of C in S or the final NUL byte. */ +static inline char * +__strchrnul (s, c) + const char *s; + int c; +{ + const unsigned char *char_ptr; + const unsigned long int *longword_ptr; + unsigned long int longword, magic_bits, charmask; -#include -#include -#include + c = (unsigned char) c; -#if HAVE_STRING_H || defined _LIBC -# include -#else -# include -#endif + /* Handle the first few characters by reading one character at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = s; ((unsigned long int) char_ptr + & (sizeof (longword) - 1)) != 0; + ++char_ptr) + if (*char_ptr == c || *char_ptr == '\0') + return (void *) char_ptr; -#if defined STDC_HEADERS || defined _LIBC -# include -#endif + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to 8-byte longwords. */ + + longword_ptr = (unsigned long int *) char_ptr; + + /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits + the "holes." Note that there is a hole just to the left of + each byte, with an extra at the end: + + bits: 01111110 11111110 11111110 11111111 + bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD + + The 1-bits make sure that carries propagate to the next 0-bit. + The 0-bits provide holes for carries to fall into. */ + switch (sizeof (longword)) + { + case 4: magic_bits = 0x7efefeffL; break; + case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break; + default: + abort (); + } + + /* Set up a longword, each of whose bytes is C. */ + charmask = c | (c << 8); + charmask |= charmask << 16; + if (sizeof (longword) > 4) + /* Do the shift in two steps to avoid a warning if long has 32 bits. */ + charmask |= (charmask << 16) << 16; + if (sizeof (longword) > 8) + abort (); + + /* Instead of the traditional loop which tests each character, + we will test a longword at a time. The tricky part is testing + if *any of the four* bytes in the longword in question are zero. */ + for (;;) + { + /* We tentatively exit the loop if adding MAGIC_BITS to + LONGWORD fails to change any of the hole bits of LONGWORD. + + 1) Is this safe? Will it catch all the zero bytes? + Suppose there is a byte with all zeros. Any carry bits + propagating from its left will fall into the hole at its + least significant bit and stop. Since there will be no + carry from its most significant bit, the LSB of the + byte to the left will be unchanged, and the zero will be + detected. + + 2) Is this worthwhile? Will it ignore everything except + zero bytes? Suppose every byte of LONGWORD has a bit set + somewhere. There will be a carry into bit 8. If bit 8 + is set, this will carry into bit 16. If bit 8 is clear, + one of bits 9-15 must be set, so there will be a carry + into bit 16. Similarly, there will be a carry into bit + 24. If one of bits 24-30 is set, there will be a carry + into bit 31, so all of the hole bits will be changed. + + The one misfire occurs when bits 24-30 are clear and bit + 31 is set; in this case, the hole at bit 31 is not + changed. If we had access to the processor carry flag, + we could close this loophole by putting the fourth hole + at bit 32! + + So it ignores everything except 128's, when they're aligned + properly. + + 3) But wait! Aren't we looking for C as well as zero? + Good point. So what we do is XOR LONGWORD with a longword, + each of whose bytes is C. This turns each byte that is C + into a zero. */ + + longword = *longword_ptr++; + + /* Add MAGIC_BITS to LONGWORD. */ + if ((((longword + magic_bits) + + /* Set those bits that were unchanged by the addition. */ + ^ ~longword) + + /* Look at only the hole bits. If any of the hole bits + are unchanged, most likely one of the bytes was a + zero. */ + & ~magic_bits) != 0 || + + /* That caught zeroes. Now test for C. */ + ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask)) + & ~magic_bits) != 0) + { + /* Which of the bytes was C or zero? + If none of them were, it was a misfire; continue the search. */ + + const unsigned char *cp = (const unsigned char *) (longword_ptr - 1); + + if (*cp == c || *cp == '\0') + return (char *) cp; + if (*++cp == c || *cp == '\0') + return (char *) cp; + if (*++cp == c || *cp == '\0') + return (char *) cp; + if (*++cp == c || *cp == '\0') + return (char *) cp; + if (sizeof (longword) > 4) + { + if (*++cp == c || *cp == '\0') + return (char *) cp; + if (*++cp == c || *cp == '\0') + return (char *) cp; + if (*++cp == c || *cp == '\0') + return (char *) cp; + if (*++cp == c || *cp == '\0') + return (char *) cp; + } + } + } + + /* This should never happen. */ + return NULL; +} /* For platform which support the ISO C amendement 1 functionality we support user defined character classes. */ diff --git a/misc/glob.c b/misc/glob.c index f4b49f2..7ee40d2 100644 --- a/misc/glob.c +++ b/misc/glob.c @@ -20,106 +20,13 @@ #pragma alloca #endif -#ifdef HAVE_CONFIG_H -# include -#endif - -/* Enable GNU extensions in glob.h. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#include -#include -#include - -/* Outcomment the following line for production quality code. */ -/* #define NDEBUG 1 */ -#include - -#include /* Needed on stupid SunOS for assert. */ - - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GLOB_INTERFACE_VERSION 1 -#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 -# include -# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#ifndef ELIDE_CODE - -#if defined STDC_HEADERS || defined __GNU_LIBRARY__ -# include -#endif - -#if defined HAVE_UNISTD_H || defined _LIBC -# include -# ifndef POSIX -# ifdef _POSIX_VERSION -# define POSIX -# endif -# endif -#endif - -#if !defined _AMIGA && !defined VMS && !defined WINDOWS32 -# include -#endif - -#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - -#ifndef NULL -# define NULL 0 -#endif - - -#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# ifdef HAVE_SYS_NDIR_H -# include -# endif -# ifdef HAVE_SYS_DIR_H -# include -# endif -# ifdef HAVE_NDIR_H -# include -# endif -# ifdef HAVE_VMSDIR_H -# include "vmsdir.h" -# endif /* HAVE_VMSDIR_H */ -#endif - +# include "system.h" -/* In GNU systems, defines this macro for us. */ -#ifdef _D_NAMLEN -# undef NAMLEN -# define NAMLEN(d) _D_NAMLEN(d) -#endif - -/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available - if the `d_type' member for `struct dirent' is available. */ -#ifdef _DIRENT_HAVE_D_TYPE -# define HAVE_D_TYPE 1 -#endif +# include +#define __alloca alloca +#define __stat stat +#define NAMLEN(_d) NLENGTH(_d) #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ /* Posix does not require that the d_ino field be present, and some @@ -129,169 +36,12 @@ extern int errno; # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif /* POSIX */ -#if defined STDC_HEADERS || defined __GNU_LIBRARY__ -# include -# include -# define ANSI_STRING -#else /* No standard headers. */ - -extern char *getenv (); - -# ifdef HAVE_STRING_H -# include -# define ANSI_STRING -# else -# include -# endif -# ifdef HAVE_MEMORY_H -# include -# endif - -extern char *malloc (), *realloc (); -extern void free (); - -extern void qsort (); -extern void abort (), exit (); - -#endif /* Standard headers. */ - -#ifdef HAVE_GETLOGIN_R -extern int getlogin_r __P ((char *, size_t)); -#else -extern char *getlogin __P ((void)); -#endif - -#ifndef ANSI_STRING - -# ifndef bzero -extern void bzero (); -# endif -# ifndef bcopy -extern void bcopy (); -# endif - -# define memcpy(d, s, n) bcopy ((s), (d), (n)) -# define strrchr rindex -/* memset is only used for zero here, but let's be paranoid. */ -# define memset(s, better_be_zero, n) \ - ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) -#endif /* Not ANSI_STRING. */ - -#if !defined HAVE_STRCOLL && !defined _LIBC -# define strcoll strcmp -#endif - -#if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1 -# define HAVE_MEMPCPY 1 -# undef mempcpy -# define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len) -#endif - -#ifndef __GNU_LIBRARY__ -# ifdef __GNUC__ -__inline -# endif -# ifndef __SASC -# ifdef WINDOWS32 -static void * -# else -static char * -# endif -my_realloc (p, n) - char *p; - unsigned int n; -{ - /* These casts are the for sake of the broken Ultrix compiler, - which warns of illegal pointer combinations otherwise. */ - if (p == NULL) - return (char *) malloc (n); - return (char *) realloc (p, n); -} -# define realloc my_realloc -# endif /* __SASC */ -#endif /* __GNU_LIBRARY__ */ - - -#if !defined __alloca && !defined __GNU_LIBRARY__ - -# ifdef __GNUC__ -# undef alloca -# define alloca(n) __builtin_alloca (n) -# else /* Not GCC. */ -# ifdef HAVE_ALLOCA_H -# include -# else /* Not HAVE_ALLOCA_H. */ -# ifndef _AIX -# ifdef WINDOWS32 -# include -# else -extern char *alloca (); -# endif /* WINDOWS32 */ -# endif /* Not _AIX. */ -# endif /* sparc or HAVE_ALLOCA_H. */ -# endif /* GCC. */ - -# define __alloca alloca - -#endif - -#ifndef __GNU_LIBRARY__ -# define __stat stat -# ifdef STAT_MACROS_BROKEN -# undef S_ISDIR -# endif -# ifndef S_ISDIR -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -# endif -#endif - -#ifdef _LIBC -# undef strdup -# define strdup(str) __strdup (str) -# define sysconf(id) __sysconf (id) -# define closedir(dir) __closedir (dir) -# define opendir(name) __opendir (name) -# define readdir(str) __readdir (str) -# define getpwnam_r(name, bufp, buf, len, res) \ - __getpwnam_r (name, bufp, buf, len, res) -# ifndef __stat -# define __stat(fname, buf) __xstat (_STAT_VER, fname, buf) -# endif -#endif +/* Outcomment the following line for production quality code. */ +/* #define NDEBUG 1 */ -#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__) -# undef size_t -# define size_t unsigned int -#endif +#define GLOB_INTERFACE_VERSION 1 -/* Some system header files erroneously define these. - We want our own definitions from to take precedence. */ -#ifndef __GNU_LIBRARY__ -# undef FNM_PATHNAME -# undef FNM_NOESCAPE -# undef FNM_PERIOD -#endif -#include - -/* Some system header files erroneously define these. - We want our own definitions from to take precedence. */ -#ifndef __GNU_LIBRARY__ -# undef GLOB_ERR -# undef GLOB_MARK -# undef GLOB_NOSORT -# undef GLOB_DOOFFS -# undef GLOB_NOCHECK -# undef GLOB_APPEND -# undef GLOB_NOESCAPE -# undef GLOB_PERIOD -#endif -#include - -static -#if __GNUC__ - 0 >= 2 -inline -#endif -const char *next_brace_sub __P ((const char *begin)); +static inline const char *next_brace_sub __P ((const char *begin)); static int glob_in_dir __P ((const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), @@ -302,11 +52,7 @@ static int collated_compare __P ((const __ptr_t, const __ptr_t)); /* Find the end of the sub-pattern in a brace expression. We define this as an inline function if the compiler permits. */ -static -#if __GNUC__ - 0 >= 2 -inline -#endif -const char * +static inline const char * next_brace_sub (begin) const char *begin; { @@ -345,6 +91,8 @@ next_brace_sub (begin) return cp; } +static int __glob_pattern_p (const char *pattern, int quote); + /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. If a directory cannot be opened or read and ERRFUNC is not nil, @@ -388,7 +136,7 @@ glob (pattern, flags, errfunc, pglob) #ifdef __GNUC__ char onealt[strlen (pattern) - 1]; #else - char *onealt = (char *) malloc (strlen (pattern) - 1); + char *onealt = (char *) xmalloc (strlen (pattern) - 1); if (onealt == NULL) { if (!(flags & GLOB_APPEND)) @@ -794,7 +542,7 @@ glob (pattern, flags, errfunc, pglob) && S_ISDIR (st.st_mode))) { pglob->gl_pathv - = (char **) realloc (pglob->gl_pathv, + = (char **) xrealloc (pglob->gl_pathv, (pglob->gl_pathc + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + @@ -808,11 +556,11 @@ glob (pattern, flags, errfunc, pglob) pglob->gl_pathv[pglob->gl_pathc++] = NULL; #if defined HAVE_STRDUP || defined _LIBC - pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname); + pglob->gl_pathv[pglob->gl_pathc] = xstrdup (dirname); #else { size_t len = strlen (dirname) + 1; - char *dircopy = malloc (len); + char *dircopy = xmalloc (len); if (dircopy != NULL) pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname, len); @@ -925,7 +673,7 @@ glob (pattern, flags, errfunc, pglob) /* This is an pessimistic guess about the size. */ pglob->gl_pathv - = (char **) realloc (pglob->gl_pathv, + = (char **) xrealloc (pglob->gl_pathv, (pglob->gl_pathc + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + @@ -953,7 +701,7 @@ glob (pattern, flags, errfunc, pglob) /* No directory, ignore this entry. */ continue; - pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1 + pglob->gl_pathv[pglob->gl_pathc] = xmalloc (dir_len + 1 + filename_len); if (pglob->gl_pathv[pglob->gl_pathc] == NULL) { @@ -980,7 +728,7 @@ glob (pattern, flags, errfunc, pglob) pglob->gl_flags = flags; /* Now we know how large the gl_pathv vector must be. */ - new_pathv = (char **) realloc (pglob->gl_pathv, + new_pathv = (char **) xrealloc (pglob->gl_pathv, ((pglob->gl_pathc + 1) * sizeof (char *))); if (new_pathv != NULL) @@ -1028,7 +776,7 @@ glob (pattern, flags, errfunc, pglob) && S_ISDIR (st.st_mode)) { size_t len = strlen (pglob->gl_pathv[i]) + 2; - char *new = realloc (pglob->gl_pathv[i], len); + char *new = xrealloc (pglob->gl_pathv[i], len); if (new == NULL) { globfree (pglob); @@ -1132,7 +880,7 @@ prefix_array (dirname, array, n) for (i = 0; i < n; ++i) { size_t eltlen = strlen (array[i]) + 1; - char *new = (char *) malloc (dirlen + 1 + eltlen); + char *new = (char *) xmalloc (dirlen + 1 + eltlen); if (new == NULL) { while (i > 0) @@ -1163,10 +911,8 @@ prefix_array (dirname, array, n) #if !defined _LIBC || !defined NO_GLOB_PATTERN_P /* Return nonzero if PATTERN contains any metacharacters. Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ -int -__glob_pattern_p (pattern, quote) - const char *pattern; - int quote; +static int +__glob_pattern_p (const char *pattern, int quote) { register const char *p; int open = 0; @@ -1268,7 +1014,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) /* This is a special case for matching directories like in "*a/". */ names = (struct globlink *) __alloca (sizeof (struct globlink)); - names->name = (char *) malloc (1); + names->name = (char *) xmalloc (1); if (names->name == NULL) goto memory_error; names->name[0] = '\0'; @@ -1328,7 +1074,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) struct globlink *new = (struct globlink *) __alloca (sizeof (struct globlink)); len = NAMLEN (d); - new->name = (char *) malloc (len + 1); + new->name = (char *) xmalloc (len + 1); if (new->name == NULL) goto memory_error; #ifdef HAVE_MEMPCPY @@ -1353,7 +1099,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) nfound = 1; names = (struct globlink *) __alloca (sizeof (struct globlink)); names->next = NULL; - names->name = (char *) malloc (len + 1); + names->name = (char *) xmalloc (len + 1); if (names->name == NULL) goto memory_error; #ifdef HAVE_MEMPCPY @@ -1367,7 +1113,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) if (nfound != 0) { pglob->gl_pathv - = (char **) realloc (pglob->gl_pathv, + = (char **) xrealloc (pglob->gl_pathv, (pglob->gl_pathc + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + nfound + 1) * @@ -1415,5 +1161,3 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) } return GLOB_NOSPACE; } - -#endif /* Not ELIDE_CODE. */ diff --git a/system.h b/system.h index ee891c4..8a03d55 100644 --- a/system.h +++ b/system.h @@ -267,16 +267,17 @@ char *__progname; /* ============== from misc/miscfn.h */ +#if !defined(USE_GNU_GLOB) #if HAVE_FNMATCH_H #include -#else -#include "misc/fnmatch.h" #endif #if HAVE_GLOB_H #include +#endif #else #include "misc/glob.h" +#include "misc/fnmatch.h" #endif #if ! HAVE_S_IFSOCK