summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2020-02-11 22:20:57 -0500
committerTavian Barnes <tavianator@tavianator.com>2020-02-11 22:20:57 -0500
commit60a33ca726518a3325e56d77f65bfdcbecf91444 (patch)
tree99fadc2fe4b13f0da18162a6cfc971fd42b98b0e /util.c
parent31d4d9ea8bb2678ea4a3742a7d34e76c0ed86956 (diff)
downloadbfs-60a33ca726518a3325e56d77f65bfdcbecf91444.tar.xz
Implement explicit reference times (-newerXt)
Diffstat (limited to 'util.c')
-rw-r--r--util.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/util.c b/util.c
index 691402c..88f90aa 100644
--- a/util.c
+++ b/util.c
@@ -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, "----------");