< 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 >