提交 ea4e7475 编写于 作者: S simonis

8134505: Cleanup of "TimeZone_md.c"

Reviewed-by: rriggs, dsamersoff, simonis
Contributed-by: christoph.langer@sap.com
上级 72c90b53
/* /*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,14 +35,20 @@ ...@@ -35,14 +35,20 @@
#include <string.h> #include <string.h>
#include <dirent.h> #include <dirent.h>
#include <unistd.h> #include <unistd.h>
#ifdef __solaris__ #if defined(__solaris__)
#include <libscf.h> #include <libscf.h>
#endif #endif
#include "jvm.h" #include "jvm.h"
#include "TimeZone_md.h"
#define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++; #define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++;
#if defined(_ALLBSD_SOURCE)
#define dirent64 dirent
#define readdir64_r readdir_r
#endif
#if !defined(__solaris__) || defined(__sparcv9) || defined(amd64) #if !defined(__solaris__) || defined(__sparcv9) || defined(amd64)
#define fileopen fopen #define fileopen fopen
#define filegets fgets #define filegets fgets
...@@ -50,19 +56,20 @@ ...@@ -50,19 +56,20 @@
#endif #endif
#if defined(__linux__) || defined(_ALLBSD_SOURCE) #if defined(__linux__) || defined(_ALLBSD_SOURCE)
static const char *ETC_TIMEZONE_FILE = "/etc/timezone"; 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 *DEFAULT_ZONEINFO_FILE = "/etc/localtime"; static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
#else #else
#ifdef _AIX
static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
#endif
static const char *SYS_INIT_FILE = "/etc/default/init"; static const char *SYS_INIT_FILE = "/etc/default/init";
static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo"; static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo";
static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime"; static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
#endif /*__linux__*/ #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
#if defined(_AIX)
static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
#endif
#if defined(__linux__) || defined(MACOSX) || defined(__solaris__)
/* /*
* Returns a pointer to the zone ID portion of the given zoneinfo file * Returns a pointer to the zone ID portion of the given zoneinfo file
...@@ -108,8 +115,8 @@ findZoneinfoFile(char *buf, size_t size, const char *dir) ...@@ -108,8 +115,8 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
{ {
DIR *dirp = NULL; DIR *dirp = NULL;
struct stat statbuf; struct stat statbuf;
struct dirent *dp = NULL; struct dirent64 *dp = NULL;
struct dirent *entry = NULL; struct dirent64 *entry = NULL;
char *pathname = NULL; char *pathname = NULL;
int fd = -1; int fd = -1;
char *dbuf = NULL; char *dbuf = NULL;
...@@ -120,19 +127,13 @@ findZoneinfoFile(char *buf, size_t size, const char *dir) ...@@ -120,19 +127,13 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
return NULL; return NULL;
} }
entry = (struct dirent *) malloc((size_t) pathconf(dir, _PC_NAME_MAX)); entry = (struct dirent64 *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));
if (entry == NULL) { if (entry == NULL) {
(void) closedir(dirp); (void) closedir(dirp);
return NULL; return NULL;
} }
#if defined(_AIX) || defined(__linux__) || defined(MACOSX) || (defined(__solaris__) \ while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
&& (defined(_POSIX_PTHREAD_SEMANTICS) || defined(_LP64)))
while (readdir_r(dirp, entry, &dp) == 0 && dp != NULL) {
#else
while ((dp = readdir_r(dirp, entry)) != NULL) {
#endif
/* /*
* Skip '.' and '..' (and possibly other .* files) * Skip '.' and '..' (and possibly other .* files)
*/ */
...@@ -145,7 +146,7 @@ findZoneinfoFile(char *buf, size_t size, const char *dir) ...@@ -145,7 +146,7 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
*/ */
if ((strcmp(dp->d_name, "ROC") == 0) if ((strcmp(dp->d_name, "ROC") == 0)
|| (strcmp(dp->d_name, "posixrules") == 0) || (strcmp(dp->d_name, "posixrules") == 0)
#ifdef __solaris__ #if defined(__solaris__)
/* /*
* Skip the "src" and "tab" directories on Solaris. * Skip the "src" and "tab" directories on Solaris.
*/ */
...@@ -230,7 +231,7 @@ getPlatformTimeZoneID() ...@@ -230,7 +231,7 @@ getPlatformTimeZoneID()
char *buf; char *buf;
size_t size; size_t size;
#ifdef __linux__ #if defined(__linux__)
/* /*
* Try reading the /etc/timezone file for Debian distros. There's * Try reading the /etc/timezone file for Debian distros. There's
* no spec of the file format available. This parsing assumes that * no spec of the file format available. This parsing assumes that
...@@ -254,7 +255,7 @@ getPlatformTimeZoneID() ...@@ -254,7 +255,7 @@ getPlatformTimeZoneID()
return tz; return tz;
} }
} }
#endif /* __linux__ */ #endif /* defined(__linux__) */
/* /*
* Next, try /etc/localtime to find the zone ID. * Next, try /etc/localtime to find the zone ID.
...@@ -318,8 +319,9 @@ getPlatformTimeZoneID() ...@@ -318,8 +319,9 @@ getPlatformTimeZoneID()
free((void *) buf); free((void *) buf);
return tz; return tz;
} }
#else
#ifdef __solaris__ #elif defined(__solaris__)
#if !defined(__sparcv9) && !defined(amd64) #if !defined(__sparcv9) && !defined(amd64)
/* /*
...@@ -444,8 +446,7 @@ filegets(char *s, int n, FILE *stream) ...@@ -444,8 +446,7 @@ filegets(char *s, int n, FILE *stream)
} }
/*NOTREACHED*/ /*NOTREACHED*/
} }
#endif /* not __sparcv9 */ #endif /* !defined(__sparcv9) && !defined(amd64) */
/* /*
* Performs Solaris dependent mapping. Returns a zone ID if * Performs Solaris dependent mapping. Returns a zone ID if
...@@ -546,7 +547,7 @@ cleanupScf(scf_handle_t *h, ...@@ -546,7 +547,7 @@ cleanupScf(scf_handle_t *h,
} }
/* /*
* Retruns a zone ID of Solaris when the TZ value is "localtime". * Returns a zone ID of Solaris when the TZ value is "localtime".
* First, it tries scf. If scf fails, it looks for the same file as * First, it tries scf. If scf fails, it looks for the same file as
* /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/. * /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/.
*/ */
...@@ -615,10 +616,11 @@ getSolarisDefaultZoneID() { ...@@ -615,10 +616,11 @@ getSolarisDefaultZoneID() {
free((void *) buf); free((void *) buf);
return tz; return tz;
} }
#endif /*__solaris__*/
#endif /*__linux__*/
#ifdef _AIX #endif /* defined(__solaris__) */
#elif defined(_AIX)
static char * static char *
getPlatformTimeZoneID() getPlatformTimeZoneID()
{ {
...@@ -644,8 +646,103 @@ getPlatformTimeZoneID() ...@@ -644,8 +646,103 @@ getPlatformTimeZoneID()
return tz; return tz;
} }
static char *mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz);
#endif static char *
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
FILE *tzmapf;
char mapfilename[PATH_MAX + 1];
char line[256];
int linecount = 0;
char *tz_buf = NULL;
char *temp_tz = NULL;
char *javatz = NULL;
size_t tz_len = 0;
/* On AIX, the TZ environment variable may end with a comma
* followed by modifier fields. These are ignored here. */
temp_tz = strchr(tz, ',');
tz_len = (temp_tz == NULL) ? strlen(tz) : temp_tz - tz;
tz_buf = (char *)malloc(tz_len + 1);
memcpy(tz_buf, tz, tz_len);
tz_buf[tz_len] = 0;
/* Open tzmappings file, with buffer overrun check */
if ((strlen(java_home_dir) + 15) > PATH_MAX) {
jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir);
goto tzerr;
}
strcpy(mapfilename, java_home_dir);
strcat(mapfilename, "/lib/tzmappings");
if ((tzmapf = fopen(mapfilename, "r")) == NULL) {
jio_fprintf(stderr, "can't open %s\n", mapfilename);
goto tzerr;
}
while (fgets(line, sizeof(line), tzmapf) != NULL) {
char *p = line;
char *sol = line;
char *java;
int result;
linecount++;
/*
* Skip comments and blank lines
*/
if (*p == '#' || *p == '\n') {
continue;
}
/*
* Get the first field, platform zone ID
*/
while (*p != '\0' && *p != '\t') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at near line %d.\n", linecount);
break;
}
*p++ = '\0';
if ((result = strncmp(tz_buf, sol, tz_len)) == 0) {
/*
* If this is the current platform zone ID,
* take the Java time zone ID (2nd field).
*/
java = p;
while (*p != '\0' && *p != '\n') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at line %d.\n", linecount);
break;
}
*p = '\0';
javatz = strdup(java);
break;
} else if (result < 0) {
break;
}
}
(void) fclose(tzmapf);
tzerr:
if (tz_buf != NULL ) {
free((void *) tz_buf);
}
if (javatz == NULL) {
return getGMTOffsetID();
}
return javatz;
}
#endif /* defined(_AIX) */
/* /*
* findJavaTZ_md() maps platform time zone ID to Java time zone ID * findJavaTZ_md() maps platform time zone ID to Java time zone ID
...@@ -664,51 +761,50 @@ findJavaTZ_md(const char *java_home_dir) ...@@ -664,51 +761,50 @@ findJavaTZ_md(const char *java_home_dir)
tz = getenv("TZ"); tz = getenv("TZ");
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
if (tz == NULL) {
#else
#if defined (__solaris__) || defined(_AIX)
if (tz == NULL || *tz == '\0') { if (tz == NULL || *tz == '\0') {
#endif
#endif
tz = getPlatformTimeZoneID(); tz = getPlatformTimeZoneID();
freetz = tz; freetz = tz;
} }
/*
* Remove any preceding ':'
*/
if (tz != NULL && *tz == ':') {
tz++;
}
#ifdef __solaris__
if (tz != NULL && strcmp(tz, "localtime") == 0) {
tz = getSolarisDefaultZoneID();
freetz = tz;
}
#endif
if (tz != NULL) { if (tz != NULL) {
#ifdef __linux__ /* Ignore preceding ':' */
/* if (*tz == ':') {
* Ignore "posix/" prefix. tz++;
*/ }
#if defined(__linux__)
/* Ignore "posix/" prefix on Linux. */
if (strncmp(tz, "posix/", 6) == 0) { if (strncmp(tz, "posix/", 6) == 0) {
tz += 6; tz += 6;
} }
#endif #endif
javatz = strdup(tz);
#if defined(_AIX)
/* On AIX do the platform to Java mapping. */
javatz = mapPlatformToJavaTimezone(java_home_dir, tz);
if (freetz != NULL) { if (freetz != NULL) {
free((void *) freetz); free((void *) freetz);
} }
#else
#ifdef _AIX #if defined(__solaris__)
freetz = mapPlatformToJavaTimezone(java_home_dir, javatz); /* Solaris might use localtime, so handle it here. */
if (javatz != NULL) { if (strcmp(tz, "localtime") == 0) {
free((void *) javatz); javatz = getSolarisDefaultZoneID();
if (freetz != NULL) {
free((void *) freetz);
}
} else
#endif
if (freetz == NULL) {
/* strdup if we are still working on getenv result. */
javatz = strdup(tz);
} else if (freetz != tz) {
/* strdup and free the old buffer, if we moved the pointer. */
javatz = strdup(tz);
free((void *) freetz);
} else {
/* we are good if we already work on a freshly allocated buffer. */
javatz = tz;
} }
javatz = freetz;
#endif #endif
} }
...@@ -719,7 +815,7 @@ findJavaTZ_md(const char *java_home_dir) ...@@ -719,7 +815,7 @@ findJavaTZ_md(const char *java_home_dir)
* Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00") * Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
*/ */
#ifdef MACOSX #if defined(MACOSX)
char * char *
getGMTOffsetID() getGMTOffsetID()
...@@ -735,15 +831,16 @@ getGMTOffsetID() ...@@ -735,15 +831,16 @@ getGMTOffsetID()
local_tm = localtime(&clock); local_tm = localtime(&clock);
if (local_tm->tm_gmtoff >= 0) { if (local_tm->tm_gmtoff >= 0) {
offset = (time_t) local_tm->tm_gmtoff; offset = (time_t) local_tm->tm_gmtoff;
sign = "+"; sign = '+';
} else { } else {
offset = (time_t) -local_tm->tm_gmtoff; offset = (time_t) -local_tm->tm_gmtoff;
sign = "-"; sign = '-';
} }
sprintf(buf, (const char *)"GMT%c%02d:%02d", sprintf(buf, (const char *)"GMT%c%02d:%02d",
sign, (int)(offset/3600), (int)((offset%3600)/60)); sign, (int)(offset/3600), (int)((offset%3600)/60));
return strdup(buf); return strdup(buf);
} }
#else #else
char * char *
...@@ -751,7 +848,7 @@ getGMTOffsetID() ...@@ -751,7 +848,7 @@ getGMTOffsetID()
{ {
time_t offset; time_t offset;
char sign, buf[32]; char sign, buf[32];
#ifdef __solaris__ #if defined(__solaris__)
struct tm localtm; struct tm localtm;
time_t currenttime; time_t currenttime;
...@@ -763,7 +860,7 @@ getGMTOffsetID() ...@@ -763,7 +860,7 @@ getGMTOffsetID()
offset = localtm.tm_isdst ? altzone : timezone; offset = localtm.tm_isdst ? altzone : timezone;
#else #else
offset = timezone; offset = timezone;
#endif /*__linux__*/ #endif
if (offset == 0) { if (offset == 0) {
return strdup("GMT"); return strdup("GMT");
...@@ -781,101 +878,3 @@ getGMTOffsetID() ...@@ -781,101 +878,3 @@ getGMTOffsetID()
return strdup(buf); return strdup(buf);
} }
#endif /* MACOSX */ #endif /* MACOSX */
#ifdef _AIX
static char *
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
FILE *tzmapf;
char mapfilename[PATH_MAX+1];
char line[256];
int linecount = 0;
char temp[100], *temp_tz;
char *javatz = NULL;
char *str_tmp = NULL;
size_t temp_tz_len = 0;
/* On AIX, the TZ environment variable may end with a comma
* followed by modifier fields. These are ignored here.
*/
strncpy(temp, tz, 100);
temp_tz = strtok_r(temp, ",", &str_tmp);
if(temp_tz == NULL)
goto tzerr;
temp_tz_len = strlen(temp_tz);
if (strlen(java_home_dir) >= (PATH_MAX - 15)) {
jio_fprintf(stderr, "java.home longer than maximum path length \n");
goto tzerr;
}
strncpy(mapfilename, java_home_dir, PATH_MAX);
strcat(mapfilename, "/lib/tzmappings");
if ((tzmapf = fopen(mapfilename, "r")) == NULL) {
jio_fprintf(stderr, "can't open %s\n", mapfilename);
goto tzerr;
}
while (fgets(line, sizeof(line), tzmapf) != NULL) {
char *p = line;
char *sol = line;
char *java;
int result;
linecount++;
/*
* Skip comments and blank lines
*/
if (*p == '#' || *p == '\n') {
continue;
}
/*
* Get the first field, platform zone ID
*/
while (*p != '\0' && *p != '\t') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at near line %d.\n", linecount);
break;
}
*p++ = '\0';
if ((result = strncmp(temp_tz, sol, temp_tz_len)) == 0) {
/*
* If this is the current platform zone ID,
* take the Java time zone ID (2nd field).
*/
java = p;
while (*p != '\0' && *p != '\n') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at line %d.\n", linecount);
break;
}
*p = '\0';
javatz = strdup(java);
break;
} else if (result < 0) {
break;
}
}
(void) fclose(tzmapf);
tzerr:
if (javatz == NULL) {
return getGMTOffsetID();
}
return javatz;
}
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册