Mercurial > hg > jdk9-shenandoah > jdk
changeset 12722:4b948e5a3e77
8134505: Cleanup of "TimeZone_md.c"
Reviewed-by: rriggs, dsamersoff, simonis
Contributed-by: christoph.langer@sap.com
author | simonis |
---|---|
date | Thu, 10 Sep 2015 17:56:24 +0200 |
parents | f36fe8adbbd4 |
children | 56cc614c57f5 7ecf45f5fa46 |
files | src/java.base/unix/native/libjava/TimeZone_md.c |
diffstat | 1 files changed, 184 insertions(+), 188 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/unix/native/libjava/TimeZone_md.c Thu Sep 10 17:14:59 2015 +0200 +++ b/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 */