diff mbox series

[03/18] posix: Consolidate glob implementation

Message ID 1502463044-4042-4-git-send-email-adhemerval.zanella@linaro.org
State Superseded
Headers show
Series None | expand

Commit Message

Adhemerval Zanella Netto Aug. 11, 2017, 2:50 p.m. UTC
This patch consolidates the glob implementation.  The main changes are:

  * Remove specific defines required for multiple compilation in same
    unit (GLOB_ONLY_P, NO_GLOB_PATTERN_P and GLOB_COMPAT_BUILD).  To allow
    using the same code to build compat version on Linux, extra units are
    used instead (oldglob.c).

  * Both globfree and GNU extension glob_pattern_p are now on their own
    files.  This simplifies the creation of compat symbol when required.

  * Also similar to glob/glob64, a new globfree64 is file is added with an
    empty implementation as default.

  * On Linux all implementation now uses a default one with the exception
    of alpha (which requires specific versioning) and s390-32 (which
    different than other 32 bits with support for v2.1 symbol does not
    add a compat one).

  * Move i386 olddirent.h header to Linux default directory, since it is
    the only header with this name and it is shared among different
    architectures (and used on compat glob symbol as well).

Checked on x86_64-linux-gnu and i686-linux-gnu.

	* posix/Makefile (routines): Add globfree, globfree64, and
	glob_pattern_p.
	* posix/glob.c: Remove GLOB_ONLY_P, GLOB_COMPAT_BUILD, and
	NO_GLOB_PATTERN_P define usage.
	(globfree): Move to its own file.
	(__glob_pattern_type): Likewise.
	(__glob_pattern_p): Likewise.
	* posix/glob_internal.h: New file.
	* posix/glob_pattern_p.c: Likewise.
	* posix/globfree.c: Likewise.
	* posix/globfree64.c: Likewise.
	* sysdeps/gnu/glob64.c: Remove file.
	* sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add oldglob.
	* sysdeps/unix/sysv/linux/alpha/Makefile [$(subdir) = posix]
	(sysdep_routines): Remove rule.
	* sysdeps/unix/sysv/linux/alpha/glob.c: Remove file.
	* sysdeps/unix/sysv/linux/arm/glob64.c: Likewise.
	* sysdeps/wordsize-64/glob.c: Likewise.
	* sysdeps/unix/sysv/linux/m68k/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/wordsize-64/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/glob.c: Likewise.
	* sysdeps/wordsize-64/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/alpha/glob64.c: New file.
	* sysdeps/unix/sysv/linux/alpha/globfree.c: Likewise.
	* sysdeps/unix/sysv/linux/glob.c: Likewise.
	* sysdeps/unix/sysv/linux/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/globfree.c: Likewise.
	* sysdeps/unix/sysv/linux/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/alphasort64.c: include olddirent.h
	using relative path instead of absolute one.
	* sysdeps/unix/sysv/linux/i386/getdents64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/readdir64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/versionsort64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/olddirent.h: Move to ...
	* sysdeps/unix/sysv/linux/olddirent.h: ... here.
	* sysdeps/unix/sysv/linux/i386/glob64.c: Move to ...
	* sysdeps/unix/sysv/linux/oldglob.c: ... here.
	* sysdeps/unix/sysv/linux/i386/glob64.c: Remove file.
	* sysdeps/unix/sysv/linux/oldglob.c: New file.
	* sysdeps/unix/sysv/linux/s390/s390-32/glob64.c: New file.
	* sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c: Likewise.
