This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 22/25] glob: Rewrite to use struct scratch_buffer instead of extend_alloca
- From: Florian Weimer <fweimer at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Sun, 1 Mar 2015 19:49:50 +0100
- Subject: [PATCH 22/25] glob: Rewrite to use struct scratch_buffer instead of extend_alloca
- Authentication-results: sourceware.org; auth=none
- References: <cover dot 1425285061 dot git dot fweimer at redhat dot com>
---
posix/glob.c | 147 +++++++++++++----------------------------------------------
1 file changed, 31 insertions(+), 116 deletions(-)
diff --git a/posix/glob.c b/posix/glob.c
index 5b92776..f2756f8 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <stddef.h>
+#include <scratch_buffer.h>
/* Outcomment the following line for production quality code. */
/* #define NDEBUG 1 */
@@ -267,7 +268,7 @@ glob (pattern, flags, errfunc, pglob)
glob_t dirs;
int retval = 0;
#ifdef _LIBC
- size_t alloca_used = 0;
+ size_t alloca_used = sizeof (struct scratch_buffer);
#endif
if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
@@ -624,33 +625,13 @@ glob (pattern, flags, errfunc, pglob)
{
struct passwd *p;
# if defined HAVE_GETPWNAM_R || defined _LIBC
- long int pwbuflen = GETPW_R_SIZE_MAX ();
- char *pwtmpbuf;
struct passwd pwbuf;
- int malloc_pwtmpbuf = 0;
int save = errno;
+ struct scratch_buffer pwtmpbuf;
+ scratch_buffer_init (&pwtmpbuf);
-# ifndef _LIBC
- if (pwbuflen == -1)
- /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
- Try a moderate value. */
- pwbuflen = 1024;
-# endif
- if (__libc_use_alloca (alloca_used + pwbuflen))
- pwtmpbuf = alloca_account (pwbuflen, alloca_used);
- else
- {
- pwtmpbuf = malloc (pwbuflen);
- if (pwtmpbuf == NULL)
- {
- retval = GLOB_NOSPACE;
- goto out;
- }
- malloc_pwtmpbuf = 1;
- }
-
- while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
- != 0)
+ while (getpwnam_r (name, &pwbuf,
+ pwtmpbuf.data, pwtmpbuf.length, &p) != 0)
{
if (errno != ERANGE)
{
@@ -658,67 +639,37 @@ glob (pattern, flags, errfunc, pglob)
break;
}
- if (!malloc_pwtmpbuf
- && __libc_use_alloca (alloca_used
- + 2 * pwbuflen))
- pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen,
- 2 * pwbuflen,
- alloca_used);
- else
+ if (!scratch_buffer_grow (&pwtmpbuf))
{
- char *newp = realloc (malloc_pwtmpbuf
- ? pwtmpbuf : NULL,
- 2 * pwbuflen);
- if (newp == NULL)
- {
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
- retval = GLOB_NOSPACE;
- goto out;
- }
- pwtmpbuf = newp;
- pwbuflen = 2 * pwbuflen;
- malloc_pwtmpbuf = 1;
+ retval = GLOB_NOSPACE;
+ goto out;
}
__set_errno (save);
}
# else
- p = getpwnam (name);
+ p = getpwnam (namebuf.data);
# endif
if (p != NULL)
{
- if (!malloc_pwtmpbuf)
- 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 (__libc_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);
-
- free (pwtmpbuf);
+ scratch_buffer_free (&pwtmpbuf);
+ retval = GLOB_NOSPACE;
+ goto out;
}
}
+ scratch_buffer_free (&pwtmpbuf);
}
}
if (home_dir == NULL || home_dir[0] == '\0')
{
+ if (malloc_home_dir)
+ free (home_dir);
+ malloc_home_dir = 0;
if (flags & GLOB_TILDE_CHECK)
{
- if (__glibc_unlikely (malloc_home_dir))
- free (home_dir);
retval = GLOB_NOMATCH;
goto out;
}
@@ -839,57 +790,24 @@ glob (pattern, flags, errfunc, pglob)
{
struct passwd *p;
# if defined HAVE_GETPWNAM_R || defined _LIBC
- long int buflen = GETPW_R_SIZE_MAX ();
- char *pwtmpbuf;
- int malloc_pwtmpbuf = 0;
struct passwd pwbuf;
int save = errno;
+ struct scratch_buffer pwtmpbuf;
+ scratch_buffer_init (&pwtmpbuf);
-# ifndef _LIBC
- if (buflen == -1)
- /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
- moderate value. */
- buflen = 1024;
-# endif
- if (__libc_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 = 1;
- }
-
- while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
+ while (getpwnam_r (user_name, &pwbuf,
+ pwtmpbuf.data, pwtmpbuf.length, &p) != 0)
{
if (errno != ERANGE)
{
p = NULL;
break;
}
- if (!malloc_pwtmpbuf
- && __libc_use_alloca (alloca_used + 2 * buflen))
- pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen,
- 2 * buflen, alloca_used);
- else
+
+ if (!scratch_buffer_grow (&pwtmpbuf))
{
- char *newp = realloc (malloc_pwtmpbuf ? pwtmpbuf : NULL,
- 2 * buflen);
- if (newp == NULL)
- {
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
- goto nomem_getpw;
- }
- pwtmpbuf = newp;
- malloc_pwtmpbuf = 1;
+ retval = GLOB_NOSPACE;
+ goto out;
}
__set_errno (save);
}
@@ -918,8 +836,7 @@ glob (pattern, flags, errfunc, pglob)
dirname = malloc (home_len + rest_len + 1);
if (dirname == NULL)
{
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ scratch_buffer_free (&pwtmpbuf);
retval = GLOB_NOSPACE;
goto out;
}
@@ -931,13 +848,11 @@ glob (pattern, flags, errfunc, pglob)
dirlen = home_len + rest_len;
dirname_modified = 1;
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ scratch_buffer_free (&pwtmpbuf);
}
else
{
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ scratch_buffer_free (&pwtmpbuf);
if (flags & GLOB_TILDE_CHECK)
/* We have to regard it as an error if we cannot find the
--
2.1.0