From patchwork Sun Mar 1 18:49:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 444966 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A4BE414009B for ; Mon, 2 Mar 2015 19:41:29 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=sourceware.org header.i=@sourceware.org header.b=Q8kmV5Y5; dkim-adsp=none (unprotected policy); dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:in-reply-to:references:from:date :subject:to; q=dns; s=default; b=uX2gFPk1/6mdGAmG25iUAMRf5WOWg7s Ikr7XgBw6XSR7LGnZHQ7HfLN6BvDycenbuts6/nId8UvKVacjh+K0Nitw2Y1A70r wqXuzThahFtuGXN11VYDu2NbwtIE7F4nDnn8D1oAlO37oHVwyrkkNhqJnyGissIC oEg+9vczf7w0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:in-reply-to:references:from:date :subject:to; s=default; bh=SsbPP/KOrTc+ghUIs2Ve7KFGOgQ=; b=Q8kmV 5Y5Xg3CLXQ+djHst8A5iCf/4aPAHeKK8lN0t6qlhlCOA+EkvCxeBTi6d2qkSoJmr TzwYk2NbB2+nUgAk+BwYsaImtWQqsWi58otUb9shDjhY7c2ukCgfv4p8a4ZPPAff mlDoGKgPepK6X9C0kEZdHCLX/Wf5U1j6awpTww= Received: (qmail 78476 invoked by alias); 2 Mar 2015 08:40:34 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 78427 invoked by uid 89); 2 Mar 2015 08:40:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, DATE_IN_PAST_12_24, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Message-Id: <99e4c640472ead8a515764679be90874745dbf4d.1425285061.git.fweimer@redhat.com> In-Reply-To: References: From: Florian Weimer Date: Sun, 1 Mar 2015 19:49:50 +0100 Subject: [PATCH 22/25] glob: Rewrite to use struct scratch_buffer instead of extend_alloca To: libc-alpha@sourceware.org --- 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 #include #include +#include /* 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