---
 posix/Makefile                                     |  2 +-
 posix/glob.c                                       | 90 ++--------------------
 posix/glob_internal.h                              | 57 ++++++++++++++
 posix/glob_pattern_p.c                             | 29 +++++++
 posix/globfree.c                                   | 37 +++++++++
 posix/globfree64.c                                 | 27 +++++++
 sysdeps/gnu/glob64.c                               | 25 ------
 sysdeps/unix/sysv/linux/Makefile                   |  2 +-
 sysdeps/unix/sysv/linux/alpha/Makefile             |  4 -
 sysdeps/unix/sysv/linux/alpha/{glob.c => glob64.c} | 11 ---
 sysdeps/unix/sysv/linux/alpha/globfree.c           | 36 +++++++++
 sysdeps/unix/sysv/linux/arm/glob64.c               |  1 -
 sysdeps/unix/sysv/linux/glob.c                     | 23 ++++++
 sysdeps/unix/sysv/linux/glob64.c                   | 55 +++++++++++++
 sysdeps/unix/sysv/linux/globfree.c                 | 23 ++++++
 sysdeps/unix/sysv/linux/globfree64.c               |  0
 sysdeps/unix/sysv/linux/i386/alphasort64.c         |  2 +-
 sysdeps/unix/sysv/linux/i386/getdents64.c          |  2 +-
 sysdeps/unix/sysv/linux/i386/readdir64.c           |  2 +-
 sysdeps/unix/sysv/linux/i386/readdir64_r.c         |  2 +-
 sysdeps/unix/sysv/linux/i386/versionsort64.c       |  2 +-
 sysdeps/unix/sysv/linux/m68k/glob64.c              |  1 -
 sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c   |  1 -
 sysdeps/unix/sysv/linux/{i386 => }/olddirent.h     |  0
 .../unix/sysv/linux/{i386/glob64.c => oldglob.c}   | 53 +++----------
 sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c |  1 -
 sysdeps/unix/sysv/linux/s390/s390-32/glob64.c      | 20 +++++
 sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c     |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c     |  1 -
 sysdeps/unix/sysv/linux/wordsize-64/glob64.c       |  2 -
 sysdeps/unix/sysv/linux/x86_64/x32/glob.c          |  1 -
 sysdeps/wordsize-64/glob.c                         |  8 --
 sysdeps/wordsize-64/glob64.c                       |  1 -
 33 files changed, 335 insertions(+), 188 deletions(-)
 create mode 100644 posix/glob_internal.h
 create mode 100644 posix/glob_pattern_p.c
 create mode 100644 posix/globfree.c
 create mode 100644 posix/globfree64.c
 delete mode 100644 sysdeps/gnu/glob64.c
 rename sysdeps/unix/sysv/linux/alpha/{glob.c => glob64.c} (78%)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/globfree.c
 delete mode 100644 sysdeps/unix/sysv/linux/arm/glob64.c
 create mode 100644 sysdeps/unix/sysv/linux/glob.c
 create mode 100644 sysdeps/unix/sysv/linux/glob64.c
 create mode 100644 sysdeps/unix/sysv/linux/globfree.c
 create mode 100644 sysdeps/unix/sysv/linux/globfree64.c
 delete mode 100644 sysdeps/unix/sysv/linux/m68k/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
 rename sysdeps/unix/sysv/linux/{i386 => }/olddirent.h (100%)
 rename sysdeps/unix/sysv/linux/{i386/glob64.c => oldglob.c} (61%)
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/wordsize-64/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/glob.c
 delete mode 100644 sysdeps/wordsize-64/glob.c
 delete mode 100644 sysdeps/wordsize-64/glob64.c

-- 
2.7.4
diff mbox series

Patch

diff --git a/posix/Makefile b/posix/Makefile
index 5ebbc4e..8340549 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -45,7 +45,7 @@  routines :=								      \
 	getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid	      \
 	getresuid getresgid setresuid setresgid				      \
 	pathconf sysconf fpathconf					      \
-	glob glob64 fnmatch regex					      \
+	glob glob64 globfree globfree64 glob_pattern_p fnmatch regex	      \
 	confstr								      \
 	getopt getopt1 							      \
 	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
diff --git a/posix/glob.c b/posix/glob.c
index 5e4b7fc..dcfbc78 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -37,8 +37,6 @@ 
 
 #include <stdio.h>		/* Needed on stupid SunOS for assert.  */
 
-#ifndef GLOB_ONLY_P
-
 #include <unistd.h>
 #if !defined POSIX && defined _POSIX_VERSION
 # define POSIX
@@ -90,6 +88,8 @@ 
 
 #include <fnmatch.h>
 
+#include <glob_internal.h>
+
 #ifdef _SC_GETPW_R_SIZE_MAX
 # define GETPW_R_SIZE_MAX()	sysconf (_SC_GETPW_R_SIZE_MAX)
 #else
