]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Use __fstat64_time64 in __fts64_children_time64 (bug 33653)
authorAndreas Schwab <schwab@suse.de>
Thu, 20 Nov 2025 11:16:15 +0000 (12:16 +0100)
committerAndreas Schwab <schwab@suse.de>
Thu, 20 Nov 2025 13:33:59 +0000 (14:33 +0100)
Make sure that fts_safe_changedir can handle a directory with a time stamp
after y2038.

io/Makefile
io/fts.c
io/fts64-time64.c
io/fts64.c
io/tst-fts-time64-y2038.c [new file with mode: 0644]
io/tst-fts.c

index 435f5a994f3b12de7d77b721025d033d6b09be08..269a3151a2f822952b8bfc288a0d9777ff4d6077 100644 (file)
@@ -235,6 +235,7 @@ tests := \
 tests-time64 := \
   tst-fcntl-time64 \
   tst-fts-time64 \
+  tst-fts-time64-y2038 \
   tst-futimens-time64 \
   tst-futimes-time64\
   tst-futimesat-time64 \
index d03b059177713dca1ca8be7824a49038e8a2c068..674a98530d07842b283231758283f4d9cbdd797d 100644 (file)
--- a/io/fts.c
+++ b/io/fts.c
@@ -85,6 +85,7 @@ static char sccsid[] = "@(#)fts.c     8.6 (Berkeley) 8/14/94";
 # define STRUCT_STAT stat
 # define STAT __stat
 # define LSTAT __lstat
+# define FSTAT __fstat
 #endif
 
 static FTSENTRY        *fts_alloc (FTSOBJ *, const char *, size_t);
@@ -1111,14 +1112,14 @@ static int
 fts_safe_changedir (FTSOBJ *sp, FTSENTRY *p, int fd, const char *path)
 {
        int ret, oerrno, newfd;
-       struct stat64 sb;
+       struct STRUCT_STAT sb;
 
        newfd = fd;
        if (ISSET(FTS_NOCHDIR))
                return (0);
        if (fd < 0 && (newfd = __open(path, O_RDONLY, 0)) < 0)
                return (-1);
-       if (__fstat64(newfd, &sb)) {
+       if (FSTAT (newfd, &sb)) {
                ret = -1;
                goto bail;
        }
index cd36125d7d5a54229c38dbe21b7fb97102cac88b..f8b7b590a08ebdf469745220554852fc01b7a823 100644 (file)
@@ -30,6 +30,7 @@
 # define STRUCT_STAT __stat64_t64
 # define STAT __stat64_time64
 # define LSTAT __lstat64_time64
+# define FSTAT __fstat64_time64
 
 # include "fts.c"
 #endif
index 41c079b664ee734bd1f37c463a61998ee55d0c52..cf67cc19f743bb9461b107364465e0426e74d108 100644 (file)
@@ -27,5 +27,6 @@
 #define STRUCT_STAT stat64
 #define STAT __stat64
 #define LSTAT __lstat64
+#define FSTAT __fstat64
 
 #include "fts.c"
diff --git a/io/tst-fts-time64-y2038.c b/io/tst-fts-time64-y2038.c
new file mode 100644 (file)
index 0000000..bddf259
--- /dev/null
@@ -0,0 +1,3 @@
+/* Test for bug 33653 in fts_safe_changedir.  */
+#define TST_FTS_Y2038
+#include "tst-fts.c"
index d97aaef431a19117c6ccc24a3cd09c7d5792c1ea..c472c1b4cc2922eaa9297eab64c9ce2d00f1046d 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <utime.h>
 
 static void prepare (void);
 static int do_test (void);
@@ -54,6 +55,28 @@ make_dir (const char *dirname)
   add_temp_file (name);
 }
 
+#ifdef TST_FTS_Y2038
+static void
+set_time_y2038 (const char *dirname)
+{
+  char *name;
+  if (asprintf (&name, "%s/%s", fts_test_dir, dirname) < 0)
+    {
+      puts ("out of memory");
+      exit (1);
+    }
+
+  struct utimbuf ut = { 0x100000000, 0x100000000 };
+  if (utime (name, &ut) < 0)
+    {
+      printf ("cannot set time on dir \"%s\": %m\n", name);
+      exit (1);
+    }
+
+  free (name);
+}
+#endif
+
 static void
 make_file (const char *filename)
 {
@@ -108,6 +131,10 @@ prepare (void)
   make_file ("bbb/1234");
   make_file ("bbb/5678");
   make_file ("bbb/90ab");
+
+#ifdef TST_FTS_Y2038
+  set_time_y2038 ("bbb");
+#endif
 }
 
 /* Largest name wins, otherwise strcmp.  */
@@ -160,7 +187,13 @@ do_test (void)
 {
   char *paths[2] = { fts_test_dir, NULL };
   FTS *fts;
-  fts = fts_open (paths, FTS_LOGICAL, &compare_ents);
+  int flags = 0;
+  /* FTS_LOGICAL implies FTS_NOCHDIR, thus when testing for bug 33653,
+     don't use FTS_LOGICAL.  */
+#ifndef TST_FTS_Y2038
+  flags |= FTS_LOGICAL;
+#endif
+  fts = fts_open (paths, flags, &compare_ents);
   if (fts == NULL)
     {
       printf ("FAIL: fts_open: %m\n");