From patchwork Mon Feb 5 13:27:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869275 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89969-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="A4x64PqM"; dkim-atps=neutral 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 3zZpMF2jmTz9s8J for ; Tue, 6 Feb 2018 00:28:41 +1100 (AEDT) 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=RoDuw88VH/VnKxiQQw9UPJQqjxTeKkp pWqAeyPpHlZVAhc26eDbw4s8TqPrYSMpKaGR8nRXqvDjEOA25gm5re3hulJBUSmE 6CXamObPJ/yXvl5jPnACbSLT7yDzqqLhg5rPCXalY+HvPct6wMyNlgFsdro6XkUL oF6Ao4m5dVcQ= 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=WhU2oJ6DwxKfOC6uQ/M7yB/GXIU=; b=A4x64 PqMY1pFFYci4MFpWcNTzpSS+12WrtqzKnP7J2UrkgO17T0RlO2Upd/RKYAc0JwfI 1OWxWI9dd3btrtAJvTJ/N5eorsMAuHoXtIVtIrGsB1f3e7/fCtl9gP6pYotgDhpA F1wstwwERgerWqT8jVbIpeUQnyLVyWrCM9xFDs= Received: (qmail 32985 invoked by alias); 5 Feb 2018 13:27:54 -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 32769 invoked by uid 89); 5 Feb 2018 13:27:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f193.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=8wnpdPwrnzEzLoN4Ilk9UZN+3OjwSpuIlTmotSHiRWE=; b=kRpIlMZPbvaB3fDV8E3h5dbY4HQtO/OODS0KWnoL35Jj9yDF19kUypSFDvZknwFF0C 84c51mayN4DVCXd99CqtNWk+zXsdQGQNdoU2CqYJVUaHrR3fu/+d2QYCrWermj+QP0Sc +JD/vCaushfSlCfcDegMjIWU03psfXcNVTK/3Q5GPYIqYQFQxp/JbZ13zL453U837n8s dzBAOfDclyvE3m2wKgq8Zefvfs9QsHtHbVPvRzGLQAsImy2qjQsteBWARnkocqmVvFHD q8+BGbQJiZMsfJdi/Hn5YaPaf9PWXOPQ/5arqSl6dWAbhWGAl3YLmLkQtDjLIw6qsiDh XgsQ== X-Gm-Message-State: AKwxytdhHQAtroaHFo2htCpTQfWRbGmcnBECClTcBRPZzqo+Bi66+7/A NcbmNQwrY2bX4b6M5qyD06CqQ3WjV20= X-Google-Smtp-Source: AH8x226EOPaV8TFLRD0ERU7cEuABYYgP3U+P8GqGKSHxvb3GoJRquxPIQUFgDqGwfFHwBlGc/uDXlw== X-Received: by 10.237.41.163 with SMTP id o32mr80498571qtd.80.1517837268721; Mon, 05 Feb 2018 05:27:48 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 05/12] posix: Use dynarray for globname in glob Date: Mon, 5 Feb 2018 11:27:27 -0200 Message-Id: <1517837254-19399-6-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-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_in_dir): Use dynarray for globnames. --- ChangeLog | 2 + posix/glob.c | 127 +++++++++++++++++------------------------------------------ 2 files changed, 39 insertions(+), 90 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index 26af331..2632e93 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -1189,6 +1189,21 @@ 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. The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. @@ -1199,25 +1214,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags, glob_t *pglob, size_t alloca_used) { void *stream = NULL; -# define GLOBNAMES_MEMBERS(nnames) \ - struct globnames *next; size_t count; char *name[nnames]; - struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) }; - struct { GLOBNAMES_MEMBERS (64) } init_names_buf; - struct globnames *init_names = (struct globnames *) &init_names_buf; - 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_buf; - - init_names->next = NULL; - init_names->count = ((sizeof init_names_buf - - offsetof (struct globnames, name)) - / sizeof init_names->name[0]); + globnames_array_init (&globnames); meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE)); if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) @@ -1294,34 +1297,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 nameoff = offsetof (struct globnames, name); - size_t size = FLEXSIZEOF (struct globnames, name, - count * sizeof (char *)); - if ((SIZE_MAX - nameoff) / 2 / sizeof (char *) - < names->count) - goto memory_error; - 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) + globnames_array_add (&globnames, strdup (d.name)); + if (globnames_array_has_failed (&globnames)) goto memory_error; + nfound++; } } } @@ -1331,10 +1310,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; @@ -1355,59 +1337,24 @@ glob_in_dir (const char *pattern, const char *directory, int flags, if (new_gl_pathv == NULL) { memory_error: - while (1) - { - struct globnames *old = names; - for (size_t 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; - for (size_t 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); + = ret.names[i]; + pglob->gl_pathv = new_gl_pathv; + 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); } }