From patchwork Thu Jun 8 21:13:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 103418 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp2633012qgd; Thu, 8 Jun 2017 14:16:28 -0700 (PDT) X-Received: by 10.84.205.70 with SMTP id o6mr23139998plh.32.1496956588587; Thu, 08 Jun 2017 14:16:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496956588; cv=none; d=google.com; s=arc-20160816; b=zgQNAvtqtfOe5+hOvuRSzNFZFfnrJalcXnWUgkJt/1gziPIrwgmpSZdCapQAVKwZSK bFgUGt1PC7hQAd8NNpIgeV9bTa6Rg92Ne4a7nOu0LRaXKRW1ap/OIt0Ym1f7kk8IzWki +iLXgTWGQVXEztBh2FTL84XO8cbsOceo1cpiZ4a+fS+0BAXvbRvLm9sdTfVXQE4rDWqy PC4GiGUFw/Jd4KAvgkhY2xyrRLuq+QGXZPsBhgubfdYZzdLVOzYsJrWw9YgICUgiLco+ JXmo9/xgGPfTiJoyIAJUOw5OqWotz9CX9n2LFf5pi4GqhNrSOYMPIQSUjN2TKrEAsjMO umZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=2Lo4DSyvvsyY+OwpETP3t8B45pvImUsuolI/b5oYDlM=; b=p0Egs3pYyqbHjuZNrlwlUtAsgvEv6d0fMYmTa3Wz5jTK36xZnt+TbBNcQ2sqdvtXcX MqS/6sTx92qTpY4qcr/JcIXHSJnDmpcC0Xct16UYdDr8bgo0LfOCrrNfrx+/jKm3kge0 iqR/olCwd87tYKX2KNO/3qbQAyj9ZawFcJxWULvyAMQePnF5g3iY+Q4N6X54WXsd7r5/ 0iRu7W96D8fvCC4He7yi626npcxMryxBspYXhjgrKKOsN0GkGYMUI6lI8qlaxA9JKUyy FYVDszZ66clH5m9AK4Yi7YIxiWHAmWpnWbWiITNIc7ndDcfB1yNoxVBNPSN7BG+mNt3+ t8Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-80212-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80212-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id e186si5153396pgc.163.2017.06.08.14.16.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Jun 2017 14:16:28 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-80212-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-80212-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80212-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=P7ujHQQXdUJLe/gYiOMXY6IaxOYNFxi PY5tRlnw7FVf36csr9dWhLwWAnhImkRR7em3yP0AE3AWpB25Oz4OAKSij92OEPHi e6c27yCEr/alQ6cwOrLZ035wb+ImbHUaBC/n0Qmuo0m6rEJESPBA5MQbKIoplWqr rOCjGNbp6iL8= 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:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=WdD3TZ/gke9t20uBCxA5PmicZvk=; b=bg/wE 2HM7kBtHaC5zEJhLLjNWi0SVzl6EG4MTp7WKbZiawvNy+HKyjiVD1F8p44qdb+pp VKZjS5YqeS6GX/xifjvxaezTAE3/3cJKFeaRGXTSah00xeSiebG/jyoRrchmEjh/ vP51CVybYJOMw61wuejZiEqAPp5SsiF6esb5DA= Received: (qmail 40420 invoked by alias); 8 Jun 2017 21:14:15 -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 40355 invoked by uid 89); 8 Jun 2017 21:14:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f181.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=2Lo4DSyvvsyY+OwpETP3t8B45pvImUsuolI/b5oYDlM=; b=Q5ifOJB4k1Xt8Fa35Etqei2wwa7GlidlL9rFi9dy06+YC8F7EgemCjotFANB9birc6 Ctg2seczw2HwgeAbFs2yLqWD2d/Ez8PuYqOd1KDYj4U06O7jZOUpIKAvvaIUFg6qC3cJ ggb2vqnEO9t8yn8l2+/NK73R0LmFZYZEEFSPrOJbapylsTPWoKtFe6tSnnQFazHUMHP7 u9sw+eFng9nUyHTLP1vVoiNkUpF85+zFQFujk2tAcabLIEaG7t1CdOP6sHI4EDT57Xhg GH90YjEvF0z0l9zmQCrJWJT3dUpitgWTMmK0cPJOGldUF2blgI2TGk4oRtQ7f6OkvNDs gzuQ== X-Gm-Message-State: AODbwcB8/TC4qXr6UERH9HH39tU9u51ALxthkGQHS9vc03EOifR7q9jO y1tCumVs4CnIdq/oTZXxcg== X-Received: by 10.200.45.83 with SMTP id o19mr39644424qta.43.1496956454478; Thu, 08 Jun 2017 14:14:14 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 13/17] posix: Use dynarray for globname in glob Date: Thu, 8 Jun 2017 18:13:27 -0300 Message-Id: <1496956411-25594-14-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1496956411-25594-1-git-send-email-adhemerval.zanella@linaro.org> References: <1496956411-25594-1-git-send-email-adhemerval.zanella@linaro.org> This patch uses dynarray at glob internal glob_in_dir function to manage the various matched patterns. It simplify and removes all the boilerplate buffer managements required. It also removes the glob_use_alloca, since it is not used anymore. Checked on x86_64-linux-gnu. * posix/glob.c (glob_use_alloca): Remove. (glob_in_dir): Use dynarray for globnames. --- posix/glob.c | 155 +++++++++++++++-------------------------------------------- 1 file changed, 38 insertions(+), 117 deletions(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index beeb639..62be373 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -237,33 +237,6 @@ convert_dirent64 (const struct dirent64 *source) ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0) #endif -/* Set *R = A + B. Return true if the answer is mathematically - incorrect due to overflow; in this case, *R is the low order - bits of the correct answer.. */ - -static bool size_add_wrapv (size_t a, size_t b, size_t *r); -static bool glob_use_alloca (size_t alloca_used, size_t len); - -/* We must not compile this function twice. */ -static bool -size_add_wrapv (size_t a, size_t b, size_t *r) -{ -#if 5 <= __GNUC__ - return __builtin_add_overflow (a, b, r); -#else - *r = a + b; - return *r < a; -#endif -} - -static bool -glob_use_alloca (size_t alloca_used, size_t len) -{ - size_t size; - return (!size_add_wrapv (alloca_used, len, &size) - && __libc_use_alloca (size)); -} - static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), glob_t *pglob, size_t alloca_used); @@ -1262,6 +1235,20 @@ prefix_array (const char *dirname, char **array, size_t n) return 0; } +struct globnames_result +{ + char **names; + size_t length; +}; + +/* Create a dynamic array for C string representing the glob name found. */ +#define DYNARRAY_STRUCT globnames_array +#define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr) +#define DYNARRAY_ELEMENT char * +#define DYNARRAY_PREFIX globnames_array_ +#define DYNARRAY_FINAL_TYPE struct globnames_result +#define DYNARRAY_INITIAL_SIZE 64 +#include /* Like `glob', but PATTERN is a final pathname component, and matches are searched for in DIRECTORY. @@ -1273,26 +1260,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags, glob_t *pglob, size_t alloca_used) { void *stream = NULL; - struct globnames - { - struct globnames *next; - size_t count; - char *name[64]; - }; -#define INITIAL_COUNT sizeof (init_names.name) / sizeof (init_names.name[0]) - struct globnames init_names; - struct globnames *names = &init_names; - struct globnames *names_alloca = &init_names; + struct globnames_array globnames; size_t nfound = 0; - size_t cur = 0; int meta; int save; int result; - alloca_used += sizeof (init_names); - - init_names.next = NULL; - init_names.count = INITIAL_COUNT; + globnames_array_init (&globnames); meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE)); if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) @@ -1379,30 +1353,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags, if (fnmatch (pattern, d.name, fnm_flags) == 0) { - if (cur == names->count) - { - struct globnames *newnames; - size_t count = names->count * 2; - size_t size = (sizeof (struct globnames) - + ((count - INITIAL_COUNT) - * sizeof (char *))); - if (glob_use_alloca (alloca_used, size)) - newnames = names_alloca - = alloca_account (size, alloca_used); - else if ((newnames = malloc (size)) == NULL) - goto memory_error; - newnames->count = count; - newnames->next = names; - names = newnames; - cur = 0; - } - names->name[cur] = strdup (d.name); - if (names->name[cur] == NULL) - goto memory_error; - ++cur; - ++nfound; - if (SIZE_MAX - pglob->gl_offs <= nfound) - goto memory_error; + globnames_array_add (&globnames, strdup (d.name)); + if (globnames_array_has_failed (&globnames)) + goto memory_error; + nfound++; } } } @@ -1412,10 +1366,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags, { size_t len = strlen (pattern); nfound = 1; - names->name[cur] = malloc (len + 1); - if (names->name[cur] == NULL) + char *newp = malloc (len + 1); + if (newp == NULL) + goto memory_error; + *((char *) mempcpy (newp, pattern, len)) = '\0'; + globnames_array_add (&globnames, newp); + if (globnames_array_has_failed (&globnames)) goto memory_error; - *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0'; } result = GLOB_NOMATCH; @@ -1436,61 +1393,25 @@ glob_in_dir (const char *pattern, const char *directory, int flags, if (new_gl_pathv == NULL) { memory_error: - while (1) - { - struct globnames *old = names; - size_t i; - for (i = 0; i < cur; ++i) - free (names->name[i]); - names = names->next; - /* NB: we will not leak memory here if we exit without - freeing the current block assigned to OLD. At least - the very first block is always allocated on the stack - and this is the block assigned to OLD here. */ - if (names == NULL) - { - assert (old == &init_names); - break; - } - cur = names->count; - if (old == names_alloca) - names_alloca = names; - else - free (old); - } + globnames_array_free (&globnames); result = GLOB_NOSPACE; } else { - while (1) + struct globnames_result ret = { .names = 0, .length = -1 }; + if (!globnames_array_finalize (&globnames, &ret)) + result = GLOB_NOSPACE; + else { - struct globnames *old = names; - size_t i; - for (i = 0; i < cur; ++i) + for (size_t i = 0; i < ret.length; ++i) new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++] - = names->name[i]; - names = names->next; - /* NB: we will not leak memory here if we exit without - freeing the current block assigned to OLD. At least - the very first block is always allocated on the stack - and this is the block assigned to OLD here. */ - if (names == NULL) - { - assert (old == &init_names); - break; - } - cur = names->count; - if (old == names_alloca) - names_alloca = names; - else - free (old); - } - - pglob->gl_pathv = new_gl_pathv; + = ret.names[i]; - pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; - - pglob->gl_flags = flags; + pglob->gl_pathv = new_gl_pathv; + pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + } + free (ret.names); } }