diff --git a/INSTALL.md b/INSTALL.md index 9f5eafd..6dd5d2b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -166,19 +166,6 @@ Notes In this case, the utility library will not be built from source, and other components will link to the specified library instead. - ### Targeting 32-bit Platforms - - BookmarkFS requires 64-bit `off_t` and `time_t`, which may not be supported - on 32-bit platforms (e.g., i386 FreeBSD does not support 64-bit `time_t`). - - If using Autoconf 2.72 or later, the configuration script automatically - performs checks and defines necessary macros, and fails if unsupported. - With legacy Autoconf, only `off_t` is checked. - - To manually configure 64-bit `time_t`, add preprocessor flags - `-D_TIME_BITS=64` (or something equivalent, depending on the toolchain). - If unsupported, `make` will fail. - ### FreeBSD and GNU libiconv NOTE: You may skip this section if _not_ building the Chromium backend. diff --git a/configure.ac b/configure.ac index 48f87db..7d5e419 100644 --- a/configure.ac +++ b/configure.ac @@ -196,18 +196,7 @@ AS_VAR_IF([ac_have_largefile], [no], [ ])) ]) -m4_version_prereq([2.72], [ - AC_SYS_YEAR2038 - AS_VAR_IF([ac_have_year2038], [no], [ - AC_MSG_ERROR(m4_normalize([ - 64-bit time_t is unsupported on this platform. - ])) - ]) -], [ - dnl fallback to compile-time check... - AX_COMPILE_CHECK_SIZEOF([time_t]) -]) - +AX_COMPILE_CHECK_SIZEOF([time_t]) AX_COMPILE_CHECK_SIZEOF([uintptr_t], [#include ]) # -- Output -- diff --git a/src/backend_chromium.c b/src/backend_chromium.c index 5087525..2e31521 100644 --- a/src/backend_chromium.c +++ b/src/backend_chromium.c @@ -58,17 +58,14 @@ #include "watcher.h" #include "xstd.h" -#if defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T != 8) -# error "64-bit time_t is required" -#endif - #define BACKEND_FILENAME_GUID ( 1u << 16 ) -// Chromium uses Windows FILETIME epoch instead of Unix epoch. +// Chromium uses Windows FILETIME epoch, which is +// `((1970 - 1601) * 365 + 89) * 24 * 3600` seconds before the Unix epoch. // // See Chromium source code: /base/time/time.h // (`base::Time::kTimeTToMicrosecondsOffset`) -#define EPOCH_DIFF ( (time_t)((1970 - 1601) * 365 + 89) * 24 * 3600 ) +#define EPOCH_DIFF INT64_C(11644473600) #define BOOKMARKS_ROOT_ID 0 @@ -387,7 +384,7 @@ build_tsnode ( ts = &now; } - time_t secs = ts->tv_sec + EPOCH_DIFF; + int64_t secs = ts->tv_sec + EPOCH_DIFF; int64_t microsecs = secs * 1000000 + ts->tv_nsec / 1000; char buf[32]; @@ -1461,12 +1458,17 @@ parse_ts ( } if (buf != NULL) { - time_t secs = microsecs / 1000000; - if (unlikely(secs < EPOCH_DIFF)) { + int64_t secs = microsecs / 1000000 - EPOCH_DIFF; + if (unlikely(secs < 0)) { // Stay away from negative tv_sec - secs = EPOCH_DIFF; + secs = 0; } - buf->tv_sec = secs - EPOCH_DIFF; +#if defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T < 8) + else if (secs > INT32_MAX) { + secs = INT32_MAX; + } +#endif + buf->tv_sec = secs; buf->tv_nsec = (microsecs % 1000000) * 1000; } return 0; diff --git a/src/backend_firefox.c b/src/backend_firefox.c index c975cba..2425b28 100644 --- a/src/backend_firefox.c +++ b/src/backend_firefox.c @@ -2135,7 +2135,7 @@ static int64_t timespec_to_usecs ( struct timespec const *ts ) { - return ts->tv_sec * 1000000 + ts->tv_nsec / 1000; + return (int64_t)ts->tv_sec * 1000000 + ts->tv_nsec / 1000; } static int @@ -2778,11 +2778,16 @@ usecs_to_timespec ( struct timespec *ts_buf, int64_t microsecs ) { - if (unlikely(microsecs < 0)) { - microsecs = 0; + int64_t secs = microsecs / 1000000; + if (unlikely(secs < 0)) { + secs = 0; } - - ts_buf->tv_sec = microsecs / 1000000; +#if defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T < 8) + else if (secs > INT32_MAX) { + secs = INT32_MAX; + } +#endif + ts_buf->tv_sec = secs; ts_buf->tv_nsec = (microsecs % 1000000) * 1000; } diff --git a/tests/check_fs_times.c b/tests/check_fs_times.c index bdbb871..70088d9 100644 --- a/tests/check_fs_times.c +++ b/tests/check_fs_times.c @@ -31,13 +31,14 @@ #include #include "check_util.h" +#include "backend_util.h" #include "frontend_util.h" #include "prng.h" // Forward declaration start static int compare_timespec (struct timespec, struct timespec); static int do_check_fs_times (int, int); -static void usecs_to_timespec (struct timespec *, uint32_t); +static void usecs_to_timespec (struct timespec *, uint64_t); // Forward declaration end static int @@ -113,9 +114,8 @@ do_check_fs_times ( ASSERT_NE(-1, compare_timespec(stat_buf.st_atim, now)); for (int i = 0; i < rounds; ++i) { - uint64_t bits = prng_rand(); - usecs_to_timespec(×[0], bits & 0xffffffff); - usecs_to_timespec(×[1], bits >> 32); + usecs_to_timespec(×[0], prng_rand()); + usecs_to_timespec(×[1], prng_rand()); ASSERT_EQ(0, futimens(fd, times)); ASSERT_EQ(0, fstat(fd, &stat_buf)); @@ -142,9 +142,15 @@ do_check_fs_times ( static void usecs_to_timespec ( struct timespec *ts_buf, - uint32_t usecs + uint64_t usecs ) { - ts_buf->tv_sec = usecs / 1000000; + int64_t secs = usecs / 1000000; +#if defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T < 8) + secs %= (int64_t)INT32_MAX + 1; +#else + secs %= TIMESPEC_SEC_MAX + 1; +#endif + ts_buf->tv_sec = secs; ts_buf->tv_nsec = (usecs % 1000000) * 1000; }