6456628: (tz) Default timezone is incorrectly set occasionally on Linux

Reviewed-by: okutsu
This commit is contained in:
Yuka Kamiya 2009-08-31 14:53:05 +09:00
parent 4e70dbf4cd
commit 4e064060c0

View File

@ -51,9 +51,9 @@
#ifdef __linux__ #ifdef __linux__
static const char *sysconfig_clock_file = "/etc/sysconfig/clock"; static const char *ETC_TIMEZONE_FILE = "/etc/timezone";
static const char *zoneinfo_dir = "/usr/share/zoneinfo"; static const char *ZONEINFO_DIR = "/usr/share/zoneinfo";
static const char *defailt_zoneinfo_file = "/etc/localtime"; static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
/* /*
* Returns a point to the zone ID portion of the given zoneinfo file * Returns a point to the zone ID portion of the given zoneinfo file
@ -201,53 +201,22 @@ getPlatformTimeZoneID()
size_t size; size_t size;
/* /*
* First, try the ZONE entry in /etc/sysconfig/clock. However, the * Try reading the /etc/timezone file for Debian distros. There's
* ZONE entry is not set up after initial Red Hat Linux * no spec of the file format available. This parsing assumes that
* installation. In case that /etc/localtime is set up without * there's one line of an Olson tzid followed by a '\n', no
* using timeconfig, there might be inconsistency between * leading or trailing spaces, no comments.
* /etc/localtime and the ZONE entry. The inconsistency between
* timeconfig and linuxconf is reported as a bug in the Red Hat
* web page as of May 1, 2000.
*/ */
if ((fp = fopen(sysconfig_clock_file, "r")) != NULL) { if ((fp = fopen(ETC_TIMEZONE_FILE, "r")) != NULL) {
char line[256]; char line[256];
while (fgets(line, sizeof(line), fp) != NULL) { if (fgets(line, sizeof(line), fp) != NULL) {
char *p = line; char *p = strchr(line, '\n');
char *s; if (p != NULL) {
*p = '\0';
SKIP_SPACE(p);
if (*p != 'Z') {
continue;
} }
if (strncmp(p, "ZONE=\"", 6) == 0) { if (strlen(line) > 0) {
p += 6; tz = strdup(line);
} else {
/*
* In case we need to parse it token by token.
*/
if (strncmp(p, "ZONE", 4) != 0) {
continue;
}
p += 4;
SKIP_SPACE(p);
if (*p++ != '=') {
break;
}
SKIP_SPACE(p);
if (*p++ != '"') {
break;
}
} }
for (s = p; *s && *s != '"'; s++)
;
if (*s != '"') {
/* this ZONE entry is broken. */
break;
}
*s = '\0';
tz = strdup(p);
break;
} }
(void) fclose(fp); (void) fclose(fp);
if (tz != NULL) { if (tz != NULL) {
@ -258,7 +227,7 @@ getPlatformTimeZoneID()
/* /*
* Next, try /etc/localtime to find the zone ID. * Next, try /etc/localtime to find the zone ID.
*/ */
if (lstat(defailt_zoneinfo_file, &statbuf) == -1) { if (lstat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) {
return NULL; return NULL;
} }
@ -273,9 +242,9 @@ getPlatformTimeZoneID()
char linkbuf[PATH_MAX+1]; char linkbuf[PATH_MAX+1];
int len; int len;
if ((len = readlink(defailt_zoneinfo_file, linkbuf, sizeof(linkbuf)-1)) == -1) { if ((len = readlink(DEFAULT_ZONEINFO_FILE, linkbuf, sizeof(linkbuf)-1)) == -1) {
jio_fprintf(stderr, (const char *) "can't get a symlink of %s\n", jio_fprintf(stderr, (const char *) "can't get a symlink of %s\n",
defailt_zoneinfo_file); DEFAULT_ZONEINFO_FILE);
return NULL; return NULL;
} }
linkbuf[len] = '\0'; linkbuf[len] = '\0';
@ -295,7 +264,7 @@ getPlatformTimeZoneID()
if (buf == NULL) { if (buf == NULL) {
return NULL; return NULL;
} }
if ((fd = open(defailt_zoneinfo_file, O_RDONLY)) == -1) { if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) {
free((void *) buf); free((void *) buf);
return NULL; return NULL;
} }
@ -307,7 +276,7 @@ getPlatformTimeZoneID()
} }
(void) close(fd); (void) close(fd);
tz = findZoneinfoFile(buf, size, zoneinfo_dir); tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
free((void *) buf); free((void *) buf);
return tz; return tz;
} }