diff options
46 files changed, 632 insertions, 61 deletions
@@ -1,3 +1,61 @@ +2017-09-25 Adhemerval Zanella <adhemerval.zanella@linaro.org> + + [BZ #22183] + * include/gnu-versions.h (_GNU_GLOB_INTERFACE_VERSION): Increase + version to 2. + * posix/Makefile (routines): Add glob-lstat-compat and + glob64-lstat-compat. + * posix/Versions (GLIBC_2.27, glob, glob64): Add symbol version. + * posix/glob-lstat-compat.c: New file. + * posix/glob64-lstat-compat.c: Likewise. + * posix/tst-glob_lstat_compat.c: Likewise. + * sysdeps/unix/sysv/linux/glob-lstat-compat.c: Likewise. + * sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c: Likewise. + * sysdeps/unix/sysv/linux/glob64-lstat-compat.c: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/glob64-lstat-compat.c: + Likewise. + * sysdeps/unix/sysv/linux/alpha/glob.c: Remove file. + * sysdeps/unix/sysv/linux/s390/s390-32/glob64.c: Likewise. + * posix/glob.c (glob_lstat): New function. + (glob): Rename to __glob and add versioned symbol to 2.27. + (glob_in_dir): Use glob_lstat. + * posix/glob64.c (glob64): Add GLOB_ATTRIBUTE. + * sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/glob.c (glob): Add versioned symbol for + 2.27. + * sysdeps/unix/sysv/linux/glob64.c (glob64): Likewise. + * sysdeps/unix/sysv/linux/oldglob.c (GLOB_NO_LSTAT): Define. + * sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_glob): Do not use + gl_lstat on glob call. + * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add GLIBC_2.27 glob + and glob64 symbols. + * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: + Likewise. + * sysdeps/unix/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise. + 2017-09-25 H.J. Lu <hongjiu.lu@intel.com> * configure.ac (AS): Require binutils 2.25 or later. diff --git a/include/gnu-versions.h b/include/gnu-versions.h index 40f2bfcc79..ce2625440b 100644 --- a/include/gnu-versions.h +++ b/include/gnu-versions.h @@ -45,7 +45,7 @@ #define _GNU_OBSTACK_INTERFACE_VERSION 1 /* vs malloc/obstack.c */ #define _GNU_REGEX_INTERFACE_VERSION 1 /* vs posix/regex.c */ -#define _GNU_GLOB_INTERFACE_VERSION 1 /* vs posix/glob.c */ +#define _GNU_GLOB_INTERFACE_VERSION 2 /* vs posix/glob.c */ #define _GNU_GETOPT_INTERFACE_VERSION 2 /* vs posix/getopt.c and posix/getopt1.c */ diff --git a/posix/Makefile b/posix/Makefile index 7f77b07dfa..b5894425ae 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -46,6 +46,7 @@ routines := \ getresuid getresgid setresuid setresgid \ pathconf sysconf fpathconf \ glob glob64 globfree globfree64 glob_pattern_p fnmatch regex \ + glob-lstat-compat glob64-lstat-compat \ confstr \ getopt getopt1 \ sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \ @@ -95,7 +96,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-posix_fadvise tst-posix_fadvise64 \ tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve tests-internal := bug-regex5 bug-regex20 bug-regex33 \ - tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 + tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \ + tst-glob_lstat_compat xtests := bug-ga2 ifeq (yes,$(build-shared)) test-srcs := globtest diff --git a/posix/Versions b/posix/Versions index bb481a505b..65e96870e1 100644 --- a/posix/Versions +++ b/posix/Versions @@ -134,6 +134,9 @@ libc { GLIBC_2.11 { execvpe; } + GLIBC_2.27 { + glob; glob64; + } GLIBC_PRIVATE { __libc_fork; __libc_pread; __libc_pwrite; } diff --git a/posix/glob-lstat-compat.c b/posix/glob-lstat-compat.c new file mode 100644 index 0000000000..e30d34351d --- /dev/null +++ b/posix/glob-lstat-compat.c @@ -0,0 +1,36 @@ +/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC. + Copyright (C) 2017 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 + <http://www.gnu.org/licenses/>. */ + +#include <shlib-compat.h> + +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27) + +# include <glob.h> + +# define __glob(pattern, flags, errfunc, pglob) \ + __glob_lstat_compat (pattern, flags, errfunc, pglob) + +# define GLOB_ATTRIBUTE attribute_compat_text_section + +/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC. */ +# define GLOB_NO_LSTAT + +# include <posix/glob.c> + +compat_symbol (libc, __glob_lstat_compat, glob, GLIBC_2_0); +#endif diff --git a/posix/glob.c b/posix/glob.c index c699177d19..98122dac88 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -57,7 +57,9 @@ # endif # define struct_stat64 struct stat64 # define FLEXIBLE_ARRAY_MEMBER +# include <shlib-compat.h> #else /* !_LIBC */ +# define __glob glob # define __getlogin_r(buf, len) getlogin_r (buf, len) # define __lstat64(fname, buf) lstat (fname, buf) # define __stat64(fname, buf) stat (fname, buf) @@ -179,6 +181,29 @@ convert_dirent64 (const struct dirent64 *source) ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0) #endif +static int +glob_lstat (glob_t *pglob, int flags, const char *fullname) +{ +/* Use on glob-lstat-compat.c to provide a compat symbol which does not + use lstat / gl_lstat. */ +#ifdef GLOB_NO_LSTAT +# define GL_LSTAT gl_stat +# define LSTAT64 __stat64 +#else +# define GL_LSTAT gl_lstat +# define LSTAT64 __lstat64 +#endif + + union + { + struct stat st; + struct_stat64 st64; + } ust; + return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC) + ? pglob->GL_LSTAT (fullname, &ust.st) + : LSTAT64 (fullname, &ust.st64)); +} + /* 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. */ @@ -248,6 +273,9 @@ next_brace_sub (const char *cp, int flags) return *cp != '\0' ? cp : NULL; } +#ifndef GLOB_ATTRIBUTE +# define GLOB_ATTRIBUTE +#endif /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. @@ -258,11 +286,9 @@ next_brace_sub (const char *cp, int flags) If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. Otherwise, 'glob' returns zero. */ int -#ifdef GLOB_ATTRIBUTE GLOB_ATTRIBUTE -#endif -glob (const char *pattern, int flags, int (*errfunc) (const char *, int), - glob_t *pglob) +__glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + glob_t *pglob) { const char *filename; char *dirname = NULL; @@ -406,9 +432,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* Construct the new glob expression. */ mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); - result = glob (onealt, - ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) - | GLOB_APPEND), errfunc, pglob); + result = __glob (onealt, + ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) + | GLOB_APPEND), + errfunc, pglob); /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) @@ -557,7 +584,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); } } - int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob); if (val == 0) pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK)); @@ -931,11 +958,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), dirs.gl_lstat = pglob->gl_lstat; } - status = glob (dirname, - ((flags & (GLOB_ERR | GLOB_NOESCAPE - | GLOB_ALTDIRFUNC)) - | GLOB_NOSORT | GLOB_ONLYDIR), - errfunc, &dirs); + status = __glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC)) + | GLOB_NOSORT | GLOB_ONLYDIR), + errfunc, &dirs); if (status != 0) { if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH) @@ -1133,8 +1159,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), return retval; } -#if defined _LIBC && !defined glob -libc_hidden_def (glob) +#if defined _LIBC && !defined __glob +versioned_symbol (libc, __glob, glob, GLIBC_2_27); +libc_hidden_ver (__glob, glob) #endif @@ -1250,11 +1277,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, } else if (meta == GLOBPAT_NONE) { - union - { - struct stat st; - struct_stat64 st64; - } ust; size_t patlen = strlen (pattern); size_t fullsize; bool alloca_fullname @@ -1273,10 +1295,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); - if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) - ? (*pglob->gl_lstat) (fullname, &ust.st) - : __lstat64 (fullname, &ust.st64)) - == 0) + if (glob_lstat (pglob, flags, fullname) == 0 || errno == EOVERFLOW) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ diff --git a/posix/glob64-lstat-compat.c b/posix/glob64-lstat-compat.c new file mode 100644 index 0000000000..1fabf8667e --- /dev/null +++ b/posix/glob64-lstat-compat.c @@ -0,0 +1,36 @@ +/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC. + Copyright (C) 2017 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 + <http://www.gnu.org/licenses/>. */ + +#include <shlib-compat.h> + +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27) + +# include <glob.h> + +# define glob(pattern, flags, errfunc, pglob) \ + __glob64_lstat_compat (pattern, flags, errfunc, pglob) + +# define GLOB_ATTRIBUTE attribute_compat_text_section + +/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC. */ +# d |
