--- a/jdk/src/java.base/unix/native/libjava/TimeZone_md.c Thu Sep 10 17:14:59 2015 +0200
+++ b/jdk/src/java.base/unix/native/libjava/TimeZone_md.c Thu Sep 10 17:56:24 2015 +0200
@@ -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 @@
{
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 @@
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 @@
*/
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 @@
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 @@
return tz;
}
}
-#endif /* __linux__ */
+#endif /* defined(__linux__) */
/*
* Next, try /etc/localtime to find the zone ID.
@@ -318,8 +319,9 @@
free((void *) buf);
return tz;
}
-#else
-#ifdef __solaris__
+
+#elif defined(__solaris__)
+
#if !defined(__sparcv9) && !defined(amd64)
/*
@@ -444,8 +446,7 @@
}
/*NOTREACHED*/
}
-#endif /* not __sparcv9 */
-
+#endif /* !defined(__sparcv9) && !defined(amd64) */
/*
* Performs Solaris dependent mapping. Returns a zone ID if
@@ -546,7 +547,7 @@
}
/*
- * 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 @@
free((void *) buf);
return tz;
}
-#endif /*__solaris__*/
-#endif /*__linux__*/
+
+#endif /* defined(__solaris__) */
-#ifdef _AIX
+#elif defined(_AIX)
+
static char *
getPlatformTimeZoneID()
{
@@ -644,178 +646,33 @@
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 @@
}
*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 @@
(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 */