summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--io/Makefile1
-rw-r--r--io/fts.c5
-rw-r--r--io/fts64-time64.c1
-rw-r--r--io/fts64.c1
-rw-r--r--io/tst-fts-time64-y2038.c3
-rw-r--r--io/tst-fts.c35
6 files changed, 43 insertions, 3 deletions
diff --git a/io/Makefile b/io/Makefile
index 435f5a994f..269a3151a2 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -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 \
diff --git a/io/fts.c b/io/fts.c
index d03b059177..674a98530d 100644
--- 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;
}
diff --git a/io/fts64-time64.c b/io/fts64-time64.c
index cd36125d7d..f8b7b590a0 100644
--- a/io/fts64-time64.c
+++ b/io/fts64-time64.c
@@ -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
diff --git a/io/fts64.c b/io/fts64.c
index 41c079b664..cf67cc19f7 100644
--- a/io/fts64.c
+++ b/io/fts64.c
@@ -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
index 0000000000..bddf259b0c
--- /dev/null
+++ b/io/tst-fts-time64-y2038.c
@@ -0,0 +1,3 @@
+/* Test for bug 33653 in fts_safe_changedir. */
+#define TST_FTS_Y2038
+#include "tst-fts.c"
diff --git a/io/tst-fts.c b/io/tst-fts.c
index d97aaef431..c472c1b4cc 100644
--- a/io/tst-fts.c
+++ b/io/tst-fts.c
@@ -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");