summary refs log tree commit diff
path: root/posix
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-03-02 20:17:07 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-06-15 10:42:11 -0300
commit84f7ce84474c1648ce96884f1c91ca7b97ca3fc2 (patch)
tree4a19687d260d69a380414d41a592fb261841e5cd /posix
parent47f24c21ee38701ae275aa9e451f70fa3e77478c (diff)
downloadglibc-84f7ce84474c1648ce96884f1c91ca7b97ca3fc2.tar.gz
glibc-84f7ce84474c1648ce96884f1c91ca7b97ca3fc2.tar.xz
glibc-84f7ce84474c1648ce96884f1c91ca7b97ca3fc2.zip
posix: Add glob64 with 64-bit time_t support
The glob might pass a different stat struct for gl_stat and gl_lstat
when GLOB_ALTDIRFUNC is used.  This requires add a new 64-bit time
version that also uses 64-bit time stat functions.

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

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'posix')
-rw-r--r--posix/Makefile4
-rw-r--r--posix/glob.c46
-rw-r--r--posix/glob.h22
-rw-r--r--posix/glob64-lstat-compat.c3
-rw-r--r--posix/glob64-time64.c49
-rw-r--r--posix/globfree64-time64.c30
6 files changed, 131 insertions, 23 deletions
diff --git a/posix/Makefile b/posix/Makefile
index fa0dc0ea20..c8c538fcee 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -67,7 +67,9 @@ routines :=								      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
 	streams-compat \
 	shm-directory                                                         \
-	execveat
+	execveat \
+	glob64-time64 \
+	globfree64-time64
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
diff --git a/posix/glob.c b/posix/glob.c
index 32c88e5d15..593a4c358f 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -59,25 +59,37 @@
 # define readdir(str) __readdir64 (str)
 # define getpwnam_r(name, bufp, buf, len, res) \
     __getpwnam_r (name, bufp, buf, len, res)
-# define struct_stat64          struct stat64
 # define FLEXIBLE_ARRAY_MEMBER
+# ifndef struct_stat
+#  define struct_stat           struct stat
+# endif
+# ifndef struct_stat64
+#  define struct_stat64         struct stat64
+# endif
+# ifndef GLOB_LSTAT
+#  define GLOB_LSTAT            gl_lstat
+# endif
+# ifndef GLOB_STAT64
+#  define GLOB_STAT64           __stat64
+# endif
+# ifndef GLOB_LSTAT64
+#  define GLOB_LSTAT64          __lstat64
+# endif
 # 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)
-# if defined _WIN32 && !defined __CYGWIN__
-   /* Avoid GCC or clang warning.  The original __stat64 macro is unused.  */
-#  undef __stat64
-# endif
-# define __stat64(fname, buf)   stat (fname, buf)
 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
-# define struct_stat64          struct stat
 # ifndef __MVS__
 #  define __alloca              alloca
 # endif
 # define __readdir              readdir
 # define COMPILE_GLOB64
+# define struct_stat            struct stat
+# define struct_stat64          struct stat
+# define GLOB_LSTAT             gl_lstat
+# define GLOB_STAT64            stat
+# define GLOB_LSTAT64           lstat
 #endif /* _LIBC */
 
 #include <fnmatch.h>
@@ -196,22 +208,14 @@ 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_stat st;
     struct_stat64 st64;
   } ust;
   return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
-          ? pglob->GL_LSTAT (fullname, &ust.st)
-          : LSTAT64 (fullname, &ust.st64));
+          ? pglob->GLOB_LSTAT (fullname, &ust.st)
+          : GLOB_LSTAT64 (fullname, &ust.st64));
 }
 
 /* Set *R = A + B.  Return true if the answer is mathematically
@@ -249,11 +253,11 @@ static int collated_compare (const void *, const void *) __THROWNL;
 static bool
 is_dir (char const *filename, int flags, glob_t const *pglob)
 {
-  struct stat st;
+  struct_stat st;
   struct_stat64 st64;
   return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
           ? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
-          : __stat64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
+          : GLOB_STAT64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
 }
 
 /* Find the end of the sub-pattern in a brace expression.  */
