summaryrefslogtreecommitdiffstats
path: root/src/time64.h
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2016-09-19 03:10:04 +0200
committerGravatar Nikias Bassen2016-09-19 03:10:04 +0200
commit8d34de3078469aba636846a15bad08198f66fdc8 (patch)
treedb97f8ccb45f35f28348b7e2bffc070b87297089 /src/time64.h
parent912cb45928f03355ca162a2f1286ca49eb58155c (diff)
downloadlibplist-8d34de3078469aba636846a15bad08198f66fdc8.tar.gz
libplist-8d34de3078469aba636846a15bad08198f66fdc8.tar.bz2
Use time64 implementation by Michael G Schwern to extend allowed date/time range
The main benefit of this is to allow date/time values outside of the 32bit time_t range which is very important on 32bit platforms. But there are also some other issues that will be fixed with this, for example on macOS, mktime() will not work for dates < 1902 despite time_t being 64bit. In the same run this commit will also use a reentrant version of gmtime64_r that should help in multithreaded scenarios. Original code taken from: https://github.com/evalEmpire/y2038
Diffstat (limited to 'src/time64.h')
-rw-r--r--src/time64.h85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/time64.h b/src/time64.h
new file mode 100644
index 0000000..556e06f
--- /dev/null
+++ b/src/time64.h
@@ -0,0 +1,85 @@
1#ifndef TIME64_H
2# define TIME64_H
3
4#include <time.h>
5#ifdef HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9/* Set our custom types */
10typedef long long Int64;
11typedef Int64 Time64_T;
12typedef Int64 Year;
13
14
15/* A copy of the tm struct but with a 64 bit year */
16struct TM64 {
17 int tm_sec;
18 int tm_min;
19 int tm_hour;
20 int tm_mday;
21 int tm_mon;
22 Year tm_year;
23 int tm_wday;
24 int tm_yday;
25 int tm_isdst;
26
27#ifdef HAVE_TM_TM_GMTOFF
28 long tm_gmtoff;
29#endif
30
31#ifdef HAVE_TM_TM_ZONE
32 char *tm_zone;
33#endif
34};
35
36
37/* Decide which tm struct to use */
38#ifdef USE_TM64
39#define TM TM64
40#else
41#define TM tm
42#endif
43
44
45/* Declare public functions */
46struct TM *gmtime64_r (const Time64_T *, struct TM *);
47struct TM *localtime64_r (const Time64_T *, struct TM *);
48struct TM *gmtime64 (const Time64_T *);
49struct TM *localtime64 (const Time64_T *);
50
51char *asctime64 (const struct TM *);
52char *asctime64_r (const struct TM *, char *);
53
54char *ctime64 (const Time64_T*);
55char *ctime64_r (const Time64_T*, char*);
56
57Time64_T timegm64 (const struct TM *);
58Time64_T mktime64 (struct TM *);
59Time64_T timelocal64 (struct TM *);
60
61
62/* Not everyone has gm/localtime_r(), provide a replacement */
63#ifdef HAVE_LOCALTIME_R
64# define LOCALTIME_R(clock, result) localtime_r(clock, result)
65#else
66# define LOCALTIME_R(clock, result) fake_localtime_r(clock, result)
67#endif
68#ifdef HAVE_GMTIME_R
69# define GMTIME_R(clock, result) gmtime_r(clock, result)
70#else
71# define GMTIME_R(clock, result) fake_gmtime_r(clock, result)
72#endif
73
74
75/* Use a different asctime format depending on how big the year is */
76#ifdef USE_TM64
77 #define TM64_ASCTIME_FORMAT "%.3s %.3s%3d %.2d:%.2d:%.2d %lld\n"
78#else
79 #define TM64_ASCTIME_FORMAT "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n"
80#endif
81
82void copy_tm_to_TM64(const struct tm *src, struct TM *dest);
83void copy_TM64_to_tm(const struct TM *src, struct tm *dest);
84
85#endif