diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2020-02-11 22:20:57 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2020-02-11 22:20:57 -0500 |
commit | 60a33ca726518a3325e56d77f65bfdcbecf91444 (patch) | |
tree | 99fadc2fe4b13f0da18162a6cfc971fd42b98b0e /util.c | |
parent | 31d4d9ea8bb2678ea4a3742a7d34e76c0ed86956 (diff) | |
download | bfs-60a33ca726518a3325e56d77f65bfdcbecf91444.tar.xz |
Implement explicit reference times (-newerXt)
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 54 |
1 files changed, 54 insertions, 0 deletions
@@ -174,6 +174,60 @@ int xlocaltime(const time_t *timep, struct tm *result) { } } +int xgmtime(const time_t *timep, struct tm *result) { + // Should be called before gmtime_r() according to POSIX.1-2004 + tzset(); + + if (gmtime_r(timep, result)) { + return 0; + } else { + return -1; + } +} + +time_t xtimegm(struct tm *tm) { + // Some man pages for timegm() recommend this as a portable approach + time_t ret = -1; + int error; + + char *old_tz = getenv("TZ"); + if (old_tz) { + old_tz = strdup(old_tz); + if (!old_tz) { + error = errno; + goto fail; + } + } + + if (setenv("TZ", "UTC0", true) != 0) { + error = errno; + goto fail; + } + + ret = mktime(tm); + error = errno; + + if (old_tz) { + if (setenv("TZ", old_tz, true) != 0) { + ret = -1; + error = errno; + goto fail; + } + } else { + if (unsetenv("TZ") != 0) { + ret = -1; + error = errno; + goto fail; + } + } + + tzset(); +fail: + free(old_tz); + errno = error; + return ret; +} + void format_mode(mode_t mode, char str[11]) { strcpy(str, "----------"); |