Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107406242
D30183.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D30183.diff
View Options
diff --git a/contrib/tzcode/stdtime/localtime.c b/contrib/tzcode/stdtime/localtime.c
--- a/contrib/tzcode/stdtime/localtime.c
+++ b/contrib/tzcode/stdtime/localtime.c
@@ -354,6 +354,45 @@
}
}
+#ifdef DETECT_TZ_CHANGES
+/*
+ * Determine if there's a change in the timezone since the last time we checked.
+ * Returns: -1 on error
+ * 0 if the timezone has not changed
+ * 1 if the timezone has changed
+ */
+static int
+change_in_tz(const char *name)
+{
+ static char old_name[PATH_MAX];
+ static struct stat old_sb;
+ struct stat sb;
+ int error;
+
+ error = stat(name, &sb);
+ if (error != 0)
+ return -1;
+
+ if (strcmp(name, old_name) != 0) {
+ strlcpy(old_name, name, sizeof(old_name));
+ old_sb = sb;
+ return 1;
+ }
+
+ if (sb.st_dev != old_sb.st_dev ||
+ sb.st_ino != old_sb.st_ino ||
+ sb.st_ctime != old_sb.st_ctime ||
+ sb.st_mtime != old_sb.st_mtime) {
+ old_sb = sb;
+ return 1;
+ }
+
+ return 0;
+}
+#else /* !DETECT_TZ_CHANGES */
+#define change_in_tz(X) 0
+#endif /* !DETECT_TZ_CHANGES */
+
static int
differ_by_repeat(const time_t t1, const time_t t0)
{
@@ -379,6 +418,7 @@
int stored;
int nread;
int res;
+ int ret;
union {
struct tzhead tzhead;
char buf[2 * sizeof(struct tzhead) +
@@ -427,6 +467,22 @@
(void) strcat(fullname, name);
name = fullname;
}
+ if (doextend == TRUE) {
+ /*
+ * Detect if the timezone file has changed. Check
+ * 'doextend' to ignore TZDEFRULES; the change_in_tz()
+ * function can only keep state for a single file.
+ */
+ ret = change_in_tz(name);
+ if (ret <= 0) {
+ /*
+ * Returns -1 if there was an error,
+ * and 0 if the timezone had not changed.
+ */
+ free(fullname);
+ return ret;
+ }
+ }
if ((fid = _open(name, OPEN_MODE)) == -1) {
free(fullname);
return -1;
@@ -1209,12 +1265,43 @@
(void) tzparse(gmt, sp, TRUE);
}
+#ifdef DETECT_TZ_CHANGES
+static int
+recheck_tzdata()
+{
+ static time_t last_checked;
+ struct timespec now;
+ time_t current_time;
+ int error;
+
+ /*
+ * We want to recheck the timezone file every 61 sec.
+ */
+ error = clock_gettime(CLOCK_MONOTONIC, &now);
+ if (error <= 0) {
+ /* XXX: Can we somehow report this? */
+ return 0;
+ }
+
+ current_time = now.tv_sec;
+ if ((current_time - last_checked > 61) ||
+ (last_checked > current_time)) {
+ last_checked = current_time;
+ return 1;
+ }
+
+ return 0;
+}
+#else /* !DETECT_TZ_CHANGES */
+#define recheck_tzdata() 0
+#endif /* !DETECT_TZ_CHANGES */
+
static void
tzsetwall_basic(int rdlocked)
{
if (!rdlocked)
_RWLOCK_RDLOCK(&lcl_rwlock);
- if (lcl_is_set < 0) {
+ if (lcl_is_set < 0 && recheck_tzdata() == 0) {
if (!rdlocked)
_RWLOCK_UNLOCK(&lcl_rwlock);
return;
diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc
--- a/lib/libc/stdtime/Makefile.inc
+++ b/lib/libc/stdtime/Makefile.inc
@@ -12,6 +12,10 @@
CFLAGS.localtime.c= -fwrapv
+.if ${MK_DETECT_TZ_CHANGES} != "no"
+CFLAGS+= -DDETECT_TZ_CHANGES
+.endif
+
MAN+= ctime.3 strftime.3 strptime.3 time2posix.3
MAN+= tzfile.5
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -196,6 +196,7 @@
BHYVE_SNAPSHOT \
CLANG_EXTRAS \
CLANG_FORMAT \
+ DETECT_TZ_CHANGES \
DTRACE_TESTS \
EXPERIMENTAL \
HESIOD \
diff --git a/tools/build/options/WITH_DETECT_TZ_CHANGES b/tools/build/options/WITH_DETECT_TZ_CHANGES
new file mode 100644
--- /dev/null
+++ b/tools/build/options/WITH_DETECT_TZ_CHANGES
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Make the time handling code detect changes to the timezone files.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 14, 5:17 PM (7 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15797730
Default Alt Text
D30183.diff (3 KB)
Attached To
Mode
D30183: tzcode: Implement timezone change detection
Attached
Detach File
Event Timeline
Log In to Comment