| Ticket UUID: | c9eb6b0ac01bb8ef96a616c71426a3db4a279bec | ||
| Title: | ConvertLocalToUTCUsingC fails the first time if TZ is not set | ||
| Type: | Bug | Created on: | 2015-12-10 12:10:34 |
| Submitter: | anonymous | Assigned to: | nobody |
| Subsystem: | 06. Time Measurement | Severity: | Minor |
| Priority: | 5 Medium | Last modified: | 2016-02-16 21:59:09 |
| Status: | Closed | Closed by: | gahr |
| Resolution: | None | Closed on: | 2016-02-16 21:59:09 |
| Version: | 8.6 | ||
| Description: | ||||
|
This is with fossil trunk on FreeBSD 10.2-RELEASE-p7 amd64. If TZ is not set in the environment, the ConvertLocalToUTCUsingC will fail the first time it is called. To avoid this, make sure TzsetIfNecessary() always calls tzset the first time.
Index: generic/tclClock.c
==================================================================
--- generic/tclClock.c
+++ generic/tclClock.c
@@ -2005,25 +2005,28 @@
static void
TzsetIfNecessary(void)
{
static char *tzWas = NULL; /* Previous value of TZ, protected by
* clockMutex. */
+ static char first = 1; /* First time? */
const char *tzIsNow; /* Current value of TZ */
Tcl_MutexLock(&clockMutex);
tzIsNow = getenv("TZ");
- if (tzIsNow != NULL && (tzWas == NULL || strcmp(tzIsNow, tzWas) != 0)) {
+ int mod = ((size_t)tzWas ^ (size_t)tzIsNow) ||
+ ((size_t)tzWas & (size_t)tzIsNow && strcmp(tzIsNow, tzWas) != 0);
+ if (first || mod) {
+ first = 0;
tzset();
if (tzWas != NULL) {
ckfree(tzWas);
+ tzWas = NULL;
}
- tzWas = ckalloc(strlen(tzIsNow) + 1);
- strcpy(tzWas, tzIsNow);
- } else if (tzIsNow == NULL && tzWas != NULL) {
- tzset();
- ckfree(tzWas);
- tzWas = NULL;
+ if (tzIsNow != NULL) {
+ tzWas = ckalloc(strlen(tzIsNow) + 1);
+ strcpy(tzWas, tzIsNow);
+ }
}
Tcl_MutexUnlock(&clockMutex);
}
/*
Using this test driver
package require clock::iso8601
proc doit {} {
try {
::tcl::clock::ConvertLocalToUTC {
tzName :localtime
century 19
yearOfCentury 94
month 11
dayOfMonth 5
era CE
year 1994
julianDay 2449662
secondOfDay 0
localSeconds 783993600} {} 2299161
} on error msg {
return "$msg\n[info errorstack]"
}
}
puts [doit]
puts [doit]
I get this with a non-patched version of Tcl:
time value too large/small to represent
INNER {invokeStk1 ::tcl::clock::ConvertLocalToUTC {
tzName :localtime
century 19
yearOfCentury 94
month 11
dayOfMonth 5
era CE
year 1994
julianDay 2449662
secondOfDay 0
localSeconds 783993600} {} 2299161} CALL doit
tzName :localtime century 19 yearOfCentury 94 month 11 dayOfMonth 5 era CE year 1994 julianDay 2449662 secondOfDay 0 localSeconds 783993600 seconds 783993600
And this with a patched version: tzName :localtime century 19 yearOfCentury 94 month 11 dayOfMonth 5 era CE year 1994 julianDay 2449662 secondOfDay 0 localSeconds 783993600 seconds 783993600 tzName :localtime century 19 yearOfCentury 94 month 11 dayOfMonth 5 era CE year 1994 julianDay 2449662 secondOfDay 0 localSeconds 783993600 seconds 783993600 | ||||
| User Comments: | ||||
gahr added on 2016-02-16 21:59:09:
Fixed by checkin [38e14f6cc3] | ||||
