From 223f52a6db753b37abec45cf536b6a4b2385296e Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Sun, 17 Jul 2022 22:45:36 -0700 Subject: [PATCH] Fix utime/stat for time_t > 2^32 See: #17393 --- src/library_syscall.js | 11 ++++++----- tests/stat/test_stat.c | 32 ++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/library_syscall.js b/src/library_syscall.js index 447a4b9232452..99917391616bf 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -64,11 +64,11 @@ var SyscallsLibrary = { {{{ makeSetValue('buf', C_STRUCTS.stat.st_size, 'stat.size', 'i64') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_blksize, '4096', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_blocks, 'stat.blocks', 'i32') }}}; - {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_sec, '(stat.atime.getTime() / 1000)|0', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_sec, 'Math.floor(stat.atime.getTime() / 1000)', 'i64') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_nsec, '0', 'i32') }}}; - {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_sec, '(stat.mtime.getTime() / 1000)|0', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_sec, 'Math.floor(stat.mtime.getTime() / 1000)', 'i64') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_nsec, '0', 'i32') }}}; - {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, '(stat.ctime.getTime() / 1000)|0', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, 'Math.floor(stat.ctime.getTime() / 1000)', 'i64') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_nsec, '0', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i64') }}}; return 0; @@ -954,6 +954,7 @@ var SyscallsLibrary = { return 0; }, __syscall_utimensat__sig: 'iippi', + __syscall_utimensat__deps: ['$readI53FromI64'], __syscall_utimensat: function(dirfd, path, times, flags) { path = SYSCALLS.getStr(path); #if ASSERTIONS @@ -964,11 +965,11 @@ var SyscallsLibrary = { var atime = Date.now(); var mtime = atime; } else { - var seconds = {{{ makeGetValue('times', C_STRUCTS.timespec.tv_sec, 'i32') }}}; + var seconds = {{{ makeGetValue('times', C_STRUCTS.timespec.tv_sec, 'i53') }}}; var nanoseconds = {{{ makeGetValue('times', C_STRUCTS.timespec.tv_nsec, 'i32') }}}; atime = (seconds*1000) + (nanoseconds/(1000*1000)); times += {{{ C_STRUCTS.timespec.__size__ }}}; - seconds = {{{ makeGetValue('times', C_STRUCTS.timespec.tv_sec, 'i32') }}}; + seconds = {{{ makeGetValue('times', C_STRUCTS.timespec.tv_sec, 'i53') }}}; nanoseconds = {{{ makeGetValue('times', C_STRUCTS.timespec.tv_nsec, 'i32') }}}; mtime = (seconds*1000) + (nanoseconds/(1000*1000)); } diff --git a/tests/stat/test_stat.c b/tests/stat/test_stat.c index 7d05b929d73a4..49c2daa9d998c 100644 --- a/tests/stat/test_stat.c +++ b/tests/stat/test_stat.c @@ -30,8 +30,9 @@ void create_file(const char *path, const char *buffer, int mode) { close(fd); } +#define TEST_TIME (1ll << 34) void setup() { - struct utimbuf t = {1200000000, 1200000000}; + struct utimbuf t = {TEST_TIME, TEST_TIME}; mkdir("folder", 0777); create_file("folder/file", "abcdef", 0777); @@ -51,7 +52,7 @@ void cleanup() { void test() { int err; struct stat s; - struct utimbuf t = {1200000000, 1200000000}; + struct utimbuf t = {TEST_TIME, TEST_TIME}; // non-existent err = stat("does_not_exist", &s); @@ -70,8 +71,11 @@ void test() { assert(s.st_rdev == 0); #endif assert(s.st_size); - assert(s.st_atime == 1200000000); - assert(s.st_mtime == 1200000000); + printf("TEST_TIME: %llx\n", TEST_TIME); + printf("s.st_atime: %llx\n", s.st_atime); + printf("s.st_mtime: %llx\n", s.st_mtime); + assert(s.st_atime == TEST_TIME); + assert(s.st_mtime == TEST_TIME); assert(s.st_ctime); #ifdef __EMSCRIPTEN__ assert(s.st_blksize == 4096); @@ -92,8 +96,8 @@ void test() { assert(s.st_nlink); assert(s.st_rdev == 0); assert(s.st_size == 6); - assert(s.st_atime == 1200000000); - assert(s.st_mtime == 1200000000); + assert(s.st_atime == TEST_TIME); + assert(s.st_mtime == TEST_TIME); assert(s.st_ctime); #ifdef __EMSCRIPTEN__ assert(s.st_blksize == 4096); @@ -110,8 +114,8 @@ void test() { assert(s.st_nlink); assert(s.st_rdev == 0); assert(s.st_size == 6); - assert(s.st_atime == 1200000000); - assert(s.st_mtime == 1200000000); + assert(s.st_atime == TEST_TIME); + assert(s.st_mtime == TEST_TIME); assert(s.st_ctime); #ifdef __EMSCRIPTEN__ assert(s.st_blksize == 4096); @@ -152,8 +156,8 @@ void test() { assert(s.st_nlink); assert(s.st_rdev == 0); assert(s.st_size == 6); - assert(s.st_atime == 1200000000); - assert(s.st_mtime == 1200000000); + assert(s.st_atime == TEST_TIME); + assert(s.st_mtime == TEST_TIME); assert(s.st_ctime); #ifdef __EMSCRIPTEN__ assert(s.st_blksize == 4096); @@ -170,8 +174,8 @@ void test() { assert(s.st_nlink); assert(s.st_rdev == 0); assert(s.st_size == 4); // strlen("file") - assert(s.st_atime != 1200000000); // should NOT match the utime call we did for dir/file - assert(s.st_mtime != 1200000000); + assert(s.st_atime != TEST_TIME); // should NOT match the utime call we did for dir/file + assert(s.st_mtime != TEST_TIME); assert(s.st_ctime); #ifdef __EMSCRIPTEN__ assert(s.st_blksize == 4096); @@ -183,11 +187,11 @@ void test() { utime("folder/subdir", &t); create_file("folder/subdir/file", "abcdef", 0777); err = stat("folder/subdir", &s); - assert(s.st_mtime != 1200000000); + assert(s.st_mtime != TEST_TIME); utime("folder/subdir", &t); unlink("folder/subdir/file"); err = stat("folder/subdir", &s); - assert(s.st_mtime != 1200000000); + assert(s.st_mtime != TEST_TIME); puts("success"); }