src/java.base/aix/native/libnio/fs/AixNativeDispatcher.c

Print this page


   1 /*
   2  * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright 2013 SAP AG. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  */
  26 




  27 #include <stdlib.h>
  28 #include <errno.h>
  29 #include <sys/types.h>
  30 #include <sys/mntctl.h>
  31 
  32 #include "jni.h"
  33 #include "jni_util.h"








  34 
  35 #include "sun_nio_fs_AixNativeDispatcher.h"
  36 
  37 static jfieldID entry_name;
  38 static jfieldID entry_dir;
  39 static jfieldID entry_fstype;
  40 static jfieldID entry_options;
  41 
  42 static jclass entry_cls;
  43 












  44 /**
  45  * Call this to throw an internal UnixException when a system/library
  46  * call fails
  47  */
  48 static void throwUnixException(JNIEnv* env, int errnum) {
  49     jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
  50         "(I)V", errnum);
  51     if (x != NULL) {
  52         (*env)->Throw(env, x);
  53     }
  54 }
  55 
  56 /**
  57  * Initialization
  58  */
  59 JNIEXPORT void JNICALL
  60 Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
  61 {

  62     jclass clazz;
  63 
  64     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
  65     CHECK_NULL(clazz);
  66     entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
  67     CHECK_NULL(entry_name);
  68     entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
  69     CHECK_NULL(entry_dir);
  70     entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
  71     CHECK_NULL(entry_fstype);
  72     entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
  73     CHECK_NULL(entry_options);
  74     entry_cls = (*env)->NewGlobalRef(env, clazz);
  75     if (entry_cls == NULL) {
  76         JNU_ThrowOutOfMemoryError(env, NULL);
  77         return;
  78     }





  79 }
  80 
  81 /**
  82  * Special implementation of getextmntent (see SolarisNativeDispatcher.c)
  83  * that returns all entries at once.
  84  */
  85 JNIEXPORT jobjectArray JNICALL
  86 Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)
  87 {
  88     int must_free_buf = 0;
  89     char stack_buf[1024];
  90     char* buffer = stack_buf;
  91     size_t buffer_size = 1024;
  92     int num_entries;
  93     int i;
  94     jobjectArray ret;
  95     struct vmount * vm;
  96 
  97     for (i = 0; i < 5; i++) {
  98         num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);


 210 
 211         len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);
 212         bytes = (*env)->NewByteArray(env, len);
 213         if (bytes == NULL) {
 214             if (must_free_buf) {
 215                 free(buffer);
 216             }
 217             return NULL;
 218         }
 219         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));
 220         (*env)->SetObjectField(env, entry, entry_options, bytes);
 221 
 222         /* goto the next vmount structure: */
 223         vm = (struct vmount *)((char *)vm + vm->vmt_length);
 224     }
 225 
 226     if (must_free_buf) {
 227         free(buffer);
 228     }
 229     return ret;







































































































































































































































 230 }
   1 /*
   2  * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright 2013 SAP AG. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  */
  26 
  27 /*
  28  * Portions Copyright (c) 2014 IBM Corporation
  29  */
  30 
  31 #include <stdlib.h>
  32 #include <errno.h>
  33 #include <sys/types.h>
  34 #include <sys/mntctl.h>
  35 
  36 #include "jni.h"
  37 #include "jni_util.h"
  38 #include "jvm.h"
  39 #include "jlong.h"
  40 
  41 #include <stdio.h>
  42 #include <dlfcn.h>
  43 #include <mntent.h>
  44 #include <sys/vmount.h>
  45 #include "net_util.h"
  46 
  47 #include "sun_nio_fs_AixNativeDispatcher.h"
  48 
  49 static jfieldID entry_name;
  50 static jfieldID entry_dir;
  51 static jfieldID entry_fstype;
  52 static jfieldID entry_options;
  53 
  54 static jclass entry_cls;
  55 
  56 typedef size_t fgetxattr_func_t(int fd, const char* name, void* value, size_t size);
  57 typedef int fsetxattr_func_t(int fd, const char* name, void* value, size_t size, int flags);
  58 typedef int fremovexattr_func_t(int fd, const char* name);
  59 typedef int flistxattr_func_t(int fd, char* list, size_t size);
  60 
  61 fgetxattr_func_t* fgetxattr_func = NULL;
  62 fsetxattr_func_t* fsetxattr_func = NULL;
  63 fremovexattr_func_t* fremovexattr_func = NULL;
  64 flistxattr_func_t* flistxattr_func = NULL;
  65 
  66 
  67 
  68 /**
  69  * Call this to throw an internal UnixException when a system/library
  70  * call fails
  71  */
  72 static void throwUnixException(JNIEnv* env, int errnum) {
  73     jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
  74         "(I)V", errnum);
  75     if (x != NULL) {
  76         (*env)->Throw(env, x);
  77     }
  78 }
  79 
  80 /**
  81  * Initialization
  82  */
  83 JNIEXPORT void JNICALL
  84 Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
  85 {
  86     jint flags = 0;
  87     jclass clazz;
  88 
  89     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
  90     CHECK_NULL(clazz);
  91     entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
  92     CHECK_NULL(entry_name);
  93     entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
  94     CHECK_NULL(entry_dir);
  95     entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
  96     CHECK_NULL(entry_fstype);
  97     entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
  98     CHECK_NULL(entry_options);
  99     entry_cls = (*env)->NewGlobalRef(env, clazz);
 100     if (entry_cls == NULL) {
 101          JNU_ThrowOutOfMemoryError(env, NULL);
 102          return;
 103      }
 104 
 105     fgetxattr_func = (fgetxattr_func_t*)dlsym(RTLD_DEFAULT, "fgetxattr");
 106     fsetxattr_func = (fsetxattr_func_t*)dlsym(RTLD_DEFAULT, "fsetxattr");
 107     fremovexattr_func = (fremovexattr_func_t*)dlsym(RTLD_DEFAULT, "fremovexattr");
 108     flistxattr_func = (flistxattr_func_t*)dlsym(RTLD_DEFAULT, "flistxattr");
 109 }
 110 
 111 /**
 112  * Special implementation of getextmntent (see SolarisNativeDispatcher.c)
 113  * that returns all entries at once.
 114  */
 115 JNIEXPORT jobjectArray JNICALL
 116 Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)
 117 {
 118     int must_free_buf = 0;
 119     char stack_buf[1024];
 120     char* buffer = stack_buf;
 121     size_t buffer_size = 1024;
 122     int num_entries;
 123     int i;
 124     jobjectArray ret;
 125     struct vmount * vm;
 126 
 127     for (i = 0; i < 5; i++) {
 128         num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);


 240 
 241         len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);
 242         bytes = (*env)->NewByteArray(env, len);
 243         if (bytes == NULL) {
 244             if (must_free_buf) {
 245                 free(buffer);
 246             }
 247             return NULL;
 248         }
 249         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));
 250         (*env)->SetObjectField(env, entry, entry_options, bytes);
 251 
 252         /* goto the next vmount structure: */
 253         vm = (struct vmount *)((char *)vm + vm->vmt_length);
 254     }
 255 
 256     if (must_free_buf) {
 257         free(buffer);
 258     }
 259     return ret;
 260 }
 261 
 262 JNIEXPORT jint JNICALL
 263 Java_sun_nio_fs_AixNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,
 264     jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
 265 {
 266     size_t res = -1;
 267     const char* name = jlong_to_ptr(nameAddress);
 268     void* value = jlong_to_ptr(valueAddress);
 269 
 270     if (fgetxattr_func == NULL) {
 271         errno = ENOTSUP;
 272     } else {
 273         /* EINTR not documented */
 274         res = (*fgetxattr_func)(fd, name, value, valueLen);
 275     }
 276     if (res == (size_t)-1) {
 277         throwUnixException(env, errno);
 278     }
 279     return (jint)res;
 280 }
 281 
 282 JNIEXPORT void JNICALL
 283 Java_sun_nio_fs_AixNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,
 284     jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
 285 {
 286     int res = -1;
 287     const char* name = jlong_to_ptr(nameAddress);
 288     void* value = jlong_to_ptr(valueAddress);
 289 
 290     if (fsetxattr_func == NULL) {
 291         errno = ENOTSUP;
 292     } else {
 293         /* EINTR not documented */
 294         res = (*fsetxattr_func)(fd, name, value, valueLen, 0);
 295     }
 296     if (res == -1) {
 297         throwUnixException(env, errno);
 298     }
 299 }
 300 
 301 JNIEXPORT void JNICALL
 302 Java_sun_nio_fs_AixNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,
 303     jint fd, jlong nameAddress)
 304 {
 305     int res = -1;
 306     const char* name = jlong_to_ptr(nameAddress);
 307 
 308     if (fremovexattr_func == NULL) {
 309         errno = ENOTSUP;
 310     } else {
 311         /* EINTR not documented */
 312         res = (*fremovexattr_func)(fd, name);
 313     }
 314     if (res == -1) {
 315         throwUnixException(env, errno);
 316     }
 317 }
 318 
 319 JNIEXPORT jint JNICALL
 320 Java_sun_nio_fs_AixNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,
 321     jint fd, jlong listAddress, jint size)
 322 {
 323     size_t res = -1;
 324     char* list = jlong_to_ptr(listAddress);
 325 
 326     if (flistxattr_func == NULL) {
 327         errno = ENOTSUP;
 328     } else {
 329         /* EINTR not documented */
 330         res = (*flistxattr_func)(fd, list, (size_t)size);
 331     }
 332     if (res == (size_t)-1) {
 333         throwUnixException(env, errno);
 334     }
 335     return (jint)res;
 336 }
 337 
 338 JNIEXPORT jint JNICALL
 339 Java_sun_nio_fs_AixNativeDispatcher_queryMountEntrySize(JNIEnv* env, jclass this)
 340 {
 341   int size;
 342 
 343   if (mntctl(MCTL_QUERY, sizeof(size), (char *)&size) != 0) {
 344     return 0;
 345   }
 346   return size;
 347 }
 348 
 349 JNIEXPORT void JNICALL
 350 Java_sun_nio_fs_AixNativeDispatcher_getAixMountEntries(JNIEnv* env, jclass this, jobject entries, jlong bufferAddress, jint size)
 351 {
 352   jmethodID addMethod, constructor;
 353   jclass arrayListClass, unixMountEntryClass;
 354   int entryNum;
 355   char *buffer = NULL;
 356   char *ptr = NULL;
 357   char *name = NULL;
 358   char *type = NULL;
 359   char *path = NULL;
 360   char *opts = NULL;
 361   int len, count;
 362   jboolean readOnly = JNI_FALSE;
 363   jobject mountEntry;
 364   jbyteArray bytes;
 365   struct vmount * vmountPtr = NULL;
 366   jfieldID entry_name;
 367   jfieldID entry_dir;
 368   jfieldID entry_fstype;
 369   jfieldID entry_options;
 370 
 371   arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
 372   if ((*env)->ExceptionOccurred(env)) {
 373     return;
 374   }
 375 
 376   addMethod = (*env)->GetMethodID(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
 377   if ((*env)->ExceptionOccurred(env)) {
 378     return;
 379   }
 380 
 381   unixMountEntryClass = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
 382   if ((*env)->ExceptionOccurred(env)) {
 383     return;
 384   }
 385 
 386   constructor = (*env)->GetMethodID(env, unixMountEntryClass, "<init>", "()V");
 387   if ((*env)->ExceptionOccurred(env)) {
 388     return;
 389   }
 390 
 391   buffer = (char *)jlong_to_ptr(bufferAddress);
 392 
 393   entryNum = mntctl(MCTL_QUERY, size, buffer);
 394 
 395   if (entryNum <= 0) {
 396     return;
 397   }
 398 
 399   entry_name = (*env)->GetFieldID(env, unixMountEntryClass, "name", "[B");
 400   entry_dir = (*env)->GetFieldID(env, unixMountEntryClass, "dir", "[B");
 401   entry_fstype = (*env)->GetFieldID(env, unixMountEntryClass, "fstype", "[B");
 402   entry_options = (*env)->GetFieldID(env, unixMountEntryClass, "opts", "[B");
 403 
 404   ptr = buffer;
 405   for (count = 0; count < entryNum; count++, ptr += vmountPtr->vmt_length) {
 406     vmountPtr = (struct vmount *)ptr;
 407     switch (vmountPtr->vmt_gfstype) {
 408     case MNT_JFS:
 409       type = "jfs";
 410       break;
 411     case MNT_J2:
 412       type = "jfs2";
 413       break;
 414     case MNT_NFS:
 415       type = "nfs";
 416       break;
 417     case MNT_CDROM:
 418       type = "cdrom";
 419       break;
 420     case MNT_PROCFS:
 421       type = "procfs";
 422       break;
 423     default:
 424       type = "unknown";
 425     }
 426     if (vmountPtr->vmt_flags & MNT_READONLY) {
 427       readOnly = JNI_TRUE;
 428     } else {
 429       readOnly = JNI_FALSE;
 430     }
 431 
 432     name = (char *)(ptr + vmountPtr->vmt_data[VMT_OBJECT].vmt_off);
 433     path = (char *)(ptr + vmountPtr->vmt_data[VMT_STUB].vmt_off);
 434 
 435     mountEntry = (*env)->NewObject(env, unixMountEntryClass, constructor);
 436 
 437     // name
 438     len = strlen(name);
 439     bytes = (*env)->NewByteArray(env, len);
 440     if (bytes == NULL) {
 441         break;
 442     }
 443     (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
 444     (*env)->SetObjectField(env, mountEntry, entry_name, bytes);
 445 
 446     // dir
 447     len = strlen(path);
 448     bytes = (*env)->NewByteArray(env, len);
 449     if (bytes == NULL) {
 450         break;
 451     }
 452     (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)path);
 453     (*env)->SetObjectField(env, mountEntry, entry_dir, bytes);
 454 
 455     // filetype
 456     len = strlen(type);
 457     bytes = (*env)->NewByteArray(env, len);
 458     if (bytes == NULL) {
 459         break;
 460     }
 461     (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)type);
 462     (*env)->SetObjectField(env, mountEntry, entry_fstype, bytes);
 463 
 464     // opts
 465     if (readOnly) {
 466       opts = "ro";
 467     } else {
 468       opts = "";
 469     }
 470     len = strlen(opts);
 471     bytes = (*env)->NewByteArray(env, len);
 472     if (bytes == NULL) {
 473         break;
 474     }
 475     (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)opts);
 476     (*env)->SetObjectField(env, mountEntry, entry_options, bytes);
 477 
 478     if ((*env)->ExceptionOccurred(env)) {
 479       (*env)->ExceptionDescribe(env);
 480       goto error;
 481     }
 482     (*env)->CallBooleanMethod(env, entries, addMethod, mountEntry);
 483     if ((*env)->ExceptionOccurred(env)) {
 484       (*env)->ExceptionDescribe(env);
 485       goto error;
 486     }
 487   }
 488 
 489 error:
 490   return;
 491 }