好久没有写,不过想想就当个笔记吧!
ONE
find c definition from java.
1. first in os.java implemented in Posix.java
Os<--Posix
2. native
file: method:libcore_io_Posix.cpp
NATIVE_METHOD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
definition:
#define NATIVE_METHOD(className, functionName, signature) \
{ #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
function in c is "className ## _ ## functionName"
that's "Posix_connect"
in "libcore_io_Posix.cpp"
TWO
appendix:
pound in c.
a. double pound
The double pound sign is used for token concatenation:
Example:
#define BUILD_NAME(X,Y) X##.##Y
BUILD_NAME("Big", "Jim")
translates to:
"Big.Jim"
b. single pound
#define PRINT(i) printf(#i "= %d\n", i)
and use it like this:
int i = 5;
PRINT(i);
Result shown:
i = 5
THREE
c socket error to java socketexception
1. Posix_connect (in "libcore_io_Posix.cpp")
#define NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ...) ({ \
return_type _rc = -1; \
do { \
{ \
int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
AsynchronousSocketCloseMonitor _monitor(_fd); \
_rc = syscall_name(_fd, __VA_ARGS__); \
} \
if (_rc == -1) { \
if (jniGetFDFromFileDescriptor(jni_env, java_fd) == -1) { \
jniThrowException(jni_env, "java/net/SocketException", "Socket closed"); \
break; \
} else if (errno != EINTR) { \
/* TODO: with a format string we could show the arguments too, like strace(1). */ \
throwErrnoException(jni_env, # syscall_name); \
break; \
} \
} \
} while (_rc == -1); \
_rc; })
will call the function
if there errorcode is rc==-1 and errno!=EINTR
it will throw an exception according to the errno.
static void throwException(JNIEnv* env, jclass exceptionClass, jmethodID ctor3, jmethodID ctor2,
const char* functionName, int error) {
jthrowable cause = NULL;
if (env->ExceptionCheck()) {
cause = env->ExceptionOccurred();
env->ExceptionClear();
}
ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName));
if (detailMessage.get() == NULL) {
// Not really much we can do here. We're probably dead in the water,
// but let's try to stumble on...
env->ExceptionClear();
}
jobject exception;
if (cause != NULL) {
exception = env->NewObject(exceptionClass, ctor3, detailMessage.get(), error, cause);
} else {
exception = env->NewObject(exceptionClass, ctor2, detailMessage.get(), error);
}
env->Throw(reinterpret_cast<jthrowable>(exception));
}
the exception will be generated here.