From patchwork Fri Mar 2 18:59:23 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: 26158 Received: (qmail 98645 invoked by alias); 2 Mar 2018 18:59: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 97645 invoked by uid 89); 2 Mar 2018 18:59:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=cv, UD:v, c.v, Consolidate X-HELO: mail-qt0-f194.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=X/cJ7PtNgbmAorrP8HV9N2SU6uTE2ppFDbR9/wBTGPs=; b=ppWe8b8Rja7Wkje6t7ScPLUR3UZpw/4Q1iL54gCA3zzyIMvxMPZDqdfoHvb8UqDjvS I0h4pnivdCvme/qDMpd9I/BATpk/BE6eVnK/KENSy+6RiaU4tE0LsrmBCZ9D6PHHtcrT lHwJArq/vzcpV6nq3Ua12qlF1ztba2DvLRKK18YFdpZl3SOT+BmQ1XfJMdMo7IlBaryg rubSTPwagjv6kmh7v7VvzzfergeQma5cO7K2Dp1D/u5kcTMWUQJIkm4ZvOswjII0rtNk +zxnyIS6apVCf8OPDEJdpuw+nVn5I+PAJ+SMmqauoRtTvOO1GD8O1j6xeq7NPoGQYxAD sYDw== X-Gm-Message-State: AElRT7HoT1KZ1z2yKp8uTDOjl2kJw4mk0RyhaSyJGOscvsznC4S5w8Fo SJB2YFvxduZ7z7siA9J8RjxNIQ+1PUc= X-Google-Smtp-Source: AG47ELsSR5LsktI4lb6pLpXFPjvboYZcuMQfzwSIL+R7wvTXaT6ftp+9+6Mf+WrEWSaz4GetDKL90w== X-Received: by 10.200.23.176 with SMTP id o45mr10340372qtj.255.1520017177879; Fri, 02 Mar 2018 10:59:37 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 5/7] Consolidate scandir{at}{64} implementation Date: Fri, 2 Mar 2018 15:59:23 -0300 Message-Id: <1520017165-15830-5-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1520017165-15830-1-git-send-email-adhemerval.zanella@linaro.org> References: <1520017165-15830-1-git-send-email-adhemerval.zanella@linaro.org> This patch consolidates scandir{at}{64} implementation on just the default dirent/scandir{at}{64}{_r}.c ones. It changes the logic to follow the conventions used on other code consolidation: * scandir{at} is only built for _DIRENT_MATCHES_DIRENT64 being 0. * scandir{at}{64} is always built and aliased to getdents for ABIs that define _DIRENT_MATCHES_DIRENT64 to 1. Also on Linux the compat symbol for old non-LFS dirent64 definition requires a platform-specific scandir64.c. Checked on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu, sparcv9-linux-gnu, sparc64-linux-gnu, powerpc-linux-gnu, and powerpc64le-linux-gnu. * dirent/scandir-tail-common.c: New file. * dirent/scandir-tail.c: Use scandir-tail-common.c. (__scandir_tail): Build iff _DIRENT_MATCHES_DIRENT64 is not defined. * dirent/scandir.c: Use scandir-tail-common.c. * dirent/scandirat.c: Likewise. * dirent/scandir64-tail.c: Use scandir-tail-common.c. * dirent/scandir64.c (scandir64): Always build and alias to scandir if _DIRENT_MATCHES_DIRENT64 is defined. * dirent/scandirat64.c (scandirat64): Likewise. * include/dirent.h (__scandir_tail): Only define iff _DIRENT_MATCHES_DIRENT64 is not defined. (__scandir64_tail): Define regardless. (__scandirat, scandirat64): Remove libc_hidden_proto. * sysdeps/unix/sysv/linux/arm/scandir64.c: Remove file. * sysdeps/unix/sysv/linux/m68k/scandir64.c: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/scandir64.c: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c: Likewise. * sysdeps/unix/sysv/linux/i386/scandir64.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c: Likewise. * sysdeps/unix/sysv/linux/scandir64.c: New file. --- ChangeLog | 21 +++++ dirent/scandir-tail-common.c | 103 +++++++++++++++++++++ dirent/scandir-tail.c | 95 ++----------------- dirent/scandir.c | 27 +----- dirent/scandir64-tail.c | 10 +- dirent/scandir64.c | 23 +++-- dirent/scandirat.c | 30 +----- dirent/scandirat64.c | 23 +++-- include/dirent.h | 18 ++-- sysdeps/unix/sysv/linux/arm/scandir64.c | 1 - sysdeps/unix/sysv/linux/m68k/scandir64.c | 1 - .../unix/sysv/linux/powerpc/powerpc32/scandir64.c | 1 - sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c | 1 - sysdeps/unix/sysv/linux/{i386 => }/scandir64.c | 37 ++++---- sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c | 1 - 15 files changed, 198 insertions(+), 194 deletions(-) create mode 100644 dirent/scandir-tail-common.c delete mode 100644 sysdeps/unix/sysv/linux/arm/scandir64.c delete mode 100644 sysdeps/unix/sysv/linux/m68k/scandir64.c delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/scandir64.c delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c rename sysdeps/unix/sysv/linux/{i386 => }/scandir64.c (81%) delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c diff --git a/dirent/scandir-tail-common.c b/dirent/scandir-tail-common.c new file mode 100644 index 0000000..f89cf77 --- /dev/null +++ b/dirent/scandir-tail-common.c @@ -0,0 +1,103 @@ +/* Common implementation for scandir{at}. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +int +SCANDIR_TAIL (DIR *dp, + DIRENT_TYPE ***namelist, + int (*select) (const DIRENT_TYPE *), + int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) +{ + if (dp == NULL) + return -1; + + int save = errno; + __set_errno (0); + + int result; + struct scandir_cancel_struct c = { .dp = dp }; + __libc_cleanup_push (&__scandir_cancel_handler, &c); + + DIRENT_TYPE **v = NULL; + size_t vsize = 0; + DIRENT_TYPE *d; + while ((d = READDIR (dp)) != NULL) + { + if (select != NULL) + { + int selected = (*select) (d); + + /* The SELECT function might have set errno to non-zero on + success. It was zero before and it needs to be again to + make the later tests work. */ + __set_errno (0); + + if (!selected) + continue; + } + + if (__glibc_unlikely (c.cnt == vsize)) + { + if (vsize == 0) + vsize = 10; + else + vsize *= 2; + DIRENT_TYPE **new = realloc (v, vsize * sizeof *v); + if (new == NULL) + break; + c.v = v = new; + } + + size_t dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d; + DIRENT_TYPE *vnew = malloc (dsize); + if (vnew == NULL) + break; + v[c.cnt++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize); + + /* Ignore errors from readdir, malloc or realloc. These functions + might have set errno to non-zero on success. It was zero before + and it needs to be again to make the latter tests work. */ + __set_errno (0); + } + + if (__glibc_likely (errno == 0)) + { + __closedir (dp); + + /* Sort the list if we have a comparison function to sort with. */ + if (cmp != NULL) + qsort (v, c.cnt, sizeof *v, (__compar_fn_t) cmp); + + *namelist = v; + result = c.cnt; + } + else + { + /* This frees everything and calls closedir. */ + __scandir_cancel_handler (&c); + result = -1; + } + + __libc_cleanup_pop (0); + + if (result >= 0) + __set_errno (save); + return result; +} diff --git a/dirent/scandir-tail.c b/dirent/scandir-tail.c index 67c9c92..7395dc4 100644 --- a/dirent/scandir-tail.c +++ b/dirent/scandir-tail.c @@ -17,96 +17,13 @@ . */ #include -#include -#include -#include -#include -#ifndef SCANDIR_TAIL -# define SCANDIR_TAIL __scandir_tail -# define READDIR __readdir -# define DIRENT_TYPE struct dirent -#endif - -int -SCANDIR_TAIL (DIR *dp, - DIRENT_TYPE ***namelist, - int (*select) (const DIRENT_TYPE *), - int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) -{ - if (dp == NULL) - return -1; - - int save = errno; - __set_errno (0); - - int result; - struct scandir_cancel_struct c = { .dp = dp }; - __libc_cleanup_push (&__scandir_cancel_handler, &c); - - DIRENT_TYPE **v = NULL; - size_t vsize = 0; - DIRENT_TYPE *d; - while ((d = READDIR (dp)) != NULL) - { - if (select != NULL) - { - int selected = (*select) (d); - - /* The SELECT function might have set errno to non-zero on - success. It was zero before and it needs to be again to - make the later tests work. */ - __set_errno (0); - - if (!selected) - continue; - } +#if !_DIRENT_MATCHES_DIRENT64 - if (__glibc_unlikely (c.cnt == vsize)) - { - if (vsize == 0) - vsize = 10; - else - vsize *= 2; - DIRENT_TYPE **new = realloc (v, vsize * sizeof *v); - if (new == NULL) - break; - c.v = v = new; - } +# define SCANDIR_TAIL __scandir_tail +# define READDIR __readdir +# define DIRENT_TYPE struct dirent - size_t dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d; - DIRENT_TYPE *vnew = malloc (dsize); - if (vnew == NULL) - break; - v[c.cnt++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize); +# include - /* Ignore errors from readdir, malloc or realloc. These functions - might have set errno to non-zero on success. It was zero before - and it needs to be again to make the latter tests work. */ - __set_errno (0); - } - - if (__glibc_likely (errno == 0)) - { - __closedir (dp); - - /* Sort the list if we have a comparison function to sort with. */ - if (cmp != NULL) - qsort (v, c.cnt, sizeof *v, (__compar_fn_t) cmp); - - *namelist = v; - result = c.cnt; - } - else - { - /* This frees everything and calls closedir. */ - __scandir_cancel_handler (&c); - result = -1; - } - - __libc_cleanup_pop (0); - - if (result >= 0) - __set_errno (save); - return result; -} +#endif diff --git a/dirent/scandir.c b/dirent/scandir.c index b24e157..6d8352d 100644 --- a/dirent/scandir.c +++ b/dirent/scandir.c @@ -15,31 +15,14 @@ License along with the GNU C Library; if not, see . */ -/* We need to avoid the header declaration of scandir64, because - the types don't match scandir and then the compiler will - complain about the mismatch when we do the alias below. */ -#define scandir64 __renamed_scandir64 - #include -#undef scandir64 - -#ifndef SCANDIR -# define SCANDIR scandir -# define SCANDIR_TAIL __scandir_tail -# define DIRENT_TYPE struct dirent -#endif - - +#if !_DIRENT_MATCHES_DIRENT64 int -SCANDIR (const char *dir, - DIRENT_TYPE ***namelist, - int (*select) (const DIRENT_TYPE *), - int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) +scandir (const char *dir, struct dirent ***namelist, + int (*select) (const struct dirent *), + int (*cmp) (const struct dirent **, const struct dirent **)) { - return SCANDIR_TAIL (__opendir (dir), namelist, select, cmp); + return __scandir_tail (__opendir (dir), namelist, select, cmp); } - -#if _DIRENT_MATCHES_DIRENT64 -weak_alias (scandir, scandir64) #endif diff --git a/dirent/scandir64-tail.c b/dirent/scandir64-tail.c index 8d5cc07..4e873d4 100644 --- a/dirent/scandir64-tail.c +++ b/dirent/scandir64-tail.c @@ -18,9 +18,7 @@ #include -#if !_DIRENT_MATCHES_DIRENT64 -# define SCANDIR_TAIL __scandir64_tail -# define READDIR __readdir64 -# define DIRENT_TYPE struct dirent64 -# include -#endif +#define SCANDIR_TAIL __scandir64_tail +#define READDIR __readdir64 +#define DIRENT_TYPE struct dirent64 +#include diff --git a/dirent/scandir64.c b/dirent/scandir64.c index 0c63fa9..6bdd462 100644 --- a/dirent/scandir64.c +++ b/dirent/scandir64.c @@ -15,15 +15,18 @@ License along with the GNU C Library; if not, see . */ +#define scandir __no_scandir_decl #include - -/* scandir.c defines scandir64 as an alias if _DIRENT_MATCHES_DIRENT64. */ -#if !_DIRENT_MATCHES_DIRENT64 - -# define SCANDIR scandir64 -# define SCANDIR_TAIL __scandir64_tail -# define DIRENT_TYPE struct dirent64 - -# include - +#undef scandir + +int +scandir64 (const char *dir, struct dirent64 ***namelist, + int (*select) (const struct dirent64 *), + int (*cmp) (const struct dirent64 **, const struct dirent64 **)) +{ + return __scandir64_tail (__opendir (dir), namelist, select, cmp); +} + +#if _DIRENT_MATCHES_DIRENT64 +weak_alias (scandir64, scandir) #endif diff --git a/dirent/scandirat.c b/dirent/scandirat.c index 96a1b0e..8dad1e8 100644 --- a/dirent/scandirat.c +++ b/dirent/scandirat.c @@ -15,35 +15,15 @@ License along with the GNU C Library; if not, see . */ -/* We need to avoid the header declaration of scandir64, because - the types don't match scandir and then the compiler will - complain about the mismatch when we do the alias below. */ -#define scandirat64 __renamed_scandirat64 - #include -#undef scandirat64 - -#ifndef SCANDIRAT -# define SCANDIRAT __scandirat -# define SCANDIR_TAIL __scandir_tail -# define DIRENT_TYPE struct dirent -# define SCANDIRAT_WEAK_ALIAS -#endif - +#if !_DIRENT_MATCHES_DIRENT64 int -SCANDIRAT (int dfd, const char *dir, - DIRENT_TYPE ***namelist, - int (*select) (const DIRENT_TYPE *), - int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) +__scandirat (int dfd, const char *dir, struct dirent ***namelist, + int (*select) (const struct dirent *), + int (*cmp) (const struct dirent **, const struct dirent **)) { - return SCANDIR_TAIL (__opendirat (dfd, dir), namelist, select, cmp); + return __scandir_tail (__opendirat (dfd, dir), namelist, select, cmp); } -libc_hidden_def (SCANDIRAT) -#ifdef SCANDIRAT_WEAK_ALIAS weak_alias (__scandirat, scandirat) #endif - -#if _DIRENT_MATCHES_DIRENT64 -weak_alias (scandirat, scandirat64) -#endif diff --git a/dirent/scandirat64.c b/dirent/scandirat64.c index 520ae7c..7e5e209 100644 --- a/dirent/scandirat64.c +++ b/dirent/scandirat64.c @@ -15,15 +15,18 @@ License along with the GNU C Library; if not, see . */ +#define scandirat __no_scandirat_decl #include - -/* scandirat.c defines scandirat64 as an alias if _DIRENT_MATCHES_DIRENT64. */ -#if !_DIRENT_MATCHES_DIRENT64 - -# define SCANDIRAT scandirat64 -# define SCANDIR_TAIL __scandir64_tail -# define DIRENT_TYPE struct dirent64 - -# include - +#undef scandirat + +int +scandirat64 (int dfd, const char *dir, struct dirent64 ***namelist, + int (*select) (const struct dirent64 *), + int (*cmp) (const struct dirent64 **, const struct dirent64 **)) +{ + return __scandir64_tail (__opendirat (dfd, dir), namelist, select, cmp); +} + +#if _DIRENT_MATCHES_DIRENT64 +weak_alias (scandirat64, scandirat) #endif diff --git a/include/dirent.h b/include/dirent.h index cc8f189..f8f1942 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -57,25 +57,23 @@ extern int __scandir_tail (DIR *dp, int (*cmp) (const struct dirent **, const struct dirent **)) attribute_hidden; -# if _DIRENT_MATCHES_DIRENT64 -# define __scandir64_tail (dp, namelist, select, cmp) \ - __scandir_tail (dp, (struct dirent ***) (namelist), \ - (int (*) (const struct dirent *)) (select), \ - (int (*) (const struct dirent **, \ - const struct dirent **)) (cmp)) -# else +# if !_DIRENT_MATCHES_DIRENT64 +extern int __scandir_tail (DIR *dp, + struct dirent ***namelist, + int (*select) (const struct dirent *), + int (*cmp) (const struct dirent **, + const struct dirent **)) + attribute_hidden; +# endif extern int __scandir64_tail (DIR *dp, struct dirent64 ***namelist, int (*select) (const struct dirent64 *), int (*cmp) (const struct dirent64 **, const struct dirent64 **)) attribute_hidden; -# endif libc_hidden_proto (__rewinddir) extern __typeof (scandirat) __scandirat; -libc_hidden_proto (__scandirat) -libc_hidden_proto (scandirat64) # if IS_IN (rtld) && !defined NO_RTLD_HIDDEN extern __typeof (__rewinddir) __rewinddir attribute_hidden; diff --git a/sysdeps/unix/sysv/linux/arm/scandir64.c b/sysdeps/unix/sysv/linux/arm/scandir64.c deleted file mode 100644 index 506fd88..0000000 --- a/sysdeps/unix/sysv/linux/arm/scandir64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/m68k/scandir64.c b/sysdeps/unix/sysv/linux/m68k/scandir64.c deleted file mode 100644 index 506fd88..0000000 --- a/sysdeps/unix/sysv/linux/m68k/scandir64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/scandir64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/scandir64.c deleted file mode 100644 index 506fd88..0000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/scandir64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c b/sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c deleted file mode 100644 index 506fd88..0000000 --- a/sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/i386/scandir64.c b/sysdeps/unix/sysv/linux/scandir64.c similarity index 81% rename from sysdeps/unix/sysv/linux/i386/scandir64.c rename to sysdeps/unix/sysv/linux/scandir64.c index 50590c3..efb502f 100644 --- a/sysdeps/unix/sysv/linux/i386/scandir64.c +++ b/sysdeps/unix/sysv/linux/scandir64.c @@ -15,26 +15,28 @@ License along with the GNU C Library; if not, see . */ +#define scandir __no_scandir_decl #include +#undef scandir -#define SCANDIR __scandir64 -#define SCANDIR_TAIL __scandir64_tail -#define DIRENT_TYPE struct dirent64 - -#include - -#undef SCANDIR -#undef SCANDIR_TAIL -#undef DIRENT_TYPE - -#include +int +__scandir64 (const char *dir, struct dirent64 ***namelist, + int (*select) (const struct dirent64 *), + int (*cmp) (const struct dirent64 **, const struct dirent64 **)) +{ + return __scandir64_tail (__opendir (dir), namelist, select, cmp); +} +#if _DIRENT_MATCHES_DIRENT64 +weak_alias (__scandir64, scandir64) +weak_alias (__scandir64, scandir) +#else +# include versioned_symbol (libc, __scandir64, scandir64, GLIBC_2_2); - -#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) -# include -# include -# include "olddirent.h" +# if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) +# include +# include +# include "olddirent.h" int __old_scandir64 (const char *dir, struct __old_dirent64 ***namelist, @@ -133,4 +135,5 @@ __old_scandir64 (const char *dir, struct __old_dirent64 ***namelist, } compat_symbol (libc, __old_scandir64, scandir64, GLIBC_2_1); -#endif +# endif /* SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) */ +#endif /* _DIRENT_MATCHES_DIRENT64 */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c b/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c deleted file mode 100644 index 506fd88..0000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c +++ /dev/null @@ -1 +0,0 @@ -#include