summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2020-02-13 16:30:05 -0500
committerTavian Barnes <tavianator@tavianator.com>2020-02-13 16:39:30 -0500
commit95f862fdd82a99e30bbf2c43009ec9a51e416804 (patch)
tree0edafaf7a69935d56dc4ce8b442325e12dfd88ff /util.c
parent2cdc648441794db0f84518f79e8aaf3ead68f110 (diff)
downloadbfs-95f862fdd82a99e30bbf2c43009ec9a51e416804.tar.xz
parse: Handle 1969-12-31T23:59:59Z
mktime() returns -1 on error, but also for one second before the epoch. Compare the input against localtime(-1) to distinguish those cases.
Diffstat (limited to 'util.c')
-rw-r--r--util.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/util.c b/util.c
index 88f90aa..6af7d27 100644
--- a/util.c
+++ b/util.c
@@ -185,9 +185,30 @@ int xgmtime(const time_t *timep, struct tm *result) {
}
}
-time_t xtimegm(struct tm *tm) {
+int xmktime(struct tm *tm, time_t *timep) {
+ *timep = mktime(tm);
+
+ if (*timep == -1) {
+ int error = errno;
+
+ struct tm tmp;
+ if (xlocaltime(timep, &tmp) != 0) {
+ return -1;
+ }
+
+ if (tm->tm_year != tmp.tm_year || tm->tm_yday != tmp.tm_yday
+ || tm->tm_hour != tmp.tm_hour || tm->tm_min != tmp.tm_min || tm->tm_sec != tmp.tm_sec) {
+ errno = error;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int xtimegm(struct tm *tm, time_t *timep) {
// Some man pages for timegm() recommend this as a portable approach
- time_t ret = -1;
+ int ret = -1;
int error;
char *old_tz = getenv("TZ");
@@ -204,7 +225,7 @@ time_t xtimegm(struct tm *tm) {
goto fail;
}
- ret = mktime(tm);
+ ret = xmktime(tm, timep);
error = errno;
if (old_tz) {