8134505: Cleanup of "TimeZone_md.c"

Reviewed-by: rriggs, dsamersoff, simonis
This commit is contained in:
Christoph Langer 2015-09-10 17:56:24 +02:00 committed by Volker Simonis
parent 7c9b107d1f
commit 981fa17133

View File

@ -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(&currenttime, &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(&currenttime, &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 */