bug-gnulib
[Top][All Lists]
Advanced

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

[PATCH 3/3] glob: use scratch_buffer instead of extend_alloca


From: Paul Eggert
Subject: [PATCH 3/3] glob: use scratch_buffer instead of extend_alloca
Date: Fri, 1 Sep 2017 16:33:33 -0700

Much of the lib/glob.c part of this patch comes from a glibc patch
proposed by Adhemerval Zanella in:
https://sourceware.org/ml/libc-alpha/2017-08/msg00456.html
* lib/glob.c: Do not include <config.h>, since <libc-config.h>,
included via glob.h, does this for us now.
(__set_errno): Remove, as libc-config does this for us now.
Include <scratch_buffer.h>.
(GETPW_R_SIZE_MAX): Remove.
(glob): Use struct scratch_buffer instead of extend_alloca.
* lib/glob.in.h: Include libc-config.h rather than
including <sys/cdefs.h> conditionally.
(__BEGIN_DECLS, __END_DECLS, __THROW, __THROWNL, attribute_hidden)
(__glibc_unlikely, __restrict, weak_alias):
Remove, as libc-config does this for us now.
* m4/glob.m4 (gl_PREREQ_GLOB):
Remove sys/cdefs.h tests; no longer needed.
* modules/glob (Depends-on): Add libc-config, scratch_buffer.
(glob.h): Do not replace HAVE_SYS_CDEFS_H.
---
 ChangeLog     |  20 ++++++++
 lib/glob.c    | 155 ++++++++++------------------------------------------------
 lib/glob.in.h |  42 +---------------
 m4/glob.m4    |  10 +---
 modules/glob  |   5 +-
 5 files changed, 52 insertions(+), 180 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 078d5243c..a61d7755a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2017-09-01  Paul Eggert  <address@hidden>
 
+       glob: use scratch_buffer instead of extend_alloca
+       Much of the lib/glob.c part of this patch comes from a glibc patch
+       proposed by Adhemerval Zanella in:
+       https://sourceware.org/ml/libc-alpha/2017-08/msg00456.html
+       * lib/glob.c: Do not include <config.h>, since <libc-config.h>,
+       included via glob.h, does this for us now.
+       (__set_errno): Remove, as libc-config does this for us now.
+       Include <scratch_buffer.h>.
+       (GETPW_R_SIZE_MAX): Remove.
+       (glob): Use struct scratch_buffer instead of extend_alloca.
+       * lib/glob.in.h: Include libc-config.h rather than
+       including <sys/cdefs.h> conditionally.
+       (__BEGIN_DECLS, __END_DECLS, __THROW, __THROWNL, attribute_hidden)
+       (__glibc_unlikely, __restrict, weak_alias):
+       Remove, as libc-config does this for us now.
+       * m4/glob.m4 (gl_PREREQ_GLOB):
+       Remove sys/cdefs.h tests; no longer needed.
+       * modules/glob (Depends-on): Add libc-config, scratch_buffer.
+       (glob.h): Do not replace HAVE_SYS_CDEFS_H.
+
        scratch_buffer: new module
        * lib/scratch_buffer.h, lib/scratch_buffer_grow.c:
        * lib/scratch_buffer_grow_preserve.c:
diff --git a/lib/glob.c b/lib/glob.c
index 610d50a7f..596ae6c93 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -15,10 +15,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef _LIBC
-# include <config.h>
-#endif
-
 #include <glob.h>
 
 #include <errno.h>
@@ -39,10 +35,6 @@
 #endif
 
 #include <errno.h>
-#ifndef __set_errno
-# define __set_errno(val) errno = (val)
-#endif
-
 #include <dirent.h>
 #include <stdlib.h>
 #include <string.h>
@@ -82,12 +74,8 @@
 
 #include <flexmember.h>
 #include <glob_internal.h>
+#include <scratch_buffer.h>
 
-#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
 #ifdef _SC_LOGIN_NAME_MAX
 # define GET_LOGIN_NAME_MAX()   sysconf (_SC_LOGIN_NAME_MAX)
 #else