@@ -168,8 +168,6 @@  readdir_result_might_be_dir (struct readdir_result d)
     D_INO_TO_RESULT (source)		   \
   }
 
-#endif /* !defined GLOB_ONLY_P */
-
 /* Call gl_readdir on STREAM.  This macro can be overridden to reduce
    type safety if an old interface version needs to be supported.  */
 #ifndef GL_READDIR
@@ -252,7 +250,6 @@  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.  */
-#ifndef GLOB_COMPAT_BUILD
 static bool
 size_add_wrapv (size_t a, size_t b, size_t *r)
 {
@@ -271,7 +268,6 @@  glob_use_alloca (size_t alloca_used, size_t len)
   return (!size_add_wrapv (alloca_used, len, &size)
 	  && __libc_use_alloca (size));
 }
-#endif
 
 static int glob_in_dir (const char *pattern, const char *directory,
 			int flags, int (*errfunc) (const char *, int),
@@ -279,7 +275,6 @@  static int glob_in_dir (const char *pattern, const char *directory,
 extern int __glob_pattern_type (const char *pattern, int quote)
     attribute_hidden;
 
-#ifndef GLOB_ONLY_P
 static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
 static int collated_compare (const void *, const void *) __THROWNL;
 
@@ -308,7 +303,6 @@  next_brace_sub (const char *cp, int flags)
   return *cp != '\0' ? cp : NULL;
 }
 
-#endif /* !defined GLOB_ONLY_P */
 
 /* Do glob searching for PATTERN, placing results in PGLOB.
    The bits defined above may be set in FLAGS.
@@ -1372,26 +1366,6 @@  libc_hidden_def (glob)
 #endif
 
 
-#ifndef GLOB_ONLY_P
-
-/* Free storage allocated in PGLOB by a previous `glob' call.  */
-void
-globfree (glob_t *pglob)
-{
-  if (pglob->gl_pathv != NULL)
-    {
-      size_t i;
-      for (i = 0; i < pglob->gl_pathc; ++i)
-	free (pglob->gl_pathv[pglob->gl_offs + i]);
-      free (pglob->gl_pathv);
-      pglob->gl_pathv = NULL;
-    }
-}
-#if defined _LIBC && !defined globfree
-libc_hidden_def (globfree)
-#endif
-
-
 /* Do a collated comparison of A and B.  */
 static int
 collated_compare (const void *a, const void *b)
@@ -1467,71 +1441,23 @@  prefix_array (const char *dirname, char **array, size_t n)
   return 0;
 }
 
-
-/* We must not compile this function twice.  */
-#ifndef NO_GLOB_PATTERN_P
-int
-__glob_pattern_type (const char *pattern, int quote)
-{
-  const char *p;
-  int ret = 0;
-
-  for (p = pattern; *p != '\0'; ++p)
-    switch (*p)
-      {
-      case '?':
-      case '*':
-	return 1;
-
-      case '\\':
-	if (quote)
-	  {
-	    if (p[1] != '\0')
-	      ++p;
-	    ret |= 2;
-	  }
-	break;
-
-      case '[':
-	ret |= 4;
-	break;
-
-      case ']':
-	if (ret & 4)
-	  return 1;
-	break;
-      }
-
-  return ret;
-}
-
-/* Return nonzero if PATTERN contains any metacharacters.
-   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
-int
-__glob_pattern_p (const char *pattern, int quote)
-{
-  return __glob_pattern_type (pattern, quote) == 1;
-}
-# ifdef _LIBC
-weak_alias (__glob_pattern_p, glob_pattern_p)
-# endif
-#endif
-
-
 /* We put this in a separate function mainly to allow the memory
    allocated with alloca to be recycled.  */
 static int
 __attribute_noinline__
 link_stat (const char *dir, size_t dirlen, const char *fname,
 	       glob_t *pglob
-# if !defined _LIBC && !HAVE_FSTATAT
+# ifndef _LIBC
 		, int flags
 # endif
 		)
 {
   size_t fnamelen = strlen (fname);
-  char *fullname = __alloca (dirlen + 1 + fnamelen + 1);
+  char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1);
   struct stat st;
