8134505: Cleanup of "TimeZone_md.c"
Reviewed-by: rriggs, dsamersoff, simonis
This commit is contained in:
parent
7c9b107d1f
commit
981fa17133
@ -35,14 +35,20 @@
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __solaris__
|
||||
#if defined(__solaris__)
|
||||
#include <libscf.h>
|
||||
#endif
|
||||
|
||||
#include "jvm.h"
|
||||
#include "TimeZone_md.h"
|
||||
|
||||
#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)
|
||||
#define fileopen fopen
|
||||
#define filegets fgets
|
||||
@ -50,19 +56,20 @@
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
|
||||
|
||||
|
||||
static const char *ETC_TIMEZONE_FILE = "/etc/timezone";
|
||||
static const char *ZONEINFO_DIR = "/usr/share/zoneinfo";
|
||||
static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
|
||||
#else
|
||||
#ifdef _AIX
|
||||
static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
|
||||
#endif
|
||||
static const char *SYS_INIT_FILE = "/etc/default/init";
|
||||
static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo";
|
||||
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
|
||||
@ -108,8 +115,8 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
|
||||
{
|
||||
DIR *dirp = NULL;
|
||||
struct stat statbuf;
|
||||
struct dirent *dp = NULL;
|
||||
struct dirent *entry = NULL;
|
||||
struct dirent64 *dp = NULL;
|
||||
struct dirent64 *entry = NULL;
|
||||
char *pathname = NULL;
|
||||
int fd = -1;
|
||||
char *dbuf = NULL;
|
||||
@ -120,19 +127,13 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
|
||||
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) {
|
||||
(void) closedir(dirp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(_AIX) || defined(__linux__) || defined(MACOSX) || (defined(__solaris__) \
|
||||
&& (defined(_POSIX_PTHREAD_SEMANTICS) || defined(_LP64)))
|
||||
while (readdir_r(dirp, entry, &dp) == 0 && dp != NULL) {
|
||||
#else
|
||||
while ((dp = readdir_r(dirp, entry)) != NULL) {
|
||||
#endif
|
||||
|
||||
while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
|
||||
/*
|
||||
* Skip '.' and '..' (and possibly other .* files)
|
||||
*/
|
||||
@ -145,7 +146,7 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
|
||||
*/
|
||||
if ((strcmp(dp->d_name, "ROC") == 0)
|
||||
|| (strcmp(dp->d_name, "posixrules") == 0)
|
||||
#ifdef __solaris__
|
||||
#if defined(__solaris__)
|
||||
/*
|
||||
* Skip the "src" and "tab" directories on Solaris.
|
||||
*/
|
||||
@ -230,7 +231,7 @@ getPlatformTimeZoneID()
|
||||
char *buf;
|
||||
size_t size;
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__)
|
||||
/*
|
||||
* Try reading the /etc/timezone file for Debian distros. There's
|
||||
* no spec of the file format available. This parsing assumes that
|
||||
@ -254,7 +255,7 @@ getPlatformTimeZoneID()
|
||||
return tz;
|
||||
}
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
#endif /* defined(__linux__) */
|
||||
|
||||
/*
|
||||
* Next, try /etc/localtime to find the zone ID.
|
||||
@ -318,8 +319,9 @@ getPlatformTimeZoneID()
|
||||
free((void *) buf);
|
||||
return tz;
|
||||
}
|
||||
#else
|
||||
#ifdef __solaris__
|
||||
|
||||
#elif defined(__solaris__)
|
||||
|
||||
#if !defined(__sparcv9) && !defined(amd64)
|
||||
|
||||
/*
|
||||
@ -444,8 +446,7 @@ filegets(char *s, int n, FILE *stream)
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif /* not __sparcv9 */
|
||||
|
||||
#endif /* !defined(__sparcv9) && !defined(amd64) */
|
||||
|
||||
/*
|
||||
* Performs Solaris dependent mapping. Returns a zone ID if
|
||||
@ -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
|
||||
* /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/.
|
||||
*/
|
||||
@ -615,10 +616,11 @@ getSolarisDefaultZoneID() {
|
||||
free((void *) buf);
|
||||
return tz;
|
||||
}
|
||||
#endif /*__solaris__*/
|
||||
#endif /*__linux__*/
|
||||
|
||||
#ifdef _AIX
|
||||
#endif /* defined(__solaris__) */
|
||||
|
||||
#elif defined(_AIX)
|
||||
|
||||
static char *
|
||||
getPlatformTimeZoneID()
|
||||
{
|
||||
@ -644,178 +646,33 @@ getPlatformTimeZoneID()
|
||||
|
||||
return tz;
|
||||
}
|
||||
static char *mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* findJavaTZ_md() maps platform time zone ID to Java time zone ID
|
||||
* using <java_home>/lib/tzmappings. If the TZ value is not found, it
|
||||
* trys some libc implementation dependent mappings. If it still
|
||||
* can't map to a Java time zone ID, it falls back to the GMT+/-hh:mm
|
||||
* form.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
char *
|
||||
findJavaTZ_md(const char *java_home_dir)
|
||||
{
|
||||
char *tz;
|
||||
char *javatz = NULL;
|
||||
char *freetz = NULL;
|
||||
|
||||
tz = getenv("TZ");
|
||||
|
||||
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
|
||||
if (tz == NULL) {
|
||||
#else
|
||||
#if defined (__solaris__) || defined(_AIX)
|
||||
if (tz == NULL || *tz == '\0') {
|
||||
#endif
|
||||
#endif
|
||||
tz = getPlatformTimeZoneID();
|
||||
freetz = tz;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove any preceding ':'
|
||||
*/
|
||||
if (tz != NULL && *tz == ':') {
|
||||
tz++;
|
||||
}
|
||||
|
||||
#ifdef __solaris__
|
||||
if (tz != NULL && strcmp(tz, "localtime") == 0) {
|
||||
tz = getSolarisDefaultZoneID();
|
||||
if (freetz != NULL) {
|
||||
free((void *) freetz);
|
||||
}
|
||||
freetz = tz;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tz != NULL) {
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* Ignore "posix/" prefix.
|
||||
*/
|
||||
if (strncmp(tz, "posix/", 6) == 0) {
|
||||
tz += 6;
|
||||
}
|
||||
#endif
|
||||
javatz = strdup(tz);
|
||||
if (freetz != NULL) {
|
||||
free((void *) freetz);
|
||||
}
|
||||
|
||||
#ifdef _AIX
|
||||
freetz = mapPlatformToJavaTimezone(java_home_dir, javatz);
|
||||
if (javatz != NULL) {
|
||||
free((void *) javatz);
|
||||
}
|
||||
javatz = freetz;
|
||||
#endif
|
||||
}
|
||||
|
||||
return javatz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
|
||||
*/
|
||||
|
||||
#ifdef MACOSX
|
||||
|
||||
char *
|
||||
getGMTOffsetID()
|
||||
{
|
||||
time_t offset;
|
||||
char sign, buf[32];
|
||||
struct tm *local_tm;
|
||||
time_t clock;
|
||||
time_t currenttime;
|
||||
|
||||
clock = time(NULL);
|
||||
tzset();
|
||||
local_tm = localtime(&clock);
|
||||
if (local_tm->tm_gmtoff >= 0) {
|
||||
offset = (time_t) local_tm->tm_gmtoff;
|
||||
sign = '+';
|
||||
} else {
|
||||
offset = (time_t) -local_tm->tm_gmtoff;
|
||||
sign = '-';
|
||||
}
|
||||
sprintf(buf, (const char *)"GMT%c%02d:%02d",
|
||||
sign, (int)(offset/3600), (int)((offset%3600)/60));
|
||||
return strdup(buf);
|
||||
}
|
||||
#else
|
||||
|
||||
char *
|
||||
getGMTOffsetID()
|
||||
{
|
||||
time_t offset;
|
||||
char sign, buf[32];
|
||||
#ifdef __solaris__
|
||||
struct tm localtm;
|
||||
time_t currenttime;
|
||||
|
||||
currenttime = time(NULL);
|
||||
if (localtime_r(¤ttime, &localtm) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offset = localtm.tm_isdst ? altzone : timezone;
|
||||
#else
|
||||
offset = timezone;
|
||||
#endif /*__linux__*/
|
||||
|
||||
if (offset == 0) {
|
||||
return strdup("GMT");
|
||||
}
|
||||
|
||||
/* Note that the time offset direction is opposite. */
|
||||
if (offset > 0) {
|
||||
sign = '-';
|
||||
} else {
|
||||
offset = -offset;
|
||||
sign = '+';
|
||||
}
|
||||
sprintf(buf, (const char *)"GMT%c%02d:%02d",
|
||||
sign, (int)(offset/3600), (int)((offset%3600)/60));
|
||||
return strdup(buf);
|
||||
}
|
||||
#endif /* MACOSX */
|
||||
|
||||
#ifdef _AIX
|
||||
static char *
|
||||
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
|
||||
FILE *tzmapf;
|
||||
char mapfilename[PATH_MAX+1];
|
||||
char mapfilename[PATH_MAX + 1];
|
||||
char line[256];
|
||||
int linecount = 0;
|
||||
char temp[100], *temp_tz;
|
||||
char *tz_buf = NULL;
|
||||
char *temp_tz = NULL;
|
||||
char *javatz = NULL;
|
||||
char *str_tmp = NULL;
|
||||
size_t temp_tz_len = 0;
|
||||
size_t 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);
|
||||
* 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;
|
||||
|
||||
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");
|
||||
/* 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;
|
||||
}
|
||||
|
||||
strncpy(mapfilename, java_home_dir, PATH_MAX);
|
||||
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;
|
||||
@ -848,7 +705,7 @@ mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
|
||||
}
|
||||
|
||||
*p++ = '\0';
|
||||
if ((result = strncmp(temp_tz, sol, temp_tz_len)) == 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).
|
||||
@ -874,11 +731,150 @@ mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
|
||||
(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
|
||||
* using <java_home>/lib/tzmappings. If the TZ value is not found, it
|
||||
* trys some libc implementation dependent mappings. If it still
|
||||
* can't map to a Java time zone ID, it falls back to the GMT+/-hh:mm
|
||||
* form.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
char *
|
||||
findJavaTZ_md(const char *java_home_dir)
|
||||
{
|
||||
char *tz;
|
||||
char *javatz = NULL;
|
||||
char *freetz = NULL;
|
||||
|
||||
tz = getenv("TZ");
|
||||
|
||||
if (tz == NULL || *tz == '\0') {
|
||||
tz = getPlatformTimeZoneID();
|
||||
freetz = tz;
|
||||
}
|
||||
|
||||
if (tz != NULL) {
|
||||
/* Ignore preceding ':' */
|
||||
if (*tz == ':') {
|
||||
tz++;
|
||||
}
|
||||
#if defined(__linux__)
|
||||
/* Ignore "posix/" prefix on Linux. */
|
||||
if (strncmp(tz, "posix/", 6) == 0) {
|
||||
tz += 6;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_AIX)
|
||||
/* On AIX do the platform to Java mapping. */
|
||||
javatz = mapPlatformToJavaTimezone(java_home_dir, tz);
|
||||
if (freetz != NULL) {
|
||||
free((void *) freetz);
|
||||
}
|
||||
#else
|
||||
#if defined(__solaris__)
|
||||
/* Solaris might use localtime, so handle it here. */
|
||||
if (strcmp(tz, "localtime") == 0) {
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return javatz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
|
||||
*/
|
||||
|
||||
#if defined(MACOSX)
|
||||
|
||||
char *
|
||||
getGMTOffsetID()
|
||||
{
|
||||
time_t offset;
|
||||
char sign, buf[32];
|
||||
struct tm *local_tm;
|
||||
time_t clock;
|
||||
time_t currenttime;
|
||||
|
||||
clock = time(NULL);
|
||||
tzset();
|
||||
local_tm = localtime(&clock);
|
||||
if (local_tm->tm_gmtoff >= 0) {
|
||||
offset = (time_t) local_tm->tm_gmtoff;
|
||||
sign = '+';
|
||||
} else {
|
||||
offset = (time_t) -local_tm->tm_gmtoff;
|
||||
sign = '-';
|
||||
}
|
||||
sprintf(buf, (const char *)"GMT%c%02d:%02d",
|
||||
sign, (int)(offset/3600), (int)((offset%3600)/60));
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char *
|
||||
getGMTOffsetID()
|
||||
{
|
||||
time_t offset;
|
||||
char sign, buf[32];
|
||||
#if defined(__solaris__)
|
||||
struct tm localtm;
|
||||
time_t currenttime;
|
||||
|
||||
currenttime = time(NULL);
|
||||
if (localtime_r(¤ttime, &localtm) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offset = localtm.tm_isdst ? altzone : timezone;
|
||||
#else
|
||||
offset = timezone;
|
||||
#endif
|
||||
|
||||
if (offset == 0) {
|
||||
return strdup("GMT");
|
||||
}
|
||||
|
||||
/* Note that the time offset direction is opposite. */
|
||||
if (offset > 0) {
|
||||
sign = '-';
|
||||
} else {
|
||||
offset = -offset;
|
||||
sign = '+';
|
||||
}
|
||||
sprintf(buf, (const char *)"GMT%c%02d:%02d",
|
||||
sign, (int)(offset/3600), (int)((offset%3600)/60));
|
||||
return strdup(buf);
|
||||
}
|
||||
#endif /* MACOSX */
|
||||
|
Loading…
Reference in New Issue
Block a user