@@ -649,97 +637,43 @@ glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
               if (success)
                 {
                   struct passwd *p;
-                  char *malloc_pwtmpbuf = NULL;
-                  char *pwtmpbuf;
 # if defined HAVE_GETPWNAM_R || defined _LIBC
-                  long int pwbuflenmax = GETPW_R_SIZE_MAX ();
-                  size_t pwbuflen = pwbuflenmax;
                   struct passwd pwbuf;
                   int save = errno;
+                  struct scratch_buffer pwtmpbuf;
+                  scratch_buffer_init (&pwtmpbuf);
 
-#  ifndef _LIBC
-                  if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX))
-                    /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.
-                       Try a moderate value.  */
-                    pwbuflen = 1024;
-#  endif
-                  if (glob_use_alloca (alloca_used, pwbuflen))
-                    pwtmpbuf = alloca_account (pwbuflen, alloca_used);
-                  else
-                    {
-                      pwtmpbuf = malloc (pwbuflen);
-                      if (pwtmpbuf == NULL)
-                        {
-                          if (__glibc_unlikely (malloc_name))
-                            free (name);
-                          retval = GLOB_NOSPACE;
-                          goto out;
-                        }
-                      malloc_pwtmpbuf = pwtmpbuf;
-                    }
-
-                  while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
+                  while (getpwnam_r (name, &pwbuf,
+                                     pwtmpbuf.data, pwtmpbuf.length, &p)
                          != 0)
                     {
-                      size_t newlen;
-                      bool v;
                       if (errno != ERANGE)
                         {
                           p = NULL;
                           break;
                         }
-                      v = size_add_wrapv (pwbuflen, pwbuflen, &newlen);
-                      if (!v && malloc_pwtmpbuf == NULL
-                          && glob_use_alloca (alloca_used, newlen))
-                        pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen,
-                                                          newlen, alloca_used);
-                      else
+                      if (!scratch_buffer_grow (&pwtmpbuf))
                         {
-                          char *newp = (v ? NULL
-                                        : realloc (malloc_pwtmpbuf, newlen));
-                          if (newp == NULL)
-                            {
-                              free (malloc_pwtmpbuf);
-                              if (__glibc_unlikely (malloc_name))
-                                free (name);
-                              retval = GLOB_NOSPACE;
-                              goto out;
-                            }
-                          malloc_pwtmpbuf = pwtmpbuf = newp;
+                          retval = GLOB_NOSPACE;
+                          goto out;
                         }
-                      pwbuflen = newlen;
                       __set_errno (save);
                     }
 # else
-                  p = getpwnam (name);
+                  p = getpwnam (pwtmpbuf.data);
 # endif
-                  if (__glibc_unlikely (malloc_name))
-                    free (name);
                   if (p != NULL)
                     {
-                      if (malloc_pwtmpbuf == NULL)
-                        home_dir = p->pw_dir;
-                      else
+                      home_dir = strdup (p->pw_dir);
+                      malloc_home_dir = 1;
+                      if (home_dir == NULL)
                         {
-                          size_t home_dir_len = strlen (p->pw_dir) + 1;
-                          if (glob_use_alloca (alloca_used, home_dir_len))
-                            home_dir = alloca_account (home_dir_len,
-                                                       alloca_used);
-                          else
-                            {
-                              home_dir = malloc (home_dir_len);
-                              if (home_dir == NULL)
-                                {
-                                  free (pwtmpbuf);
-                                  retval = GLOB_NOSPACE;
-                                  goto out;
-                                }
-                              malloc_home_dir = 1;
-                            }
-                          memcpy (home_dir, p->pw_dir, home_dir_len);
+                          scratch_buffer_free (&pwtmpbuf);
+                          retval = GLOB_NOSPACE;
+                          goto out;
                         }
                     }
-                  free (malloc_pwtmpbuf);
+                  scratch_buffer_free (&pwtmpbuf);
                 }
               else
                 {
@@ -876,59 +810,25 @@ glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
           /* Look up specific user's home directory.  */
           {
             struct passwd *p;
-            char *malloc_pwtmpbuf = NULL;
+            struct scratch_buffer pwtmpbuf;
+            scratch_buffer_init (&pwtmpbuf);
+
 #  if defined HAVE_GETPWNAM_R || defined _LIBC
-            long int buflenmax = GETPW_R_SIZE_MAX ();
-            size_t buflen = buflenmax;
-            char *pwtmpbuf;
             struct passwd pwbuf;
             int save = errno;
 
-#   ifndef _LIBC
-            if (! (0 <= buflenmax && buflenmax <= SIZE_MAX))
-              /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.  Try 
a
-                 moderate value.  */
-              buflen = 1024;
-#   endif
-            if (glob_use_alloca (alloca_used, buflen))
-              pwtmpbuf = alloca_account (buflen, alloca_used);
-            else
-              {
-                pwtmpbuf = malloc (buflen);
-                if (pwtmpbuf == NULL)
-                  {
-                  nomem_getpw:
-                    if (__glibc_unlikely (malloc_user_name))
-                      free (user_name);
-                    retval = GLOB_NOSPACE;
-                    goto out;
-                  }
-                malloc_pwtmpbuf = pwtmpbuf;
-              }
-
-            while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
+            while (getpwnam_r (user_name, &pwbuf,
+                               pwtmpbuf.data, pwtmpbuf.length, &p) != 0)
               {
-                size_t newlen;
-                bool v;
                 if (errno != ERANGE)
                   {
                     p = NULL;
                     break;
                   }
-                v = size_add_wrapv (buflen, buflen, &newlen);
-                if (!v && malloc_pwtmpbuf == NULL
-                    && glob_use_alloca (alloca_used, newlen))
-                  pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen,
-                                                    newlen, alloca_used);
-                else
+                if (!scratch_buffer_grow (&pwtmpbuf))
                   {
-                    char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen);
-                    if (newp == NULL)
-                      {
-                        free (malloc_pwtmpbuf);
-                        goto nomem_getpw;
-                      }
-                    malloc_pwtmpbuf = pwtmpbuf = newp;
+                    retval = GLOB_NOSPACE;
+                    goto out;
                   }
                 __set_errno (save);
               }
