summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--lib/glob.c155
-rw-r--r--lib/glob.in.h42
-rw-r--r--m4/glob.m410
-rw-r--r--modules/glob5
5 files changed, 52 insertions, 180 deletions
diff --git a/ChangeLog b/ChangeLog
index 078d5243cc..a61d7755a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
2017-09-01 Paul Eggert <eggert@cs.ucla.edu>
+ 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 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
<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 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 <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 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 && \