From: Paul Eggert Date: Fri, 1 Sep 2017 22:41:45 +0000 (-0700) Subject: glob: use scratch_buffer instead of extend_alloca X-Git-Tag: v1.0~5966 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=e1e842053e2a573d132bd44439534e20ce00d23b;p=gnulib.git 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 , since , included via glob.h, does this for us now. (__set_errno): Remove, as libc-config does this for us now. Include . (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 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. --- diff --git a/ChangeLog b/ChangeLog index 078d5243cc..a61d7755a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 2017-09-01 Paul Eggert + 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 , since , + included via glob.h, does this for us now. + (__set_errno): Remove, as libc-config does this for us now. + Include . + (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 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 610d50a7f7..596ae6c93a 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -15,10 +15,6 @@ License along with the GNU C Library; if not, see . */ -#ifndef _LIBC -# include -#endif - #include #include @@ -39,10 +35,6 @@ #endif #include -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - #include #include #include @@ -82,12 +74,8 @@ #include #include +#include -#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 b0d27cff6d..4f61705e2e 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 -#endif +#include #include @@ -31,48 +29,10 @@ rely on 'struct stat'. */ #include -#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 189cd3a18f..d64e70de40 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 98d49e34f8..2ea73e803a 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 $@-t $@ && \ { 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; \ } > $@-t && \