diff --git a/make/lib/CoreLibraries.gmk b/make/lib/CoreLibraries.gmk index 758fa8e59b5e300676e333204247705a7d34c732..066a4bf0928c5313ebdb7f03be05a02565bc0a37 100644 --- a/make/lib/CoreLibraries.gmk +++ b/make/lib/CoreLibraries.gmk @@ -205,6 +205,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \ -framework Foundation \ -framework Security -framework SystemConfiguration, \ LDFLAGS_SUFFIX_windows := -export:winFileHandleOpen -export:handleLseek \ + -export:getErrorString \ jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \ shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \ advapi32.lib version.lib, \ diff --git a/make/mapfiles/libjava/mapfile-vers b/make/mapfiles/libjava/mapfile-vers index c4775ea05ee132506cfbb8020cf9dec1cd3813ea..618d50111735738532ec0fc2e8c4e6d0155f4cd7 100644 --- a/make/mapfiles/libjava/mapfile-vers +++ b/make/mapfiles/libjava/mapfile-vers @@ -284,6 +284,8 @@ SUNWprivate_1.1 { # ZipFile.c needs this one throwFileNotFoundException; + # zip_util.c needs this + getErrorString; # Java_sun_misc_VM_getState; threads.c # Java_sun_misc_VM_threadsSuspended; threads.c diff --git a/src/share/native/common/jni_util.h b/src/share/native/common/jni_util.h index 0242d71f497fd3b29369ff9338c6a0a813373cf1..cdfaa63dc0c263d06dc1c313cd32bc8f2f108fb5 100644 --- a/src/share/native/common/jni_util.h +++ b/src/share/native/common/jni_util.h @@ -391,6 +391,7 @@ void* getProcessHandle(); void buildJniFunctionName(const char *sym, const char *cname, char *jniEntryName); +extern int getErrorString(int err, char *buf, size_t len); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ diff --git a/src/share/native/java/util/zip/zip_util.c b/src/share/native/java/util/zip/zip_util.c index b172cde31729f67a54ea2bfeffdeda7c5a97c708..05ef55d131020c3200fbe135d63cdbb5b975a031 100644 --- a/src/share/native/java/util/zip/zip_util.c +++ b/src/share/native/java/util/zip/zip_util.c @@ -1449,6 +1449,7 @@ jboolean JNICALL ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) { char *msg; + char tmpbuf[1024]; strcpy(entryname, entry->name); if (entry->csize == 0) { @@ -1467,8 +1468,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) msg = zip->msg; ZIP_Unlock(zip); if (n == -1) { - jio_fprintf(stderr, "%s: %s\n", zip->name, - msg != 0 ? msg : strerror(errno)); + if (msg == 0) { + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + msg = tmpbuf; + } + jio_fprintf(stderr, "%s: %s\n", zip->name, msg); return JNI_FALSE; } buf += n; @@ -1481,8 +1485,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) if ((msg == NULL) || (*msg == 0)) { msg = zip->msg; } - jio_fprintf(stderr, "%s: %s\n", zip->name, - msg != 0 ? msg : strerror(errno)); + if (msg == 0) { + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + msg = tmpbuf; + } + jio_fprintf(stderr, "%s: %s\n", zip->name, msg); return JNI_FALSE; } } diff --git a/src/solaris/native/common/jni_util_md.c b/src/solaris/native/common/jni_util_md.c index 42ab2de0037eac3ae5a8b166a648eab6d0024e35..598dc41eb06994740b52bee41183a39e6095bdf2 100644 --- a/src/solaris/native/common/jni_util_md.c +++ b/src/solaris/native/common/jni_util_md.c @@ -37,6 +37,13 @@ char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) return NULL; } +#if defined(LINUX) && (defined(_GNU_SOURCE) || \ + (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE < 200112L \ + && defined(_XOPEN_SOURCE) && _XOPEN_SOURCE < 600)) +extern int __xpg_strerror_r(int, char *, size_t); +#define strerror_r(a, b, c) __xpg_strerror_r((a), (b), (c)) +#endif + void* getProcessHandle() { static void *procHandle = NULL; if (procHandle != NULL) { @@ -59,3 +66,9 @@ void buildJniFunctionName(const char *sym, const char *cname, } } +int +getErrorString(int err, char *buf, size_t len) +{ + if (err == 0 || len < 1) return 0; + return strerror_r(err, buf, len); +} diff --git a/src/solaris/native/java/io/io_util_md.c b/src/solaris/native/java/io/io_util_md.c index 5899a4103472118c6433917a3e6f12b7bdebc21e..f8fdc467de008ed7f97d4f2439c7bac5ba51d56a 100644 --- a/src/solaris/native/java/io/io_util_md.c +++ b/src/solaris/native/java/io/io_util_md.c @@ -216,13 +216,6 @@ size_t getLastErrorString(char *buf, size_t len) { if (errno == 0 || len < 1) return 0; - - const char *err = strerror(errno); - size_t n = strlen(err); - if (n >= len) - n = len - 1; - - strncpy(buf, err, n); - buf[n] = '\0'; - return n; + getErrorString(errno, buf, len); + return strlen(buf); } diff --git a/src/solaris/native/java/lang/UNIXProcess_md.c b/src/solaris/native/java/lang/UNIXProcess_md.c index bccd41d32aabfbfc87dd3b15637564301fc187a1..7df5d5901783c967f4ba8cd8e8e45373edcadff0 100644 --- a/src/solaris/native/java/lang/UNIXProcess_md.c +++ b/src/solaris/native/java/lang/UNIXProcess_md.c @@ -292,12 +292,13 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) static const char * const format = "error=%d, %s"; const char *detail = defaultDetail; char *errmsg; + char tmpbuf[1024]; jstring s; if (errnum != 0) { - const char *s = strerror(errnum); - if (strcmp(s, "Unknown error") != 0) - detail = s; + int ret = getErrorString(errnum, tmpbuf, sizeof(tmpbuf)); + if (ret != EINVAL) + detail = tmpbuf; } /* ASCII Decimal representation uses 2.4 times as many bits as binary. */ errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum)); diff --git a/src/solaris/native/java/net/PlainDatagramSocketImpl.c b/src/solaris/native/java/net/PlainDatagramSocketImpl.c index 67c5540c026d16890a83bb4db7ef63ac01161cce..77899d627b589b5c357d64887449285eddc7869a 100644 --- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c +++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c @@ -954,6 +954,7 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, jobject this) { jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); int arg, fd, t = 1; + char tmpbuf[1024]; #ifdef AF_INET6 int domain = ipv6_available() ? AF_INET6 : AF_INET; #else @@ -989,14 +990,14 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, arg = 65507; if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&arg, sizeof(arg)) < 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - strerror(errno)); + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); return; } if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&arg, sizeof(arg)) < 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - strerror(errno)); + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); return; } #endif /* __APPLE__ */ @@ -1004,15 +1005,16 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int)); #if defined(__linux__) - arg = 0; - int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP; - if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) && - (errno != ENOPROTOOPT)) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - strerror(errno)); - close(fd); - return; - } + arg = 0; + int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP; + if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) && + (errno != ENOPROTOOPT)) + { + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); + close(fd); + return; + } #endif #if defined (__linux__) && defined (AF_INET6) diff --git a/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c b/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c index e8a1623a87de4b030c87af1090fe17b88fb24de9..2799f9ab0d61f8a30d372e14ab66019db3ea83bc 100644 --- a/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c +++ b/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c @@ -308,21 +308,15 @@ Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) { JNIEXPORT jbyteArray Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error) { - char* msg; + char tmpbuf[1024]; jsize len; jbyteArray bytes; -#ifdef _AIX - /* strerror() is not thread-safe on AIX so we have to use strerror_r() */ - char buffer[256]; - msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r"; -#else - msg = strerror((int)error); -#endif - len = strlen(msg); + getErrorString((int)errno, tmpbuf, sizeof(tmpbuf)); + len = strlen(tmpbuf); bytes = (*env)->NewByteArray(env, len); if (bytes != NULL) { - (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg); + (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)tmpbuf); } return bytes; } diff --git a/src/windows/native/common/jni_util_md.c b/src/windows/native/common/jni_util_md.c index cdaaa2b5574fa80bcd2e6dd6613830f6e5567d3a..161b9032626cc279392ccd46cb721e23e602c94a 100644 --- a/src/windows/native/common/jni_util_md.c +++ b/src/windows/native/common/jni_util_md.c @@ -142,6 +142,15 @@ void* getProcessHandle() { return (void*)GetModuleHandle(NULL); } +int +getErrorString(int err, char *buf, size_t len) +{ + int ret = 0; + if (err == 0 || len < 1) return 0; + ret = strerror_s(buf, len, err); + return ret; +} + /* * Windows symbols can be simple like JNI_OnLoad or __stdcall format * like _JNI_OnLoad@8. We need to handle both. diff --git a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c index f9997d14f01ba3085ef102e576e1d2c883fcb7c1..3b1994dfc4e124ba0b213f0698ed0aa55595dc6a 100644 --- a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c +++ b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c @@ -2239,8 +2239,11 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj optlen = sizeof(optval.i); if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) { - char errmsg[255]; - sprintf(errmsg, "error getting socket option: %s\n", strerror(errno)); + char tmpbuf[255]; + int size = 0; + char errmsg[255 + 31]; + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + sprintf(errmsg, "error getting socket option: %s", tmpbuf); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg); return NULL; }