|
@@ -72,16 +72,27 @@ static int workaround_non_threadsafe_calls(JNIEnv *env, jclass clazz) {
|
|
|
static void stat_init(JNIEnv *env, jclass nativeio_class) {
|
|
|
// Init Stat
|
|
|
jclass clazz = (*env)->FindClass(env, "org/apache/hadoop/io/nativeio/NativeIO$Stat");
|
|
|
- PASS_EXCEPTIONS(env);
|
|
|
+ if (!clazz) {
|
|
|
+ return; // exception has been raised
|
|
|
+ }
|
|
|
stat_clazz = (*env)->NewGlobalRef(env, clazz);
|
|
|
+ if (!stat_clazz) {
|
|
|
+ return; // exception has been raised
|
|
|
+ }
|
|
|
stat_ctor = (*env)->GetMethodID(env, stat_clazz, "<init>",
|
|
|
- "(Ljava/lang/String;Ljava/lang/String;I)V");
|
|
|
-
|
|
|
+ "(III)V");
|
|
|
+ if (!stat_ctor) {
|
|
|
+ return; // exception has been raised
|
|
|
+ }
|
|
|
jclass obj_class = (*env)->FindClass(env, "java/lang/Object");
|
|
|
- assert(obj_class != NULL);
|
|
|
+ if (!obj_class) {
|
|
|
+ return; // exception has been raised
|
|
|
+ }
|
|
|
jmethodID obj_ctor = (*env)->GetMethodID(env, obj_class,
|
|
|
"<init>", "()V");
|
|
|
- assert(obj_ctor != NULL);
|
|
|
+ if (!obj_ctor) {
|
|
|
+ return; // exception has been raised
|
|
|
+ }
|
|
|
|
|
|
if (workaround_non_threadsafe_calls(env, nativeio_class)) {
|
|
|
pw_lock_object = (*env)->NewObject(env, obj_class, obj_ctor);
|
|
@@ -158,8 +169,6 @@ Java_org_apache_hadoop_io_nativeio_NativeIO_fstat(
|
|
|
JNIEnv *env, jclass clazz, jobject fd_object)
|
|
|
{
|
|
|
jobject ret = NULL;
|
|
|
- char *pw_buf = NULL;
|
|
|
- int pw_lock_locked = 0;
|
|
|
|
|
|
int fd = fd_get(env, fd_object);
|
|
|
PASS_EXCEPTIONS_GOTO(env, cleanup);
|
|
@@ -171,71 +180,14 @@ Java_org_apache_hadoop_io_nativeio_NativeIO_fstat(
|
|
|
goto cleanup;
|
|
|
}
|
|
|
|
|
|
- size_t pw_buflen = get_pw_buflen();
|
|
|
- if ((pw_buf = malloc(pw_buflen)) == NULL) {
|
|
|
- THROW(env, "java/lang/OutOfMemoryError", "Couldn't allocate memory for pw buffer");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- if (pw_lock_object != NULL) {
|
|
|
- if ((*env)->MonitorEnter(env, pw_lock_object) != JNI_OK) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- pw_lock_locked = 1;
|
|
|
- }
|
|
|
-
|
|
|
- // Grab username
|
|
|
- struct passwd pwd, *pwdp;
|
|
|
- while ((rc = getpwuid_r(s.st_uid, &pwd, pw_buf, pw_buflen, &pwdp)) != 0) {
|
|
|
- if (rc != ERANGE) {
|
|
|
- throw_ioe(env, rc);
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- free(pw_buf);
|
|
|
- pw_buflen *= 2;
|
|
|
- if ((pw_buf = malloc(pw_buflen)) == NULL) {
|
|
|
- THROW(env, "java/lang/OutOfMemoryError", "Couldn't allocate memory for pw buffer");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- }
|
|
|
- assert(pwdp == &pwd);
|
|
|
-
|
|
|
- jstring jstr_username = (*env)->NewStringUTF(env, pwd.pw_name);
|
|
|
- if (jstr_username == NULL) goto cleanup;
|
|
|
-
|
|
|
- // Grab group
|
|
|
- struct group grp, *grpp;
|
|
|
- while ((rc = getgrgid_r(s.st_gid, &grp, pw_buf, pw_buflen, &grpp)) != 0) {
|
|
|
- if (rc != ERANGE) {
|
|
|
- throw_ioe(env, rc);
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- free(pw_buf);
|
|
|
- pw_buflen *= 2;
|
|
|
- if ((pw_buf = malloc(pw_buflen)) == NULL) {
|
|
|
- THROW(env, "java/lang/OutOfMemoryError", "Couldn't allocate memory for pw buffer");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- }
|
|
|
- assert(grpp == &grp);
|
|
|
-
|
|
|
- jstring jstr_groupname = (*env)->NewStringUTF(env, grp.gr_name);
|
|
|
- PASS_EXCEPTIONS_GOTO(env, cleanup);
|
|
|
-
|
|
|
// Construct result
|
|
|
ret = (*env)->NewObject(env, stat_clazz, stat_ctor,
|
|
|
- jstr_username, jstr_groupname, s.st_mode);
|
|
|
+ (jint)s.st_uid, (jint)s.st_gid, (jint)s.st_mode);
|
|
|
|
|
|
cleanup:
|
|
|
- if (pw_buf != NULL) free(pw_buf);
|
|
|
- if (pw_lock_locked) {
|
|
|
- (*env)->MonitorExit(env, pw_lock_object);
|
|
|
- }
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* public static native void posix_fadvise(
|
|
|
* FileDescriptor fd, long offset, long len, int flags);
|
|
@@ -385,6 +337,128 @@ Java_org_apache_hadoop_io_nativeio_NativeIO_chmod(
|
|
|
(*env)->ReleaseStringUTFChars(env, j_path, path);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * static native String getUserName(int uid);
|
|
|
+ */
|
|
|
+JNIEXPORT jstring JNICALL
|
|
|
+Java_org_apache_hadoop_io_nativeio_NativeIO_getUserName(JNIEnv *env,
|
|
|
+jclass clazz, jint uid)
|
|
|
+{
|
|
|
+ int pw_lock_locked = 0;
|
|
|
+ if (pw_lock_object != NULL) {
|
|
|
+ if ((*env)->MonitorEnter(env, pw_lock_object) != JNI_OK) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ pw_lock_locked = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ char *pw_buf = NULL;
|
|
|
+ int rc;
|
|
|
+ size_t pw_buflen = get_pw_buflen();
|
|
|
+ if ((pw_buf = malloc(pw_buflen)) == NULL) {
|
|
|
+ THROW(env, "java/lang/OutOfMemoryError", "Couldn't allocate memory for pw buffer");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Grab username
|
|
|
+ struct passwd pwd, *pwdp;
|
|
|
+ while ((rc = getpwuid_r((uid_t)uid, &pwd, pw_buf, pw_buflen, &pwdp)) != 0) {
|
|
|
+ if (rc != ERANGE) {
|
|
|
+ throw_ioe(env, rc);
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ free(pw_buf);
|
|
|
+ pw_buflen *= 2;
|
|
|
+ if ((pw_buf = malloc(pw_buflen)) == NULL) {
|
|
|
+ THROW(env, "java/lang/OutOfMemoryError", "Couldn't allocate memory for pw buffer");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (pwdp == NULL) {
|
|
|
+ char msg[80];
|
|
|
+ snprintf(msg, sizeof(msg), "uid not found: %d", uid);
|
|
|
+ THROW(env, "java/io/IOException", msg);
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ if (pwdp != &pwd) {
|
|
|
+ char msg[80];
|
|
|
+ snprintf(msg, sizeof(msg), "pwd pointer inconsistent with reference. uid: %d", uid);
|
|
|
+ THROW(env, "java/lang/IllegalStateException", msg);
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ jstring jstr_username = (*env)->NewStringUTF(env, pwd.pw_name);
|
|
|
+
|
|
|
+cleanup:
|
|
|
+ if (pw_lock_locked) {
|
|
|
+ (*env)->MonitorExit(env, pw_lock_object);
|
|
|
+ }
|
|
|
+ if (pw_buf != NULL) free(pw_buf);
|
|
|
+ return jstr_username;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * static native String getGroupName(int gid);
|
|
|
+ */
|
|
|
+JNIEXPORT jstring JNICALL
|
|
|
+Java_org_apache_hadoop_io_nativeio_NativeIO_getGroupName(JNIEnv *env,
|
|
|
+jclass clazz, jint gid)
|
|
|
+{
|
|
|
+ int pw_lock_locked = 0;
|
|
|
+
|
|
|
+ if (pw_lock_object != NULL) {
|
|
|
+ if ((*env)->MonitorEnter(env, pw_lock_object) != JNI_OK) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ pw_lock_locked = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ char *pw_buf = NULL;
|
|
|
+ int rc;
|
|
|
+ size_t pw_buflen = get_pw_buflen();
|
|
|
+ if ((pw_buf = malloc(pw_buflen)) == NULL) {
|
|
|
+ THROW(env, "java/lang/OutOfMemoryError", "Couldn't allocate memory for pw buffer");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Grab group
|
|
|
+ struct group grp, *grpp;
|
|
|
+ while ((rc = getgrgid_r((uid_t)gid, &grp, pw_buf, pw_buflen, &grpp)) != 0) {
|
|
|
+ if (rc != ERANGE) {
|
|
|
+ throw_ioe(env, rc);
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ free(pw_buf);
|
|
|
+ pw_buflen *= 2;
|
|
|
+ if ((pw_buf = malloc(pw_buflen)) == NULL) {
|
|
|
+ THROW(env, "java/lang/OutOfMemoryError", "Couldn't allocate memory for pw buffer");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (grpp == NULL) {
|
|
|
+ char msg[80];
|
|
|
+ snprintf(msg, sizeof(msg), "gid not found: %d", gid);
|
|
|
+ THROW(env, "java/io/IOException", msg);
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ if (grpp != &grp) {
|
|
|
+ char msg[80];
|
|
|
+ snprintf(msg, sizeof(msg), "pwd pointer inconsistent with reference. gid: %d", gid);
|
|
|
+ THROW(env, "java/lang/IllegalStateException", msg);
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ jstring jstr_groupname = (*env)->NewStringUTF(env, grp.gr_name);
|
|
|
+ PASS_EXCEPTIONS_GOTO(env, cleanup);
|
|
|
+
|
|
|
+cleanup:
|
|
|
+ if (pw_lock_locked) {
|
|
|
+ (*env)->MonitorExit(env, pw_lock_object);
|
|
|
+ }
|
|
|
+ if (pw_buf != NULL) free(pw_buf);
|
|
|
+ return jstr_groupname;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
/*
|
|
|
* Throw a java.IO.IOException, generating the message from errno.
|