+# ifndef _LIBC
+  struct_stat64 st64;
+# endif
 
   mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1),
 	   fname, fnamelen + 1);
@@ -1567,8 +1493,6 @@  link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname,
 # endif
   return status == 0 || errno == EOVERFLOW;
 }
-#endif /* !defined GLOB_ONLY_P */
-
 
 /* Like `glob', but PATTERN is a final pathname component,
    and matches are searched for in DIRECTORY.
diff --git a/posix/glob_internal.h b/posix/glob_internal.h
new file mode 100644
index 0000000..d989a98
--- /dev/null
+++ b/posix/glob_internal.h
@@ -0,0 +1,57 @@ 
+/* Shared definition for glob and glob_pattern_p.
+   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/>.  */
+
+#ifndef GLOB_INTERNAL_H
+# define GLOB_INTERNAL_H
+
+static inline int
+__glob_pattern_type (const char *pattern, int quote)
+{
+  const char *p;
+  int ret = 0;
+
+  for (p = pattern; *p != '\0'; ++p)
+    switch (*p)
+      {
+      case '?':
+      case '*':
+	return 1;
+
+      case '\\':
+	if (quote)
+	  {
+	    if (p[1] != '\0')
+	      ++p;
+	    ret |= 2;
+	  }
+	break;
+
+      case '[':
+	ret |= 4;
+	break;
+
+      case ']':
+	if (ret & 4)
+	  return 1;
+	break;
+      }
+
+  return ret;
+}
+
+#endif /* GLOB_INTERNAL_H  */
diff --git a/posix/glob_pattern_p.c b/posix/glob_pattern_p.c
new file mode 100644
index 0000000..6e451f2
--- /dev/null
+++ b/posix/glob_pattern_p.c
@@ -0,0 +1,29 @@ 
+/* Return nonzero if PATTERN contains any metacharacters.
+   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 "glob_internal.h"
+
+/* Return nonzero if PATTERN contains any metacharacters.
+   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
+int
+__glob_pattern_p (const char *pattern, int quote)
+{
+  return __glob_pattern_type (pattern, quote) == 1;
+}
+weak_alias (__glob_pattern_p, glob_pattern_p)
diff --git a/posix/globfree.c b/posix/globfree.c
new file mode 100644
index 0000000..4ebd142
--- /dev/null
+++ b/posix/globfree.c
@@ -0,0 +1,37 @@ 
+/* Frees the dynamically allocated storage from an earlier call to glob.
+   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 <stdlib.h>
+
+/* Free storage allocated in PGLOB by a previous `glob' call.  */
+void
+globfree (glob_t *pglob)
+{
+  if (pglob->gl_pathv != NULL)
+    {
+      size_t i;
+      for (i = 0; i < pglob->gl_pathc; ++i)
+	free (pglob->gl_pathv[pglob->gl_offs + i]);
+      free (pglob->gl_pathv);
+      pglob->gl_pathv = NULL;
+    }
+}
+#ifndef globfree
+libc_hidden_def (globfree)
+#endif
diff --git a/posix/globfree64.c b/posix/globfree64.c
new file mode 100644
index 0000000..cce288e
--- /dev/null
+++ b/posix/globfree64.c
@@ -0,0 +1,27 @@ 
+/* Frees the dynamically allocated storage from an earlier call to glob.
+   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 <stdlib.h>
+
+/* Free storage allocated in PGLOB by a previous `glob' call.  */
+void
+globfree64 (glob64_t *pglob)
+{
+}
+libc_hidden_def (globfree64)
diff --git a/sysdeps/gnu/glob64.c b/sysdeps/gnu/glob64.c
deleted file mode 100644
index d1e4e6f..0000000
--- a/sysdeps/gnu/glob64.c
+++ /dev/null
@@ -1,25 +0,0 @@ 
-#include <dirent.h>
-#include <glob.h>
-#include <sys/stat.h>
-
-#define dirent dirent64
-#define __readdir(dirp) __readdir64 (dirp)
-
-#define glob_t glob64_t
-#define glob(pattern, flags, errfunc, pglob) \
-  glob64 (pattern, flags, errfunc, pglob)
-#define globfree(pglob) globfree64 (pglob)
-
-#undef stat
-#define stat stat64
-#undef __stat
-#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
-
-#define NO_GLOB_PATTERN_P 1
-
-#define COMPILE_GLOB64	1
-
-#include <posix/glob.c>
-
-libc_hidden_def (glob64)
-libc_hidden_def (globfree64)
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 9d6a2de..8847751 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -162,7 +162,7 @@  endif
 ifeq ($(subdir),posix)
 sysdep_headers += bits/initspin.h
 
