This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v2 1/2] posix: Add compat glob symbol to not follow dangling symbols
On 18/09/2017 13:53, Paul Eggert wrote:
> I looked only at the posix/glob.c changes, since they're shared with Gnulib.
>
> The macro GLOB_LSTAT_COMPAT has a confusing name. The name sounds like it involves glob using lstat. But the name really means "glob should not call lstat, to be compatible with older versions". I suggest renaming it to something like GLOB_NO_LSTAT to make this clearer.
>
> Why have a named type 'union glob_stat'? It's used only once, and the old code didn't give it a name, so why give it a name now?
>
>> + return __builtin_expect (flags & GLOB_ALTDIRFUNC, 0) +/* Use on glob-lstat-compat.c to provide a compat symbol which does not + use lstat / gl_lstat. */ +#ifdef GLOB_LSTAT_COMPAT + ? (*pglob->gl_stat) (fullname, &ust.st) + : __stat64 (fullname, &ust.st64); +#else + ? (*pglob->gl_lstat) (fullname, &ust.st) + : __lstat64 (fullname, &ust.st64); +#endif
>
> Please reformulate so that the #ifdef does not appear within a statement or expression; it's confusing to have #ifs containing just parts of statements.
>
> A minor point: there is no need for the '*' prefix operator; the use of '*' in this code goes back to pre-C89 compilers and we don't need to worry about that any more.
>
> Perhaps something like the following instead? It addresses the above points.
>
> #ifdef GLOB_NO_STAT
> # 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));
Thanks for the reviews, all points addresses in the patch below:
---
* 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/alpha/glob.c: Remove file.
* 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.
---
diff --git a/include/gnu-versions.h b/include/gnu-versions.h
index 40f2bfc..ce26254 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 7188cba..203555a 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
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 bb481a5..65e9687 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 0000000..e30d343
--- /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 c699177..795cebe 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,9 @@ 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 +583,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 +957,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 +1158,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 +1276,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 +1294,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 0000000..1fabf86
--- /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. */
+# define GLOB_NO_LSTAT
+
+# include <posix/glob64.c>
+
+compat_symbol (libc, __glob64_lstat_compat, glob64, GLIBC_2_0);
+#endif
diff --git a/posix/glob64.c b/posix/glob64.c
index a515a1c..ee7ef84 100644
--- a/posix/glob64.c
+++ b/posix/glob64.c
@@ -20,6 +20,10 @@
#include <glob.h>
#include <errno.h>
+#ifdef GLOB_ATTRIBUTE
+# define GLOB_ATTRIBUTE
+#endif
+
/* Do glob searching for PATTERN, placing results in PGLOB.
The bits defined above may be set in FLAGS.
If a directory cannot be opened or read and ERRFUNC is not nil,
@@ -29,6 +33,7 @@
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
Otherwise, `glob' returns zero. */
int
+GLOB_ATTRIBUTE
glob64 (const char *pattern, int flags,
int (*errfunc) (const char *, int), glob64_t *pglob)
{
diff --git a/posix/tst-glob_lstat_compat.c b/posix/tst-glob_lstat_compat.c
new file mode 100644
index 0000000..c5b9a27
--- /dev/null
+++ b/posix/tst-glob_lstat_compat.c
@@ -0,0 +1,263 @@
+/* Test glob compat symbol which avoid call GLOB_ALTDIRFUNC/gl_lstat.
+ 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 <glob.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>
+
+#include <shlib-compat.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27)
+
+__typeof (glob) glob;
+compat_symbol_reference (libc, glob, glob, GLIBC_2_0);
+
+/* Compat glob should not call gl_lstat since for some old binaries it
+ might be unitialized (for instance GNUmake). Check if it is indeed
+ not called. */
+static bool stat_called;
+static bool lstat_called;
+
+static struct
+{
+ const char *name;
+ int level;
+ int type;
+} filesystem[] =
+{
+ { ".", 1, DT_DIR },
+ { "..", 1, DT_DIR },
+ { "dir1lev1", 1, DT_UNKNOWN },
+ { ".", 2, DT_DIR },
+ { "..", 2, DT_DIR },
+ { "file1lev2", 2, DT_REG },
+ { "file2lev2", 2, DT_REG },
+};
+static const size_t nfiles = sizeof (filesystem) / sizeof (filesystem [0]);
+
+typedef struct
+{
+ int level;
+ int idx;
+ struct dirent d;
+ char room_for_dirent[NAME_MAX];
+} my_DIR;
+
+static long int
+find_file (const char *s)
+{
+ int level = 1;
+ long int idx = 0;
+
+ while (s[0] == '/')
+ {
+ if (s[1] == '\0')
+ {
+ s = ".";
+ break;
+ }
+ ++s;
+ }
+
+ if (strcmp (s, ".") == 0)
+ return 0;
+
+ if (s[0] == '.' && s[1] == '/')
+ s += 2;
+
+ while (*s != '\0')
+ {
+ char *endp = strchrnul (s, '/');
+
+ while (idx < nfiles && filesystem[idx].level >= level)
+ {
+ if (filesystem[idx].level == level
+ && memcmp (s, filesystem[idx].name, endp - s) == 0
+ && filesystem[idx].name[endp - s] == '\0')
+ break;
+ ++idx;
+ }
+
+ if (idx == nfiles || filesystem[idx].level < level)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ if (*endp == '\0')
+ return idx + 1;
+
+ if (filesystem[idx].type != DT_DIR
+ && (idx + 1 >= nfiles
+ || filesystem[idx].level >= filesystem[idx + 1].level))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+
+ ++idx;
+
+ s = endp + 1;
+ ++level;
+ }
+
+ errno = ENOENT;
+ return -1;
+}
+
+static void *
+my_opendir (const char *s)
+{
+ long int idx = find_file (s);
+ if (idx == -1 || filesystem[idx].type != DT_DIR)
+ return NULL;
+
+ my_DIR *dir = malloc (sizeof (my_DIR));
+ if (dir == NULL)
+ FAIL_EXIT1 ("cannot allocate directory handle");
+
+ dir->level = filesystem[idx].level;
+ dir->idx = idx;
+
+ return dir;
+}
+
+static struct dirent *
+my_readdir (void *gdir)
+{
+ my_DIR *dir = gdir;
+
+ if (dir->idx == -1)
+ return NULL;
+
+ while (dir->idx < nfiles && filesystem[dir->idx].level > dir->level)
+ ++dir->idx;
+
+ if (dir->idx == nfiles || filesystem[dir->idx].level < dir->level)
+ {
+ dir->idx = -1;
+ return NULL;
+ }
+
+ dir->d.d_ino = 1; /* glob should not skip this entry. */
+
+#ifdef _DIRENT_HAVE_D_TYPE
+ dir->d.d_type = filesystem[dir->idx].type;
+#endif
+
+ strcpy (dir->d.d_name, filesystem[dir->idx].name);
+
+ ++dir->idx;
+
+ return &dir->d;
+}
+
+static void
+my_closedir (void *dir)
+{
+ free (dir);
+}
+
+static int
+my_stat (const char *name, struct stat *st)
+{
+ stat_called = true;
+
+ long int idx = find_file (name);
+ if (idx == -1)
+ return -1;
+
+ memset (st, '\0', sizeof (*st));
+
+ if (filesystem[idx].type == DT_UNKNOWN)
+ st->st_mode = DTTOIF (idx + 1 < nfiles
+ && filesystem[idx].level < filesystem[idx + 1].level
+ ? DT_DIR : DT_REG) | 0777;
+ else
+ st->st_mode = DTTOIF (filesystem[idx].type) | 0777;
+ return 0;
+}
+
+static int
+my_lstat (const char *name, struct stat *st)
+{
+ lstat_called = true;
+
+ long int idx = find_file (name);
+ if (idx == -1)
+ return -1;
+
+ memset (st, '\0', sizeof (*st));
+
+ if (filesystem[idx].type == DT_UNKNOWN)
+ st->st_mode = DTTOIF (idx + 1 < nfiles
+ && filesystem[idx].level < filesystem[idx + 1].level
+ ? DT_DIR : DT_REG) | 0777;
+ else
+ st->st_mode = DTTOIF (filesystem[idx].type) | 0777;
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ glob_t gl;
+
+ memset (&gl, '\0', sizeof (gl));
+
+ gl.gl_closedir = my_closedir;
+ gl.gl_readdir = my_readdir;
+ gl.gl_opendir = my_opendir;
+ gl.gl_lstat = my_lstat;
+ gl.gl_stat = my_stat;
+
+ int flags = GLOB_ALTDIRFUNC;
+
+ stat_called = false;
+ lstat_called = false;
+
+ TEST_VERIFY_EXIT (glob ("*/file1lev2", flags, NULL, &gl) == 0);
+ TEST_VERIFY_EXIT (gl.gl_pathc == 1);
+ TEST_VERIFY_EXIT (strcmp (gl.gl_pathv[0], "dir1lev1/file1lev2") == 0);
+
+ TEST_VERIFY_EXIT (stat_called == true);
+ TEST_VERIFY_EXIT (lstat_called == false);
+
+ return 0;
+}
+
+#else /* TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) */
+
+static int
+do_test (void)
+{
+ return 77;
+}
+#endif
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 81e4fe9..e7438c5 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2103,3 +2103,6 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c
new file mode 100644
index 0000000..a76471d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c
@@ -0,0 +1,2 @@
+#define GLOB_LSTAT_VERSION GLIBC_2_1
+#include <sysdeps/unix/sysv/linux/glob-lstat-compat.c>
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index fab7331..4836ea0 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2014,6 +2014,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/alpha/oldglob.c b/sysdeps/unix/sysv/linux/alpha/oldglob.c
index 988c92b..b54624c 100644
--- a/sysdeps/unix/sysv/linux/alpha/oldglob.c
+++ b/sysdeps/unix/sysv/linux/alpha/oldglob.c
@@ -59,7 +59,9 @@ __old_glob (const char *pattern, int flags,
correct.gl_closedir = pglob->gl_closedir;
correct.gl_readdir = pglob->gl_readdir;
correct.gl_opendir = pglob->gl_opendir;
- correct.gl_lstat = pglob->gl_lstat;
+ /* Set gl_lstat and gl_stat for both gl_stat for compatibility with old
+ implementation that did not follow dangling symlinks. */
+ correct.gl_lstat = pglob->gl_stat;
correct.gl_stat = pglob->gl_stat;
result = glob (pattern, flags, errfunc, &correct);
@@ -72,7 +74,7 @@ __old_glob (const char *pattern, int flags,
pglob->gl_closedir = correct.gl_closedir;
pglob->gl_readdir = correct.gl_readdir;
pglob->gl_opendir = correct.gl_opendir;
- pglob->gl_lstat = correct.gl_lstat;
+ /* Only need to restore gl_stat. */
pglob->gl_stat = correct.gl_stat;
return result;
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index d2a206a..5b70e1b 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -104,6 +104,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/alpha/glob.c b/sysdeps/unix/sysv/linux/glob-lstat-compat.c
similarity index 50%
rename from sysdeps/unix/sysv/linux/alpha/glob.c
rename to sysdeps/unix/sysv/linux/glob-lstat-compat.c
index 1b813c1..9867e2f 100644
--- a/sysdeps/unix/sysv/linux/alpha/glob.c
+++ b/sysdeps/unix/sysv/linux/glob-lstat-compat.c
@@ -1,4 +1,6 @@
-/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.
+ Linux version which handles LFS when required.
+ 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
@@ -12,36 +14,34 @@
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
+ License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#define glob64 __no_glob64_decl
-#define globfree64 __no_globfree64_decl
-
-#include <sys/types.h>
-#include <glob.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
#include <shlib-compat.h>
-/* For Linux/Alpha we have to make the glob symbols versioned. */
-#define glob(pattern, flags, errfunc, pglob) \
- __new_glob (pattern, flags, errfunc, pglob)
-#define globfree(pglob) \
- __new_globfree (pglob)
+#define glob64 __no_glob64_decl
+#include <glob.h>
+#undef glob64
-/* We need prototypes for these new names. */
-extern int __new_glob (const char *__pattern, int __flags,
- int (*__errfunc) (const char *, int),
- glob_t *__pglob);
-extern void __new_globfree (glob_t *__pglob);
+#define __glob __glob_lstat_compat
-#include <posix/glob.c>
+#define GLOB_ATTRIBUTE attribute_compat_text_section
-#undef glob
-#undef globfree
-#undef glob64
-#undef globfree64
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC. */
+#define GLOB_NO_LSTAT
-versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);
-libc_hidden_ver (__new_glob, glob)
+#include <posix/glob.c>
-weak_alias (__new_glob, glob64)
+#ifndef GLOB_LSTAT_VERSION
+# define GLOB_LSTAT_VERSION GLIBC_2_0
+#endif
+
+#if SHLIB_COMPAT(libc, GLOB_LSTAT_VERSION, GLIBC_2_27)
+compat_symbol (libc, __glob_lstat_compat, glob, GLOB_LSTAT_VERSION);
+# if XSTAT_IS_XSTAT64
+strong_alias (__glob_lstat_compat, __glob64_lstat_compat)
+compat_symbol (libc, __glob64_lstat_compat, glob64, GLOB_LSTAT_VERSION);
+# endif
+#endif
diff --git a/sysdeps/unix/sysv/linux/glob.c b/sysdeps/unix/sysv/linux/glob.c
index 057ae7f..e354799 100644
--- a/sysdeps/unix/sysv/linux/glob.c
+++ b/sysdeps/unix/sysv/linux/glob.c
@@ -20,9 +20,12 @@
#include <kernel_stat.h>
#define glob64 __no_glob64_decl
+#define __glob64 __no___glob64_decl
#include <posix/glob.c>
#undef glob64
+#undef __glob64
#if XSTAT_IS_XSTAT64
-weak_alias (glob, glob64)
+strong_alias (__glob, __glob64)
+versioned_symbol (libc, __glob64, glob64, GLIBC_2_27);
#endif
diff --git a/sysdeps/unix/sysv/linux/glob64-lstat-compat.c b/sysdeps/unix/sysv/linux/glob64-lstat-compat.c
new file mode 100644
index 0000000..f4e468d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/glob64-lstat-compat.c
@@ -0,0 +1,51 @@
+/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.
+ Linux version which handles LFS when required.
+ 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 <sys/stat.h>
+#include <kernel_stat.h>
+
+#if !XSTAT_IS_XSTAT64
+# include <glob.h>
+# include <dirent.h>
+# include <sys/stat.h>
+# include <shlib-compat.h>
+
+# define dirent dirent64
+# define __readdir(dirp) __readdir64 (dirp)
+
+# define glob_t glob64_t
+# define __glob __glob64_lstat_compat
+# define globfree globfree64
+
+# undef stat
+# define stat stat64
+
+# define COMPILE_GLOB64 1
+
+# define GLOB_ATTRIBUTE attribute_compat_text_section
+
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC. */
+# define GLOB_NO_LSTAT
+
+# include <posix/glob.c>
+
+# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27)
+compat_symbol (libc, __glob64_lstat_compat, glob64, GLIBC_2_2);
+# endif
+#endif /* XSTAT_IS_XSTAT64 */
diff --git a/sysdeps/unix/sysv/linux/glob64.c b/sysdeps/unix/sysv/linux/glob64.c
index 428bbac..0189d1c 100644
--- a/sysdeps/unix/sysv/linux/glob64.c
+++ b/sysdeps/unix/sysv/linux/glob64.c
@@ -28,8 +28,7 @@
# define __readdir(dirp) __readdir64 (dirp)
# define glob_t glob64_t
-# define glob(pattern, flags, errfunc, pglob) \
- __glob64 (pattern, flags, errfunc, pglob)
+# define __glob __glob64
# define globfree(pglob) globfree64 (pglob)
# undef stat
@@ -39,13 +38,13 @@
# include <posix/glob.c>
-# include "shlib-compat.h"
+# include <shlib-compat.h>
# ifdef GLOB_NO_OLD_VERSION
strong_alias (__glob64, glob64)
libc_hidden_def (glob64)
# else
-versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
+versioned_symbol (libc, __glob64, glob64, GLIBC_2_27);
libc_hidden_ver (__glob64, glob64)
# endif
#endif /* XSTAT_IS_XSTAT64 */
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 24bb730..6a2500a 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1868,6 +1868,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 12e77bd..9ab4e36 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2033,6 +2033,9 @@ GLIBC_2.26 strtof128 F
GLIBC_2.26 strtof128_l F
GLIBC_2.26 wcstof128 F
GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 62b67b8..81bb623 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1897,6 +1897,9 @@ GLIBC_2.26 strtof128 F
GLIBC_2.26 strtof128_l F
GLIBC_2.26 wcstof128 F
GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index b594ebd..5a33b57 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -105,6 +105,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index a36739d..50a86e7 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1982,6 +1982,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 16aa254..250ef30 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2103,3 +2103,6 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 907ab33..87a1dc4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1957,6 +1957,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 36ee235..f2b35f2 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1955,6 +1955,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 783aa73..e119842 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1953,6 +1953,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index e1275df..67f10f5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1948,6 +1948,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index be25228..c599dd9 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2144,3 +2144,6 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/oldglob.c b/sysdeps/unix/sysv/linux/oldglob.c
index 5402450..a034c2d 100644
--- a/sysdeps/unix/sysv/linux/oldglob.c
+++ b/sysdeps/unix/sysv/linux/oldglob.c
@@ -21,7 +21,7 @@ libc_hidden_proto (__old_glob64);
#define __readdir(dirp) __old_readdir64 (dirp)
#define glob_t glob64_t
-#define glob(pattern, flags, errfunc, pglob) \
+#define __glob(pattern, flags, errfunc, pglob) \
__old_glob64 (pattern, flags, errfunc, pglob)
#define globfree(pglob) globfree64(pglob)
@@ -33,6 +33,9 @@ libc_hidden_proto (__old_glob64);
#undef __stat
#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC. */
+#define GLOB_NO_LSTAT
+
#define GLOB_ATTRIBUTE attribute_compat_text_section
#include <posix/glob.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index e213895..385409a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1986,6 +1986,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index d25aefd..e99cb45 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1991,6 +1991,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 51a8d19..173672a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2198,3 +2198,6 @@ GLIBC_2.26 strtof128 F
GLIBC_2.26 strtof128_l F
GLIBC_2.26 wcstof128 F
GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 5eb056b..8a65443 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -105,6 +105,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 _Exit F
GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 63d33e8..271eccc 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1986,6 +1986,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index b1b2b29..8b96e16 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1887,6 +1887,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index f3a70a0..0f840e6 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1872,6 +1872,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 8c4c2e5..7f7449f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1978,6 +1978,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 1653164..a50485e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1916,6 +1916,9 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
index 41647d4..38a96d3 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2110,3 +2110,6 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index 1088923..572b917 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2110,3 +2110,6 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index 41647d4..38a96d3 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2110,3 +2110,6 @@ GLIBC_2.26 preadv64v2 F
GLIBC_2.26 pwritev2 F
GLIBC_2.26 pwritev64v2 F
GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 8bff2b2..b83d25c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1874,6 +1874,9 @@ GLIBC_2.26 strtof128 F
GLIBC_2.26 strtof128_l F
GLIBC_2.26 wcstof128 F
GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index d91a038..cba1d59 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2117,3 +2117,6 @@ GLIBC_2.26 strtof128 F
GLIBC_2.26 strtof128_l F
GLIBC_2.26 wcstof128 F
GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
--
2.7.4