< prev index next >
src/java.base/unix/native/libjava/TimeZone_md.c
Print this page
@@ -38,33 +38,32 @@
#ifdef __solaris__
#include <libscf.h>
#endif
#include "jvm.h"
+#include "TimeZone_md.h"
#define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++;
#if !defined(__solaris__) || defined(__sparcv9) || defined(amd64)
#define fileopen fopen
#define filegets fgets
#define fileclose fclose
#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) */
/*
* Returns a pointer to the zone ID portion of the given zoneinfo file
* name, or NULL if the given string doesn't contain "zoneinfo/".
*/
@@ -316,12 +315,13 @@
tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
free((void *) buf);
return tz;
}
-#else
-#ifdef __solaris__
+
+#elif defined(__solaris__)
+
#if !defined(__sparcv9) && !defined(amd64)
/*
* Those file* functions mimic the UNIX stream io functions. This is
* because of the limitation of the number of open files on Solaris
@@ -442,12 +442,11 @@
return s;
}
}
/*NOTREACHED*/
}
-#endif /* not __sparcv9 */
-
+#endif /* !defined(__sparcv9) && !defined(amd64) */
/*
* Performs Solaris dependent mapping. Returns a zone ID if
* found. Otherwise, NULL is returned. Solaris libc looks up
* "/etc/default/init" to get the default TZ value if TZ is not defined
@@ -544,11 +543,11 @@
scf_handle_destroy(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/.
*/
static char *
getSolarisDefaultZoneID() {
@@ -613,14 +612,13 @@
(void) close(fd);
tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
free((void *) buf);
return tz;
}
-#endif /*__solaris__*/
-#endif /*__linux__*/
-#ifdef _AIX
+#elif defined(_AIX)
+
static char *
getPlatformTimeZoneID()
{
FILE *fp;
char *tz = NULL;
@@ -642,12 +640,116 @@
(void) fclose(fp);
}
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 *str_tmp = NULL;
+ char *javatz = NULL;
+ size_t tz_len = 0;
+ 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.
+ */
+ tz_len = strlen(tz);
+ tz_buf = (char *)malloc(tz_len + 1);
+ strncpy(tz_buf, tz, tz_len);
+ tz_buf[tz_len] = 0;
+ temp_tz = strtok_r(tz_buf, ",", &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 (tz_buf != NULL ) {
+ free((void *) tz_buf);
+ }
+
+ if (javatz == NULL) {
+ return getGMTOffsetID();
+ }
+
+ return javatz;
+}
+
+#endif /*_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
@@ -662,58 +764,54 @@
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 == ':') {
+ if (tz != NULL) {
+ /* Ignore preceding ':' */
+ if (*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.
- */
+ /* Ignore "posix/" prefix on Linux. */
if (strncmp(tz, "posix/", 6) == 0) {
tz += 6;
}
#endif
- javatz = strdup(tz);
+
+#if defined(_AIX)
+ /* On AIX do the platform to Java mapping. */
+ javatz = mapPlatformToJavaTimezone(java_home_dir, tz);
if (freetz != NULL) {
free((void *) freetz);
}
-
-#ifdef _AIX
- freetz = mapPlatformToJavaTimezone(java_home_dir, javatz);
- if (javatz != NULL) {
- free((void *) javatz);
+#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;
}
- javatz = freetz;
#endif
}
return javatz;
}
@@ -745,10 +843,11 @@
}
sprintf(buf, (const char *)"GMT%c%02d:%02d",
sign, (int)(offset/3600), (int)((offset%3600)/60));
return strdup(buf);
}
+
#else
char *
getGMTOffsetID()
{
@@ -764,11 +863,11 @@
}
offset = localtm.tm_isdst ? altzone : timezone;
#else
offset = timezone;
-#endif /*__linux__*/
+#endif
if (offset == 0) {
return strdup("GMT");
}
@@ -782,103 +881,5 @@
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 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
-
< prev index next >