Paul Eggert wrote: >Derek Price <[EMAIL PROTECTED]> writes: > > >>submission part. Perhaps it would be smoother if someone already known >>to the glibc team introduced me and this patch? >> >> > >Yes, probably. I'm willing to have a go at it. > >I suggest submitting two patches. > >(1) the part that makes it work with gnulib. > >
glob-glibc2gnulib11.diff attached: 2005-05-31 Derek Price <[EMAIL PROTECTED]> Paul Eggert <[EMAIL PROTECTED]> * glob.c: Update copyright. Assume freestanding C89 compiler. Simplify cruft that may be replaced with GNULIB modules. Make no attempt to find 64-bit versions of file access functions directly when !_LIBC. Move definitions of GLOB_* macros to glob_.h. (DIRENT_MUST_BE, DIRENT_MIGHT_BE_SYMLINK, DIRENT_MIGHT_BE_DIR): New macros to abstract dirent->d_type access. (GETPW_R_SIZE_MAX, LOGIN_NAME_MAX): New macros to abstract sysconf access. * glob.h: Protect/define contents as necessary to coexist with GNULIB. >(2) the bug fix. > >It's OK for (2) to assume that (1) has already been applied. > > glibc-glob-list-links.diff attached. Despite its name, it actually does three things: 1. Corrects an incorrect check for a successful return from getlogin_r to assume only 0 means success, per the POSIX2 spec: <http://www.opengroup.org/onlinepubs/009695399/functions/getlogin_r.html>. 2. Moves the check for GLOB_MARK directory status (and the append of `/') into glob_in_dir, where it is more efficient than performing a second pass and sometimes calling stat a second time on each file or directory. All calls to stat are avoided when dirent->d_type is available. No call to realloc of the directory name is ever necessary since room for the slash can be allocated in the first pass. 3. Ignores broken links only when GLOB_ONLYDIR is set. With glibc versions 2.3.3 through 2.3.5, the following in an empty directory would return nothing: ln -s doesnt-exist linkname glob ("*", ...) This fix syncs with the comments in the file, syncs with the POSIX2 spec, restores the pre-glibc-2.3.3 behavior, and simply makes more sense - why should `ls *' fail to list broken links? 2005-05-31 Derek R. Price <[EMAIL PROTECTED]> * glob.c: #include <stdbool.h> (glob): Only 0 return from getlogin_r means success, according to POSIX 2. Move GLOB_MARK rescan into... (glob_in_dir): ...here - it improves efficiency. Don't fail to return broken links when GLOB_ONLYDIR is not set. (link_exists_p): Rename to... (is_dir_p): ...this and update functionality accordingly. Regards, Derek
--- ../glibc-2.3.5/sysdeps/generic/glob.c 2004-10-27 14:21:02.000000000 -0400 +++ lib/glob.c 2005-05-31 18:12:01.000000000 -0400 @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1991-2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,23 +16,16 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -/* AIX requires this to be the first thing in the file. */ -#if defined _AIX && !defined __GNUC__ - #pragma alloca -#endif - #ifdef HAVE_CONFIG_H # include <config.h> #endif -/* Enable GNU extensions in glob.h. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif +#include <glob.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> +#include <stddef.h> /* Outcomment the following line for production quality code. */ /* #define NDEBUG 1 */ @@ -40,30 +33,7 @@ #include <stdio.h> /* 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 <gnu-versions.h> -# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#ifndef ELIDE_CODE #if !defined _LIBC || !defined GLOB_ONLY_P - -#if defined STDC_HEADERS || defined __GNU_LIBRARY__ -# include <stddef.h> -#endif - #if defined HAVE_UNISTD_H || defined _LIBC # include <unistd.h> # ifndef POSIX @@ -73,22 +43,13 @@ # endif #endif -#if !defined _AMIGA && !defined VMS && !defined WINDOWS32 -# include <pwd.h> -#endif +#include <pwd.h> -#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS -extern int errno; -#endif +#include <errno.h> #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 <dirent.h> # define NAMLEN(dirent) strlen((dirent)->d_name) @@ -117,17 +78,28 @@ #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 - -#if _LIBC -# define HAVE_DIRENT64 1 -#endif + if the `d_type' member for `struct dirent' is available. + HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */ +#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE +/* True if the directory entry D must be of type T. */ +# define DIRENT_MUST_BE(d, t) ((d)->d_type == (t)) + +/* True if the directory entry D might be a symbolic link. */ +# define DIRENT_MIGHT_BE_SYMLINK(d) \ + ((d)->d_type == DT_UNKNOWN || (d)->d_type == DT_LNK) + +/* True if the directory entry D might be a directory. */ +# define DIRENT_MIGHT_BE_DIR(d) \ + ((d)->d_type == DT_DIR || DIRENT_MIGHT_BE_SYMLINK (d)) + +#else /* !HAVE_D_TYPE */ +# define DIRENT_MUST_BE(d, t) false +# define DIRENT_MIGHT_BE_SYMLINK(d) true +# define DIRENT_MIGHT_BE_DIR(d) true +#endif /* HAVE_D_TYPE */ /* If the system has the `struct dirent64' type we use it internally. */ -#if defined HAVE_DIRENT64 && !defined COMPILE_GLOB64 +#if defined _LIBC && !defined COMPILE_GLOB64 # if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ # define CONVERT_D_NAMLEN(d64, d32) # else @@ -142,7 +114,7 @@ (d64)->d_ino = (d32)->d_ino; # endif -# ifdef HAVE_D_TYPE +# ifdef _DIRENT_HAVE_D_TYPE # define CONVERT_D_TYPE(d64, d32) \ (d64)->d_type = (d32)->d_type; # else @@ -165,126 +137,18 @@ # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif /* POSIX */ -#if defined STDC_HEADERS || defined __GNU_LIBRARY__ -# include <stdlib.h> -# include <string.h> -# define ANSI_STRING -#else /* No standard headers. */ - -extern char *getenv (); - -# ifdef HAVE_STRING_H -# include <string.h> -# define ANSI_STRING -# else -# include <strings.h> -# endif -# ifdef HAVE_MEMORY_H -# include <memory.h> -# endif - -extern char *malloc (), *realloc (); -extern void free (); - -extern void qsort (); -extern void abort (), exit (); - -#endif /* Standard headers. */ +#include <stdlib.h> +#include <string.h> /* NAME_MAX is usually defined in <dirent.h> or <limits.h>. */ -#if defined HAVE_LIMITS_H || defined __GNU_LIBRARY__ -# include <limits.h> -#endif +#include <limits.h> #ifndef NAME_MAX # define NAME_MAX (sizeof (((struct dirent *) 0)->d_name)) #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 <alloca.h> -# else /* Not HAVE_ALLOCA_H. */ -# ifndef _AIX -# ifdef WINDOWS32 -# include <malloc.h> -# 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 +#include <alloca.h> #ifdef _LIBC -# include <alloca.h> # undef strdup # define strdup(str) __strdup (str) # define sysconf(id) __sysconf (id) @@ -296,52 +160,37 @@ # ifndef __stat64 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf) # endif -# define HAVE_STAT64 1 -#endif +# define struct_stat64 struct stat64 +#else /* !_LIBC */ +# include "getlogin_r.h" +# include "mempcpy.h" +# include "stat-macros.h" +# include "strdup.h" +# define __stat64(fname, buf) stat (fname, buf) +# define struct_stat64 struct stat +# define __stat(fname, buf) stat (fname, buf) +# define __alloca alloca +# define __readdir readdir +# define __readdir64 readdir64 +# define __glob_pattern_p glob_pattern_p +#endif /* _LIBC */ -#ifndef HAVE_STAT64 -# define __stat64(fname, buf) __stat (fname, buf) -/* This is the variable name we are using. */ -# define st64 st -#endif - -#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__) -# undef size_t -# define size_t unsigned int -#endif - -/* Some system header files erroneously define these. - We want our own definitions from <fnmatch.h> to take precedence. */ -#ifndef __GNU_LIBRARY__ -# undef FNM_PATHNAME -# undef FNM_NOESCAPE -# undef FNM_PERIOD -#endif #include <fnmatch.h> -/* Some system header files erroneously define these. - We want our own definitions from <glob.h> 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 +#ifdef _SC_GETPW_R_SIZE_MAX +# define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX) +#else +# define GETPW_R_SIZE_MAX() (-1) #endif -#include <glob.h> - -#ifdef HAVE_GETLOGIN_R -extern int getlogin_r (char *, size_t); +#ifdef _SC_LOGIN_NAME_MAX +# define LOGIN_NAME_MAX() sysconf (_SC_LOGIN_NAME_MAX) #else -extern char *getlogin (void); +# define LOGIN_NAME_MAX() (-1) #endif static const char *next_brace_sub (const char *begin, int flags) __THROW; -#endif /* GLOB_ONLY_P */ +#endif /* !defined _LIBC || !defined GLOB_ONLY_P */ static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), @@ -349,14 +198,12 @@ #if !defined _LIBC || !defined GLOB_ONLY_P static int prefix_array (const char *prefix, char **array, size_t n) __THROW; -static int collated_compare (const __ptr_t, const __ptr_t) __THROW; +static int collated_compare (const void *, const void *) __THROW; /* Find the end of the sub-pattern in a brace expression. */ static const char * -next_brace_sub (cp, flags) - const char *cp; - int flags; +next_brace_sub (const char *cp, int flags) { unsigned int depth = 0; while (*cp != '\0') @@ -378,7 +225,7 @@ return *cp != '\0' ? cp : NULL; } -#endif /* !GLOB_ONLY_P */ +#endif /* !defined _LIBC || !defined GLOB_ONLY_P */ /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. @@ -392,11 +239,9 @@ #ifdef GLOB_ATTRIBUTE GLOB_ATTRIBUTE #endif -glob (pattern, flags, errfunc, pglob) - const char *pattern; - int flags; - int (*errfunc) (const char *, int); - glob_t *pglob; +glob (const char *pattern, int flags, + int (*errfunc) (const char *, int), + glob_t *pglob) { const char *filename; const char *dirname; @@ -454,7 +299,7 @@ #ifdef __GNUC__ char onealt[strlen (pattern) - 1]; #else - char *onealt = (char *) malloc (strlen (pattern) - 1); + char *onealt = malloc (strlen (pattern) - 1); if (onealt == NULL) { if (!(flags & GLOB_APPEND)) @@ -467,12 +312,7 @@ #endif /* We know the prefix for all sub-patterns. */ -#ifdef HAVE_MEMPCPY alt_start = mempcpy (onealt, pattern, begin - pattern); -#else - memcpy (onealt, pattern, begin - pattern); - alt_start = &onealt[begin - pattern]; -#endif /* Find the first sub-pattern and at the same time find the rest after the closing brace. */ @@ -525,12 +365,7 @@ int result; /* Construct the new glob expression. */ -#ifdef HAVE_MEMPCPY mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); -#else - memcpy (alt_start, p, next - p); - memcpy (&alt_start[next - p], rest, rest_len); -#endif result = glob (onealt, ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) @@ -624,13 +459,8 @@ char *drive_spec; ++dirlen; - drive_spec = (char *) __alloca (dirlen + 1); -#ifdef HAVE_MEMPCPY + drive_spec = __alloca (dirlen + 1); *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; -#else - memcpy (drive_spec, pattern, dirlen); - drive_spec[dirlen] = '\0'; -#endif /* For now, disallow wildcards in the drive spec, to prevent infinite recursion in glob. */ if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) @@ -640,13 +470,8 @@ from "d:/", since "d:" and "d:/" are not the same.*/ } #endif - newp = (char *) __alloca (dirlen + 1); -#ifdef HAVE_MEMPCPY + newp = __alloca (dirlen + 1); *((char *) mempcpy (newp, pattern, dirlen)) = '\0'; -#else - memcpy (newp, pattern, dirlen); - newp[dirlen] = '\0'; -#endif dirname = newp; ++filename; @@ -675,8 +500,7 @@ else { size_t i; - pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1) - * sizeof (char *)); + pglob->gl_pathv = malloc ((pglob->gl_offs + 1) * sizeof (char *)); if (pglob->gl_pathv == NULL) return GLOB_NOSPACE; @@ -706,24 +530,20 @@ { int success; char *name; -# if defined HAVE_GETLOGIN_R || defined _LIBC - size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1; + size_t buflen = LOGIN_NAME_MAX() + 1; if (buflen == 0) /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try a moderate value. */ buflen = 20; - name = (char *) __alloca (buflen); + name = __alloca (buflen); success = getlogin_r (name, buflen) >= 0; -# else - success = (name = getlogin ()) != NULL; -# endif if (success) { struct passwd *p; # if defined HAVE_GETPWNAM_R || defined _LIBC - long int pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX); + long int pwbuflen = GETPW_R_SIZE_MAX (); char *pwtmpbuf; struct passwd pwbuf; int save = errno; @@ -734,7 +554,7 @@ Try a moderate value. */ pwbuflen = 1024; # endif - pwtmpbuf = (char *) __alloca (pwbuflen); + pwtmpbuf = __alloca (pwbuflen); while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) != 0) @@ -749,7 +569,7 @@ 2 * pwbuflen); # else pwbuflen *= 2; - pwtmpbuf = (char *) __alloca (pwbuflen); + pwtmpbuf = __alloca (pwbuflen); # endif __set_errno (save); } @@ -776,14 +596,9 @@ { char *newp; size_t home_len = strlen (home_dir); - newp = (char *) __alloca (home_len + dirlen); -# ifdef HAVE_MEMPCPY + newp = __alloca (home_len + dirlen); mempcpy (mempcpy (newp, home_dir, home_len), &dirname[1], dirlen); -# else - memcpy (newp, home_dir, home_len); - memcpy (&newp[home_len], &dirname[1], dirlen); -# endif dirname = newp; } } @@ -799,14 +614,9 @@ else { char *newp; - newp = (char *) __alloca (end_name - dirname); -# ifdef HAVE_MEMPCPY + newp = __alloca (end_name - dirname); *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) = '\0'; -# else - memcpy (newp, dirname + 1, end_name - dirname); - newp[end_name - dirname - 1] = '\0'; -# endif user_name = newp; } @@ -814,7 +624,7 @@ { struct passwd *p; # if defined HAVE_GETPWNAM_R || defined _LIBC - long int buflen = sysconf (_SC_GETPW_R_SIZE_MAX); + long int buflen = GETPW_R_SIZE_MAX (); char *pwtmpbuf; struct passwd pwbuf; int save = errno; @@ -825,7 +635,7 @@ moderate value. */ buflen = 1024; # endif - pwtmpbuf = (char *) __alloca (buflen); + pwtmpbuf = __alloca (buflen); while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) { @@ -856,15 +666,9 @@ char *newp; size_t home_len = strlen (home_dir); size_t rest_len = end_name == NULL ? 0 : strlen (end_name); - newp = (char *) __alloca (home_len + rest_len + 1); -# ifdef HAVE_MEMPCPY + newp = __alloca (home_len + rest_len + 1); *((char *) mempcpy (mempcpy (newp, home_dir, home_len), end_name, rest_len)) = '\0'; -# else - memcpy (newp, home_dir, home_len); - memcpy (&newp[home_len], end_name, rest_len); - newp[home_len + rest_len] = '\0'; -# endif dirname = newp; } else @@ -882,9 +686,7 @@ if (filename == NULL) { struct stat st; -#ifdef HAVE_STAT64 - struct stat64 st64; -#endif + struct_stat64 st64; /* Return the directory if we don't check for error or if it exists. */ if ((flags & GLOB_NOCHECK) @@ -897,8 +699,7 @@ char **new_gl_pathv; new_gl_pathv - = (char **) realloc (pglob->gl_pathv, - (newcount + 1 + 1) * sizeof (char *)); + = realloc (pglob->gl_pathv, (newcount + 1 + 1) * sizeof (char *)); if (new_gl_pathv == NULL) { nospace: @@ -909,16 +710,7 @@ } pglob->gl_pathv = new_gl_pathv; -#if defined HAVE_STRDUP || defined _LIBC pglob->gl_pathv[newcount] = strdup (dirname); -#else - { - size_t len = strlen (dirname) + 1; - char *dircopy = (char *) malloc (len); - if (dircopy != NULL) - pglob->gl_pathv[newcount] = memcpy (dircopy, dirname, len); - } -#endif if (pglob->gl_pathv[newcount] == NULL) goto nospace; pglob->gl_pathv[++newcount] = NULL; @@ -1021,9 +813,8 @@ int newcount = pglob->gl_pathc + pglob->gl_offs; char **new_gl_pathv; - new_gl_pathv = (char **) realloc (pglob->gl_pathv, - (newcount + 2) - * sizeof (char *)); + new_gl_pathv = realloc (pglob->gl_pathv, + (newcount + 2) * sizeof (char *)); if (new_gl_pathv == NULL) { globfree (&dirs); @@ -1031,7 +822,7 @@ } pglob->gl_pathv = new_gl_pathv; - pglob->gl_pathv[newcount] = __strdup (pattern); + pglob->gl_pathv[newcount] = strdup (pattern); if (pglob->gl_pathv[newcount] == NULL) { globfree (&dirs); @@ -1109,7 +900,7 @@ if (!(flags & GLOB_NOSORT)) { /* Sort the vector. */ - qsort ((__ptr_t) &pglob->gl_pathv[oldcount], + qsort (&pglob->gl_pathv[oldcount], pglob->gl_pathc + pglob->gl_offs - oldcount, sizeof (char *), collated_compare); } @@ -1125,16 +916,15 @@ /* Free storage allocated in PGLOB by a previous `glob' call. */ void -globfree (pglob) - register glob_t *pglob; +globfree (register glob_t *pglob) { if (pglob->gl_pathv != NULL) { size_t i; for (i = 0; i < pglob->gl_pathc; ++i) if (pglob->gl_pathv[pglob->gl_offs + i] != NULL) - free ((__ptr_t) pglob->gl_pathv[pglob->gl_offs + i]); - free ((__ptr_t) pglob->gl_pathv); + free (pglob->gl_pathv[pglob->gl_offs + i]); + free (pglob->gl_pathv); pglob->gl_pathv = NULL; } } @@ -1145,9 +935,7 @@ /* Do a collated comparison of A and B. */ static int -collated_compare (a, b) - const __ptr_t a; - const __ptr_t b; +collated_compare (const void *a, const void *b) { const char *const s1 = *(const char *const * const) a; const char *const s2 = *(const char *const * const) b; @@ -1167,10 +955,7 @@ A slash is inserted between DIRNAME and each elt of ARRAY, unless DIRNAME is just "/". Each old element of ARRAY is freed. */ static int -prefix_array (dirname, array, n) - const char *dirname; - char **array; - size_t n; +prefix_array (const char *dirname, char **array, size_t n) { register size_t i; size_t dirlen = strlen (dirname); @@ -1203,26 +988,20 @@ for (i = 0; i < n; ++i) { size_t eltlen = strlen (array[i]) + 1; - char *new = (char *) malloc (dirlen + 1 + eltlen); + char *new = malloc (dirlen + 1 + eltlen); if (new == NULL) { while (i > 0) - free ((__ptr_t) array[--i]); + free (array[--i]); return 1; } -#ifdef HAVE_MEMPCPY { - char *endp = (char *) mempcpy (new, dirname, dirlen); + char *endp = mempcpy (new, dirname, dirlen); *endp++ = DIRSEP_CHAR; mempcpy (endp, array[i], eltlen); } -#else - memcpy (new, dirname, dirlen); - new[dirlen] = DIRSEP_CHAR; - memcpy (&new[dirlen + 1], array[i], eltlen); -#endif - free ((__ptr_t) array[i]); + free (array[i]); array[i] = new; } @@ -1235,9 +1014,7 @@ /* 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; +__glob_pattern_p (const char *pattern, int quote) { register const char *p; int open = 0; @@ -1282,18 +1059,12 @@ glob_t *pglob, int flags) { size_t fnamelen = strlen (fname); - char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1); + char *fullname = __alloca (dirlen + 1 + fnamelen + 1); struct stat st; - struct stat64 st64; + struct_stat64 st64; -# ifdef HAVE_MEMPCPY mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1), fname, fnamelen + 1); -# else - memcpy (fullname, dir, dirlen); - fullname[dirlen] = '/'; - memcpy (&fullname[dirlen + 1], fname, fnamelen + 1); -# endif return (((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_stat) (fullname, &st) @@ -1307,15 +1078,12 @@ The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. The GLOB_APPEND flag is assumed to be set (always appends). */ static int -glob_in_dir (pattern, directory, flags, errfunc, pglob) - const char *pattern; - const char *directory; - int flags; - int (*errfunc) (const char *, int); - glob_t *pglob; +glob_in_dir (const char *pattern, const char *directory, int flags, + int (*errfunc) (const char *, int), + glob_t *pglob) { size_t dirlen = strlen (directory); - __ptr_t stream = NULL; + void *stream = NULL; struct globlink { struct globlink *next; @@ -1341,21 +1109,13 @@ /* Since we use the normal file functions we can also use stat() to verify the file is there. */ struct stat st; -# ifdef HAVE_STAT64 - struct stat64 st64; -# endif + struct_stat64 st64; size_t patlen = strlen (pattern); - char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1); + char *fullname = __alloca (dirlen + 1 + patlen + 1); -# ifdef HAVE_MEMPCPY mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); -# else - memcpy (fullname, directory, dirlen); - fullname[dirlen] = '/'; - memcpy (&fullname[dirlen + 1], pattern, patlen + 1); -# endif if (((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_stat) (fullname, &st) : __stat64 (fullname, &st64)) == 0) @@ -1371,8 +1131,8 @@ { /* This is a special case for matching directories like in "*a/". */ - names = (struct globlink *) __alloca (sizeof (struct globlink)); - names->name = (char *) malloc (1); + names = __alloca (sizeof (struct globlink)); + names->name = malloc (1); if (names->name == NULL) goto memory_error; names->name[0] = '\0'; @@ -1384,7 +1144,7 @@ { stream = ((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_opendir) (directory) - : (__ptr_t) opendir (directory)); + : opendir (directory)); if (stream == NULL) { if (errno != ENOTDIR @@ -1409,7 +1169,7 @@ { const char *name; size_t len; -#if defined HAVE_DIRENT64 && !defined COMPILE_GLOB64 +#if defined _LIBC && !defined COMPILE_GLOB64 struct dirent64 *d; union { @@ -1431,27 +1191,21 @@ d = NULL; } else - d = __readdir64 ((DIR *) stream); + d = __readdir64 (stream); #else struct dirent *d = ((flags & GLOB_ALTDIRFUNC) - ? ((struct dirent *) - (*pglob->gl_readdir) (stream)) - : __readdir ((DIR *) stream)); + ? ((*pglob->gl_readdir) (stream)) + : __readdir (stream)); #endif if (d == NULL) break; if (! REAL_DIR_ENTRY (d)) continue; -#ifdef HAVE_D_TYPE /* If we shall match only directories use the information provided by the dirent call if possible. */ - if ((flags & GLOB_ONLYDIR) - && d->d_type != DT_UNKNOWN - && d->d_type != DT_DIR - && d->d_type != DT_LNK) + if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d)) continue; -#endif name = d->d_name; @@ -1460,25 +1214,17 @@ /* If the file we found is a symlink we have to make sure the target file exists. */ if ( -#ifdef HAVE_D_TYPE - (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK) || -#endif + !DIRENT_MIGHT_BE_SYMLINK (d) || link_exists_p (directory, dirlen, name, pglob, flags)) { - struct globlink *new = (struct globlink *) + struct globlink *new = __alloca (sizeof (struct globlink)); len = NAMLEN (d); - new->name = (char *) malloc (len + 1); + new->name = malloc (len + 1); if (new->name == NULL) goto memory_error; -#ifdef HAVE_MEMPCPY - *((char *) mempcpy ((__ptr_t) new->name, name, len)) - = '\0'; -#else - memcpy ((__ptr_t) new->name, name, len); - new->name[len] = '\0'; -#endif + *((char *) mempcpy (new->name, name, len)) = '\0'; new->next = names; names = new; ++nfound; @@ -1493,17 +1239,12 @@ { size_t len = strlen (pattern); nfound = 1; - names = (struct globlink *) __alloca (sizeof (struct globlink)); + names = __alloca (sizeof (struct globlink)); names->next = NULL; - names->name = (char *) malloc (len + 1); + names->name = malloc (len + 1); if (names->name == NULL) goto memory_error; -#ifdef HAVE_MEMPCPY *((char *) mempcpy (names->name, pattern, len)) = '\0'; -#else - memcpy (names->name, pattern, len); - names->name[len] = '\0'; -#endif } if (nfound != 0) @@ -1511,9 +1252,9 @@ char **new_gl_pathv; new_gl_pathv - = (char **) realloc (pglob->gl_pathv, - (pglob->gl_pathc + pglob->gl_offs + nfound + 1) - * sizeof (char *)); + = realloc (pglob->gl_pathv, + (pglob->gl_pathc + pglob->gl_offs + nfound + 1) + * sizeof (char *)); if (new_gl_pathv == NULL) goto memory_error; pglob->gl_pathv = new_gl_pathv; @@ -1531,7 +1272,7 @@ if (flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir) (stream); else - closedir ((DIR *) stream); + closedir (stream); } __set_errno (save); @@ -1543,16 +1284,14 @@ if (flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir) (stream); else - closedir ((DIR *) stream); + closedir (stream); __set_errno (save); } while (names != NULL) { if (names->name != NULL) - free ((__ptr_t) names->name); + free (names->name); names = names->next; } return GLOB_NOSPACE; } - -#endif /* Not ELIDE_CODE. */ --- ../glibc-2.3.5/posix/glob.h 2004-09-16 20:55:15.000000000 -0400 +++ lib/glob_.h 2005-05-31 18:02:40.000000000 -0400 @@ -19,29 +19,66 @@ #ifndef _GLOB_H #define _GLOB_H 1 -#include <sys/cdefs.h> +/* Note the reversal of the common HAVE_SYS_CDEFS_H idiom below. In this + way, #ifndef _SYS_CDEFS_H may be used to include <sys/cdefs.h> both when + it has been checked for via the GNULIB configure test and found and when + it has not been checked for, which we can presume means that the <glob.h> + GNULIB shares with GLIBC is being included as a system header and not as + part of GNULIB, in which case <sys/cdefs.h> may be assumed. */ +#ifndef _SYS_CDEFS_H +# include <sys/cdefs.h> +#endif +#ifndef __BEGIN_DECLS +# define __BEGIN_DECLS +# define __END_DECLS +#endif +#ifndef __THROW +# define __THROW +#endif __BEGIN_DECLS /* We need `size_t' for the following definitions. */ -#ifndef __size_t -# if defined __GNUC__ && __GNUC__ >= 2 +#ifndef GLOB_PREFIX +# ifndef __size_t +# if defined __GNUC__ && __GNUC__ >= 2 typedef __SIZE_TYPE__ __size_t; -# ifdef __USE_XOPEN +# ifdef __USE_XOPEN typedef __SIZE_TYPE__ size_t; +# endif +# else +# include <stddef.h> +# ifndef __size_t +# define __size_t size_t +# endif # endif # else -# include <stddef.h> -# ifndef __size_t -# define __size_t size_t -# endif -# endif -#else /* The GNU CC stddef.h version defines __size_t as empty. We need a real definition. */ +# undef __size_t +# define __size_t size_t +# endif +#else /* GLOB_PREFIX */ +# include <stddef.h> # undef __size_t -# define __size_t size_t -#endif +# define __size_t size_t +#endif /* !GLOB_PREFIX */ + +#ifdef GLOB_PREFIX +/* get struct stat */ +# include <sys/stat.h> + +/* The following are necessary with MSVC and who knows where else. */ +# ifndef __const +# define __const const +# endif +# ifndef __restrict +# define __restrict restrict +# endif +# ifndef __USE_GNU +# define __USE_GNU 1 +# endif +#endif /* GLOB_PREFIX */ /* Bits set in the FLAGS argument to `glob'. */ #define GLOB_ERR (1 << 0)/* Return on read errors. */ @@ -98,7 +135,11 @@ are used instead of the normal file access functions. */ void (*gl_closedir) (void *); #ifdef __USE_GNU +# if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ struct dirent *(*gl_readdir) (void *); +# else + struct direct *(*gl_readdir) (void *); +# endif #else void *(*gl_readdir) (void *); #endif @@ -112,7 +153,7 @@ #endif } glob_t; -#ifdef __USE_LARGEFILE64 +#if !defined GLOB_PREFIX && defined __USE_LARGEFILE64 # ifdef __USE_GNU struct stat64; # endif @@ -142,9 +183,18 @@ } glob64_t; #endif -#if __USE_FILE_OFFSET64 && __GNUC__ < 2 -# define glob glob64 -# define globfree globfree64 +#ifdef GLOB_PREFIX +# define __GLOB_CONCAT(x, y) x ## y +# define __GLOB_XCONCAT(x, y) __GLOB_CONCAT (x, y) +# define __GLOB_ID(y) __GLOB_XCONCAT (GLOB_PREFIX, y) +# define glob __GLOB_ID (glob) +# define globfree __GLOB_ID (globfree) +# define glob_pattern_p __GLOB_ID (glob_pattern_p) +#else +# if __USE_FILE_OFFSET64 && __GNUC__ < 2 +# define glob glob64 +# define globfree globfree64 +# endif #endif /* Do glob searching for PATTERN, placing results in PGLOB. @@ -155,7 +205,7 @@ `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. Otherwise, `glob' returns zero. */ -#if !defined __USE_FILE_OFFSET64 || __GNUC__ < 2 +#if !defined __USE_FILE_OFFSET64 || __GNUC__ < 2 || defined GLOB_PREFIX extern int glob (__const char *__restrict __pattern, int __flags, int (*__errfunc) (__const char *, int), glob_t *__restrict __pglob) __THROW; @@ -171,7 +221,7 @@ extern void __REDIRECT_NTH (globfree, (glob_t *__pglob), globfree64); #endif -#ifdef __USE_LARGEFILE64 +#if !defined GLOB_PREFIX && defined __USE_LARGEFILE64 extern int glob64 (__const char *__restrict __pattern, int __flags, int (*__errfunc) (__const char *, int), glob64_t *__restrict __pglob) __THROW;
--- ../glob-glibc2gnulib/lib/glob.c 2005-05-31 18:12:01.000000000 -0400 +++ lib/glob.c 2005-05-27 13:52:28.000000000 -0400 @@ -175,6 +175,7 @@ # define __glob_pattern_p glob_pattern_p #endif /* _LIBC */ +#include <stdbool.h> #include <fnmatch.h> #ifdef _SC_GETPW_R_SIZE_MAX @@ -538,7 +539,7 @@ glob (const char *pattern, int flags, buflen = 20; name = __alloca (buflen); - success = getlogin_r (name, buflen) >= 0; + success = getlogin_r (name, buflen) == 0; if (success) { struct passwd *p; @@ -868,35 +869,6 @@ glob (const char *pattern, int flags, } } - if (flags & GLOB_MARK) - { - /* Append slashes to directory names. */ - size_t i; - struct stat st; -#ifdef HAVE_STAT64 - struct stat64 st64; -#endif - - for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i) - if (((flags & GLOB_ALTDIRFUNC) - ? ((*pglob->gl_stat) (pglob->gl_pathv[i], &st) == 0 - && S_ISDIR (st.st_mode)) - : (__stat64 (pglob->gl_pathv[i], &st64) == 0 - && S_ISDIR (st64.st_mode)))) - { - size_t len = strlen (pglob->gl_pathv[i]) + 2; - char *new = realloc (pglob->gl_pathv[i], len); - if (new == NULL) - { - globfree (pglob); - pglob->gl_pathc = 0; - return GLOB_NOSPACE; - } - strcpy (&new[len - 2], "/"); - pglob->gl_pathv[i] = new; - } - } - if (!(flags & GLOB_NOSORT)) { /* Sort the vector. */ @@ -1054,9 +1026,9 @@ weak_alias (__glob_pattern_p, glob_patte /* We put this in a separate function mainly to allow the memory allocated with alloca to be recycled. */ #if !defined _LIBC || !defined GLOB_ONLY_P -static int -link_exists_p (const char *dir, size_t dirlen, const char *fname, - glob_t *pglob, int flags) +static bool +is_dir_p (const char *dir, size_t dirlen, const char *fname, + glob_t *pglob, int flags) { size_t fnamelen = strlen (fname); char *fullname = __alloca (dirlen + 1 + fnamelen + 1); @@ -1066,9 +1038,9 @@ link_exists_p (const char *dir, size_t d mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1), fname, fnamelen + 1); - return (((flags & GLOB_ALTDIRFUNC) - ? (*pglob->gl_stat) (fullname, &st) - : __stat64 (fullname, &st64)) == 0); + return ((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (fullname, &st) == 0 && S_ISDIR (st.st_mode) + : __stat64 (fullname, &st64) == 0 && S_ISDIR (st64.st_mode)); } #endif @@ -1211,20 +1183,35 @@ glob_in_dir (const char *pattern, const if (fnmatch (pattern, name, fnm_flags) == 0) { - /* If the file we found is a symlink we have to - make sure the target file exists. */ - if ( - !DIRENT_MIGHT_BE_SYMLINK (d) || - link_exists_p (directory, dirlen, name, pglob, - flags)) + /* ISDIR will often be incorrectly set to false + when not in GLOB_ONLYDIR || GLOB_MARK mode, but we + don't care. It won't be used and we save the + expensive call to stat. */ + int need_dir_test = + (GLOB_MARK | (DIRENT_MIGHT_BE_SYMLINK (d) + ? GLOB_ONLYDIR : 0)); + bool isdir = (DIRENT_MUST_BE (d, DT_DIR) + || ((flags & need_dir_test) + && is_dir_p (directory, dirlen, name, + pglob, flags))); + + /* In GLOB_ONLYDIR mode, skip non-dirs. */ + if ((flags & GLOB_ONLYDIR) && !isdir) + continue; + { struct globlink *new = __alloca (sizeof (struct globlink)); + char *p; len = NAMLEN (d); - new->name = malloc (len + 1); + new->name = + malloc (len + 1 + ((flags & GLOB_MARK) && isdir)); if (new->name == NULL) goto memory_error; - *((char *) mempcpy (new->name, name, len)) = '\0'; + p = mempcpy (new->name, name, len); + if ((flags & GLOB_MARK) && isdir) + *p++ = '/'; + *p = '\0'; new->next = names; names = new; ++nfound;
_______________________________________________ bug-gnulib mailing list bug-gnulib@gnu.org http://lists.gnu.org/mailman/listinfo/bug-gnulib