@@ -957,7 +857,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const 
char *, int),
                     dirname = malloc (home_len + rest_len + 1);
                     if (dirname == NULL)
                       {
-                        free (malloc_pwtmpbuf);
+                        scratch_buffer_free (&pwtmpbuf);
                         retval = GLOB_NOSPACE;
                         goto out;
                       }
@@ -968,13 +868,9 @@ glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
 
                 dirlen = home_len + rest_len;
                 dirname_modified = 1;
-
-                free (malloc_pwtmpbuf);
               }
             else
               {
-                free (malloc_pwtmpbuf);
-
                 if (flags & GLOB_TILDE_CHECK)
                   {
                     /* We have to regard it as an error if we cannot find the
@@ -983,6 +879,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const 
char *, int),
                     goto out;
                   }
               }
+            scratch_buffer_free (&pwtmpbuf);
           }
 #endif /* !WINDOWS32 */
         }
diff --git a/lib/glob.in.h b/lib/glob.in.h
index b0d27cff6..4f61705e2 100644
--- a/lib/glob.in.h
+++ b/lib/glob.in.h
@@ -20,9 +20,7 @@
 #ifndef _GL_GLOB_H
 #define _GL_GLOB_H
 
-#if @HAVE_SYS_CDEFS_H@
-# include <sys/cdefs.h>
-#endif
+#include <libc-config.h>
 
 #include <stddef.h>
 
@@ -31,48 +29,10 @@
    rely on 'struct stat'.  */
 #include <sys/stat.h>
 
-#ifndef __BEGIN_DECLS
-# ifdef __cplusplus
-#  define __BEGIN_DECLS  extern "C" {
-#  define __END_DECLS    }
-# else
-#  define __BEGIN_DECLS
-#  define __END_DECLS
-# endif
-#endif
-#ifndef __THROW
-# define __THROW
-#endif
-#ifndef __THROWNL
-# define __THROWNL
-#endif
-
-#define attribute_hidden
-
-#if __GNUC__ < 3
-# define __glibc_unlikely(cond) (cond)
-#else
-# define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
-#endif
-
-/* GCC 2.95 and later have "__restrict", and C99 compilers have
-   "restrict".  */
-#if ! (defined __restrict || 2 < __GNUC__ + (95 <= __GNUC_MINOR__))
-# if 199901L <= __STDC_VERSION__
-#  define __restrict restrict
-# else
-#  define __restrict
-# endif
-#endif
-
 #ifndef __USE_GNU
 # define __USE_GNU    1
 #endif
 
-#ifndef weak_alias
-# define weak_alias(name, alias)
-#endif
-
 
 #define glob rpl_glob
 #define globfree rpl_globfree
diff --git a/m4/glob.m4 b/m4/glob.m4
index 189cd3a18..d64e70de4 100644
--- a/m4/glob.m4
+++ b/m4/glob.m4
@@ -1,4 +1,4 @@
-# glob.m4 serial 15
+# glob.m4 serial 16
 dnl Copyright (C) 2005-2007, 2009-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -65,12 +65,6 @@ AC_DEFUN([gl_PREREQ_GLOB],
   AC_REQUIRE([gl_CHECK_TYPE_STRUCT_DIRENT_D_TYPE])dnl
   AC_REQUIRE([AC_C_RESTRICT])dnl
   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])dnl
-  AC_CHECK_HEADERS_ONCE([sys/cdefs.h unistd.h])dnl
-  if test $ac_cv_header_sys_cdefs_h = yes; then
-    HAVE_SYS_CDEFS_H=1
-  else
-    HAVE_SYS_CDEFS_H=0
-  fi
-  AC_SUBST([HAVE_SYS_CDEFS_H])
+  AC_CHECK_HEADERS_ONCE([unistd.h])dnl
   AC_CHECK_FUNCS_ONCE([getlogin_r getpwnam_r])dnl
 ])
diff --git a/modules/glob b/modules/glob
index 98d49e34f..2ea73e803 100644
--- a/modules/glob
+++ b/modules/glob
@@ -24,10 +24,12 @@ d-type          [test -n "$GLOB_H"]
 flexmember      [test -n "$GLOB_H"]
 fnmatch         [test -n "$GLOB_H"]
 getlogin_r      [test -n "$GLOB_H"]
+libc-config     [test -n "$GLOB_H"]
 memchr          [test -n "$GLOB_H"]
 mempcpy         [test -n "$GLOB_H"]
 opendir         [test -n "$GLOB_H"]
 readdir         [test -n "$GLOB_H"]
+scratch_buffer  [test -n "$GLOB_H"]
 stdbool         [test -n "$GLOB_H"]
 stdint          [test -n "$GLOB_H"]
 strdup          [test -n "$GLOB_H"]
@@ -53,8 +55,7 @@ if GL_GENERATE_GLOB_H
 glob.h: glob.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
        $(AM_V_GEN)rm -f address@hidden $@ && \
        { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-         sed -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|g' \
-             -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+         sed -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
              -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
              < $(srcdir)/glob.in.h; \
        } > address@hidden && \
-- 
2.13.5




reply via email to

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