diff options
| -rw-r--r-- | libcore/luni/src/main/native/java_net_NetworkInterface.cpp | 4 | ||||
| -rw-r--r-- | libnativehelper/JNIHelp.c | 34 | ||||
| -rw-r--r-- | libnativehelper/README | 9 | ||||
| -rw-r--r-- | libnativehelper/include/nativehelper/JNIHelp.h | 8 |
4 files changed, 32 insertions, 23 deletions
diff --git a/libcore/luni/src/main/native/java_net_NetworkInterface.cpp b/libcore/luni/src/main/native/java_net_NetworkInterface.cpp index 7d270569a..abc6e16ce 100644 --- a/libcore/luni/src/main/native/java_net_NetworkInterface.cpp +++ b/libcore/luni/src/main/native/java_net_NetworkInterface.cpp @@ -75,7 +75,9 @@ static void jniThrowOutOfMemoryError(JNIEnv* env) { } static void jniThrowSocketException(JNIEnv* env) { - jniThrowException(env, "java/net/SocketException", strerror(errno)); + char buf[BUFSIZ]; + jniThrowException(env, "java/net/SocketException", + jniStrError(errno, buf, sizeof(buf))); } // Creates an InetAddress[] of size 'addressCount' from the ifc_req structs diff --git a/libnativehelper/JNIHelp.c b/libnativehelper/JNIHelp.c index aacecb68b..fa6b53263 100644 --- a/libnativehelper/JNIHelp.c +++ b/libnativehelper/JNIHelp.c @@ -59,30 +59,30 @@ int jniThrowException(JNIEnv* env, const char* className, const char* msg) */ int jniThrowIOException(JNIEnv* env, int errnum) { - // note: glibc has a nonstandard - // strerror_r that looks like this: - // char *strerror_r(int errnum, char *buf, size_t n); - - const char* message; char buffer[80]; - char* ret; - - buffer[0] = 0; - ret = (char*) strerror_r(errnum, buffer, sizeof(buffer)); + const char* message = jniStrError(errnum, buffer, sizeof(buffer)); + return jniThrowException(env, "java/io/IOException", message); +} +const char* jniStrError(int errnum, char* buf, size_t buflen) +{ + // note: glibc has a nonstandard strerror_r that returns char* rather + // than POSIX's int. + // char *strerror_r(int errnum, char *buf, size_t n); + char* ret = (char*) strerror_r(errnum, buf, buflen); if (((int)ret) == 0) { //POSIX strerror_r, success - message = buffer; + return buf; } else if (((int)ret) == -1) { //POSIX strerror_r, failure - - snprintf (buffer, sizeof(buffer), "errno %d", errnum); - message = buffer; + // (Strictly, POSIX only guarantees a value other than 0. The safest + // way to implement this function is to use C++ and overload on the + // type of strerror_r to accurately distinguish GNU from POSIX. But + // realistic implementations will always return -1.) + snprintf(buf, buflen, "errno %d", errnum); + return buf; } else { //glibc strerror_r returning a string - message = ret; + return ret; } - - return jniThrowException(env, "java/io/IOException", message); } - diff --git a/libnativehelper/README b/libnativehelper/README index 56ec17839..fa757c073 100644 --- a/libnativehelper/README +++ b/libnativehelper/README @@ -4,10 +4,9 @@ Support functions for Android's class libraries These are VM-agnostic native functions that implement methods for system class libraries. All code here: - - MUST be associated with a standard java.* class (no Android-specific stuff) - - MUST use JNI - - SHOULD be written in C rather than C++ (it's usually smaller and all of - our VMs are written in C) + - MUST not be associated with an android.* class (that code lives in + frameworks/base/). + - SHOULD be written in C rather than C++ where possible. -Some helper functions are defined in ../include/nativehelper/JNIHelp.h. +Some helper functions are defined in include/nativehelper/JNIHelp.h. diff --git a/libnativehelper/include/nativehelper/JNIHelp.h b/libnativehelper/include/nativehelper/JNIHelp.h index 3982797c8..1e268f845 100644 --- a/libnativehelper/include/nativehelper/JNIHelp.h +++ b/libnativehelper/include/nativehelper/JNIHelp.h @@ -58,6 +58,14 @@ int jniThrowException(C_JNIEnv* env, const char* className, const char* msg); int jniThrowIOException(C_JNIEnv* env, int errnum); /* + * Return a pointer to a locale-dependent error string explaining errno + * value 'errnum'. The returned pointer may or may not be equal to 'buf'. + * This function is thread-safe (unlike strerror) and portable (unlike + * strerror_r). + */ +const char* jniStrError(int errnum, char* buf, size_t buflen); + +/* * Create a java.io.FileDescriptor given an integer fd */ jobject jniCreateFileDescriptor(C_JNIEnv* env, int fd); |