diff --git a/posix/glob.h b/posix/glob.h
index b5686600c7..700aeb2392 100644
--- a/posix/glob.h
+++ b/posix/glob.h
@@ -150,20 +150,42 @@ extern int glob (const char *__restrict __pattern, int __flags,
 /* Free storage allocated in PGLOB by a previous `glob' call.  */
 extern void globfree (glob_t *__pglob) __THROW;
 #else
+# ifdef __USE_TIME_BITS64
+extern int __REDIRECT_NTHNL (glob, (const char *__restrict __pattern,
+				    int __flags,
+				    int (*__errfunc) (const char *, int),
+				    glob_t *__restrict __pglob),
+			     __glob64_time64);
+
+extern void __REDIRECT_NTH (globfree, (glob_t *__pglob),
+			    __globfree64_time64);
+# else
 extern int __REDIRECT_NTHNL (glob, (const char *__restrict __pattern,
 				    int __flags,
 				    int (*__errfunc) (const char *, int),
 				    glob_t *__restrict __pglob), glob64);
 
 extern void __REDIRECT_NTH (globfree, (glob_t *__pglob), globfree64);
+# endif
 #endif
 
 #ifdef __USE_LARGEFILE64
+# ifdef __USE_TIME_BITS64
+extern int __REDIRECT_NTHNL (glob64, (const char *__restrict __pattern,
+				      int __flags,
+				      int (*__errfunc) (const char *, int),
+				      glob64_t *__restrict __pglob),
+			     __glob64_time64);
+
+extern void __REDIRECT_NTH (globfree64, (glob64_t *__pglob),
+			    __globfree64_time64);
+# else
 extern int glob64 (const char *__restrict __pattern, int __flags,
 		   int (*__errfunc) (const char *, int),
 		   glob64_t *__restrict __pglob) __THROWNL;
 
 extern void globfree64 (glob64_t *__pglob) __THROW;
+# endif
 #endif
 
 
diff --git a/posix/glob64-lstat-compat.c b/posix/glob64-lstat-compat.c
index bd81a1e390..e90d4ae93e 100644
--- a/posix/glob64-lstat-compat.c
+++ b/posix/glob64-lstat-compat.c
@@ -28,7 +28,8 @@
 # define GLOB_ATTRIBUTE attribute_compat_text_section
 
 /* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */
-# define GLOB_NO_LSTAT
+# define GLOB_LSTAT   gl_stat
+# define GLOB_LSTAT64 __stat64
 
 # include <posix/glob64.c>
 
diff --git a/posix/glob64-time64.c b/posix/glob64-time64.c
new file mode 100644
index 0000000000..b0f8facd84
--- /dev/null
+++ b/posix/glob64-time64.c
@@ -0,0 +1,49 @@
+/* Long File Support glob with 64-bit time support.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <glob.h>
+#include <stddef.h>
+
+#if __TIMESIZE != 64
+
+/* 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,
+   it is called with the pathname that caused the error, and the
+   `errno' value from the failing call; if it returns non-zero
+   `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
+   If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
+   Otherwise, `glob' returns zero.  */
+int
+__glob64_time64 (const char *pattern, int flags,
+		 int (*errfunc) (const char *, int), glob64_time64_t *pglob)
+{
+  if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return GLOB_NOSYS;
+}
+
+stub_warning (glob64)
+
+#endif
diff --git a/posix/globfree64-time64.c b/posix/globfree64-time64.c
new file mode 100644
index 0000000000..1fc2085f3f
--- /dev/null
+++ b/posix/globfree64-time64.c
@@ -0,0 +1,30 @@
+/* Long File Support globfree with 64-bit time support.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <glob.h>
+
+#if __TIMESIZE != 64
+
+/* Free storage allocated in PGLOB by a previous `glob' call.  */
+void
+__globfree64_time64 (glob64_time64_t *pglob)
+{
+}
+libc_hidden_def (__globfree64_time64)
+
+#endif