-sysdep_routines += sched_getcpu
+sysdep_routines += sched_getcpu oldglob
 
 tests += tst-affinity tst-affinity-pid
 
diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
index 47bd189..50f4fb1 100644
--- a/sysdeps/unix/sysv/linux/alpha/Makefile
+++ b/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -1,7 +1,3 @@ 
-ifeq ($(subdir),posix)
-sysdep_routines += oldglob
-endif
-
 ifeq ($(subdir),stdlib)
 gen-as-const-headers += ucontext-offsets.sym
 endif
diff --git a/sysdeps/unix/sysv/linux/alpha/glob.c b/sysdeps/unix/sysv/linux/alpha/glob64.c
similarity index 78%
rename from sysdeps/unix/sysv/linux/alpha/glob.c
rename to sysdeps/unix/sysv/linux/alpha/glob64.c
index 2d7d287..dd86d15 100644
--- a/sysdeps/unix/sysv/linux/alpha/glob.c
+++ b/sysdeps/unix/sysv/linux/alpha/glob64.c
@@ -16,36 +16,25 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #define glob64 __no_glob64_decl
-#define globfree64 __no_globfree64_decl
 
-#include <sys/types.h>
 #include <glob.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)
 
 /* 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);
 
 #include <posix/glob.c>
 
 #undef glob
-#undef globfree
 #undef glob64
-#undef globfree64
 
 versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);
-versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
 libc_hidden_ver (__new_glob, glob)
-libc_hidden_ver (__new_globfree, globfree)
 
 weak_alias (__new_glob, glob64)
-weak_alias (__new_globfree, globfree64)
-libc_hidden_ver (__new_globfree, globfree64)
diff --git a/sysdeps/unix/sysv/linux/alpha/globfree.c b/sysdeps/unix/sysv/linux/alpha/globfree.c
new file mode 100644
index 0000000..9d159f1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/globfree.c
@@ -0,0 +1,36 @@ 
+/* Frees the dynamically allocated storage from an earlier call to glob.
+   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/>.  */
+
+#define globfree64 __no_globfree64_decl
+
+#include <glob.h>
+#include <shlib-compat.h>
+
+#define globfree(pglob) __new_globfree (pglob)
+extern void __new_globfree (glob_t *__pglob);
+
+#include <posix/globfree.c>
+
+#undef globfree
+#undef globfree64
+
+versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
+libc_hidden_ver (__new_globfree, globfree)
+
+weak_alias (__new_globfree, globfree64)
+libc_hidden_ver (__new_globfree, globfree64)
diff --git a/sysdeps/unix/sysv/linux/arm/glob64.c b/sysdeps/unix/sysv/linux/arm/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/arm/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/glob.c b/sysdeps/unix/sysv/linux/glob.c
new file mode 100644
index 0000000..153ba8c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/glob.c
@@ -0,0 +1,23 @@ 
+/* Find pathnames matching a pattern.
+   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/types.h>
+
+#ifndef __OFF_T_MATCHES_OFF64_T
+# include <posix/glob.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/glob64.c b/sysdeps/unix/sysv/linux/glob64.c
new file mode 100644
index 0000000..6ff6611
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/glob64.c
@@ -0,0 +1,55 @@ 
+/* Find pathnames matching a pattern.
+   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/types.h>
+
+#ifdef __OFF_T_MATCHES_OFF64_T
+# define glob64 __no_glob64_decl
+# include <posix/glob.c>
+# undef glob64
+weak_alias (glob, glob64)
+#else
+# include <glob.h>
+# include <dirent.h>
+# include <sys/stat.h>
+
+# define dirent dirent64
+# define __readdir(dirp) __readdir64 (dirp)
+
+# define glob_t glob64_t
+# define glob(pattern, flags, errfunc, pglob) \
+  __glob64 (pattern, flags, errfunc, pglob)
+# define globfree(pglob) globfree64 (pglob)
+
+# undef stat
+# define stat stat64
+
+# define COMPILE_GLOB64	1
+
+# include <posix/glob.c>
+
+# 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);
+libc_hidden_ver (__glob64, glob64)
+# endif
+#endif
diff --git a/sysdeps/unix/sysv/linux/globfree.c b/sysdeps/unix/sysv/linux/globfree.c
new file mode 100644
index 0000000..d615510
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/globfree.c
@@ -0,0 +1,23 @@ 
+/* Frees the dynamically allocated storage from an earlier call to glob.
+   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/>.  */
+
+#define globfree64 __no_globfree64_decl
+#include <posix/globfree.c>
+#undef globfree64
+weak_alias (globfree, globfree64)
+libc_hidden_ver (globfree, globfree64)
diff --git a/sysdeps/unix/sysv/linux/globfree64.c b/sysdeps/unix/sysv/linux/globfree64.c
new file mode 100644
index 0000000..e69de29
diff --git a/sysdeps/unix/sysv/linux/i386/alphasort64.c b/sysdeps/unix/sysv/linux/i386/alphasort64.c
index d5fd47a..04b29b6 100644
--- a/sysdeps/unix/sysv/linux/i386/alphasort64.c
+++ b/sysdeps/unix/sysv/linux/i386/alphasort64.c
@@ -30,7 +30,7 @@  versioned_symbol (libc, __alphasort64, alphasort64, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 int
 __old_alphasort64 (const struct __old_dirent64 **a,
diff --git a/sysdeps/unix/sysv/linux/i386/getdents64.c b/sysdeps/unix/sysv/linux/i386/getdents64.c
index e8b257f..2010bbf 100644
--- a/sysdeps/unix/sysv/linux/i386/getdents64.c
+++ b/sysdeps/unix/sysv/linux/i386/getdents64.c
@@ -28,7 +28,7 @@ 
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 #define __GETDENTS __old_getdents64
 #define DIRENT_TYPE struct __old_dirent64
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64.c b/sysdeps/unix/sysv/linux/i386/readdir64.c
index f80b6a7..bd2375f 100644
--- a/sysdeps/unix/sysv/linux/i386/readdir64.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64.c
@@ -31,7 +31,7 @@  versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 #define __READDIR attribute_compat_text_section __old_readdir64
 #define __GETDENTS __old_getdents64
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
index 344fd53..8c0262d 100644
--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
@@ -31,7 +31,7 @@  versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 #define __READDIR_R attribute_compat_text_section __old_readdir64_r
 #define __GETDENTS __old_getdents64
diff --git a/sysdeps/unix/sysv/linux/i386/versionsort64.c b/sysdeps/unix/sysv/linux/i386/versionsort64.c
index 3e1c6ea..87f2f95 100644
--- a/sysdeps/unix/sysv/linux/i386/versionsort64.c
+++ b/sysdeps/unix/sysv/linux/i386/versionsort64.c
@@ -30,7 +30,7 @@  versioned_symbol (libc, __versionsort64, versionsort64, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 int
 __old_versionsort64 (const struct __old_dirent64 **a,
diff --git a/sysdeps/unix/sysv/linux/m68k/glob64.c b/sysdeps/unix/sysv/linux/m68k/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/m68k/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c b/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
deleted file mode 100644
index 33918ea..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-/* glob64 is in glob.c */
diff --git a/sysdeps/unix/sysv/linux/i386/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h
similarity index 100%
rename from sysdeps/unix/sysv/linux/i386/olddirent.h
rename to sysdeps/unix/sysv/linux/olddirent.h
diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/oldglob.c
similarity index 61%
rename from sysdeps/unix/sysv/linux/i386/glob64.c
rename to sysdeps/unix/sysv/linux/oldglob.c
index 9c7abd8..af934f9 100644
--- a/sysdeps/unix/sysv/linux/i386/glob64.c
+++ b/sysdeps/unix/sysv/linux/oldglob.c
@@ -1,5 +1,5 @@ 
-/* Two glob variants with 64-bit support, for dirent64 and __olddirent64.
-   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+/* Find pathnames matching a pattern.  Compatibility version.
+   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
@@ -16,61 +16,32 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <dirent.h>
 #include <glob.h>
-#include <sys/stat.h>
-
-#define dirent dirent64
-#define __readdir(dirp) __readdir64 (dirp)
-
-#define glob_t glob64_t
-#define glob(pattern, flags, errfunc, pglob) \
-  __glob64 (pattern, flags, errfunc, pglob)
-#define globfree(pglob) globfree64 (pglob)
-
-#undef stat
-#define stat stat64
-#undef __stat
-#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
-
-#define NO_GLOB_PATTERN_P 1
-
-#define COMPILE_GLOB64	1
-
-#include <posix/glob.c>
-
 #include "shlib-compat.h"
 
-libc_hidden_def (globfree64)
-
-versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
-libc_hidden_ver (__glob64, glob64)
-
-#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) \
+    && !defined(GLOB_NO_OLD_VERSION)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 int __old_glob64 (const char *__pattern, int __flags,
 		  int (*__errfunc) (const char *, int),
 		  glob64_t *__pglob);
 
-#undef dirent
+#define glob_t glob64_t
+#define globfree(pglob) globfree64 (pglob)
+#undef stat
+#define stat stat64
+
 #define dirent __old_dirent64
-#undef GL_READDIR
-# define GL_READDIR(pglob, stream) \
+#define GL_READDIR(pglob, stream) \
   ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
-#undef __readdir
 #define __readdir(dirp) __old_readdir64 (dirp)
-#undef glob
 #define glob(pattern, flags, errfunc, pglob) \
   __old_glob64 (pattern, flags, errfunc, pglob)
 #define convert_dirent __old_convert_dirent
-#define glob_in_dir __old_glob_in_dir
-#define GLOB_ATTRIBUTE attribute_compat_text_section
 
-#define GLOB_ONLY_P 1
-
-#define GLOB_COMPAT_BUILD 1
+#define GLOB_ATTRIBUTE attribute_compat_text_section
 
 #include <posix/glob.c>
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c b/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
new file mode 100644
index 0000000..b00dc54
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
@@ -0,0 +1,20 @@ 
+/* Find pathnames matching a pattern.  S390-32 Linux version.
+   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/>.  */
+
+#define GLOB_NO_OLD_VERSION
+#include <sysdeps/unix/sysv/linux/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c b/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
new file mode 100644
index 0000000..56d7d12
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
@@ -0,0 +1,2 @@ 
+#define GLOB_NO_OLD_VERSION
+#include <sysdeps/unix/sysv/linux/oldglob.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c b/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/glob64.c b/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
deleted file mode 100644
index eab7703..0000000
--- a/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* This file is here so sysdeps/gnu/glob64.c doesn't take precedence.  */
-#include <sysdeps/wordsize-64/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/glob.c b/sysdeps/unix/sysv/linux/x86_64/x32/glob.c
deleted file mode 100644
index e542747..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/x32/glob.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/wordsize-64/glob.c>
diff --git a/sysdeps/wordsize-64/glob.c b/sysdeps/wordsize-64/glob.c
deleted file mode 100644
index 082faf1..0000000
--- a/sysdeps/wordsize-64/glob.c
+++ /dev/null
@@ -1,8 +0,0 @@ 
-#define glob64 __no_glob64_decl
-#define globfree64 __no_globfree64_decl
-#include <posix/glob.c>
-#undef glob64
-#undef globfree64
-weak_alias (glob, glob64)
-weak_alias (globfree, globfree64)
-libc_hidden_ver (globfree, globfree64)
diff --git a/sysdeps/wordsize-64/glob64.c b/sysdeps/wordsize-64/glob64.c
deleted file mode 100644
index 33918ea..0000000
--- a/sysdeps/wordsize-64/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-/* glob64 is in glob.c */