bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gnulib] New GNULIB glob module?


From: Derek Price
Subject: Re: [bug-gnulib] New GNULIB glob module?
Date: Tue, 31 May 2005 18:42:32 -0400
User-agent: Mozilla Thunderbird 1.0.2 (Windows/20050317)

Paul Eggert wrote:

>Derek Price <address@hidden> 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  <address@hidden>
            Paul Eggert  <address@hidden>

        * 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  <address@hidden>

        * 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;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]