jdk/src/aix/native/sun/nio/fs/AixNativeDispatcher.c
changeset 22597 7515a991bb37
child 22631 ac85b05a53f4
equal deleted inserted replaced
22596:62542b8be764 22597:7515a991bb37
       
     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 jint JNICALL
       
    60 Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
       
    61 {
       
    62     jint flags = 0;
       
    63     jclass clazz;
       
    64 
       
    65     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
       
    66     if (clazz == NULL) {
       
    67         return 0;
       
    68     }
       
    69     entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
       
    70     entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
       
    71     entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
       
    72     entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
       
    73     entry_cls = (*env)->NewGlobalRef(env, clazz);
       
    74 
       
    75     return 0;
       
    76 }
       
    77 
       
    78 /**
       
    79  * Special implementation of getextmntent (see SolarisNativeDispatcher.c)
       
    80  * that returns all entries at once.
       
    81  */
       
    82 JNIEXPORT jobjectArray JNICALL
       
    83 Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)
       
    84 {
       
    85     int must_free_buf = 0;
       
    86     char stack_buf[1024];
       
    87     char* buffer = stack_buf;
       
    88     size_t buffer_size = 1024;
       
    89     int num_entries;
       
    90     int i;
       
    91     jobjectArray ret;
       
    92     struct vmount * vm;
       
    93 
       
    94     for (i = 0; i < 5; i++) {
       
    95         num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);
       
    96         if (num_entries != 0) {
       
    97             break;
       
    98         }
       
    99         if (must_free_buf) {
       
   100             free(buffer);
       
   101         }
       
   102         buffer_size *= 8;
       
   103         buffer = malloc(buffer_size);
       
   104         must_free_buf = 1;
       
   105     }
       
   106     /* Treat zero entries like errors. */
       
   107     if (num_entries <= 0) {
       
   108         if (must_free_buf) {
       
   109             free(buffer);
       
   110         }
       
   111         throwUnixException(env, errno);
       
   112         return NULL;
       
   113     }
       
   114     ret = (*env)->NewObjectArray(env, num_entries, entry_cls, NULL);
       
   115     if (ret == NULL) {
       
   116         if (must_free_buf) {
       
   117             free(buffer);
       
   118         }
       
   119         return NULL;
       
   120     }
       
   121     vm = (struct vmount*)buffer;
       
   122     for (i = 0; i < num_entries; i++) {
       
   123         jsize len;
       
   124         jbyteArray bytes;
       
   125         const char* fstype;
       
   126         /* We set all relevant attributes so there is no need to call constructor. */
       
   127         jobject entry = (*env)->AllocObject(env, entry_cls);
       
   128         if (entry == NULL) {
       
   129             if (must_free_buf) {
       
   130                 free(buffer);
       
   131             }
       
   132             return NULL;
       
   133         }
       
   134         (*env)->SetObjectArrayElement(env, ret, i, entry);
       
   135 
       
   136         /* vm->vmt_data[...].vmt_size is 32 bit aligned and also includes NULL byte. */
       
   137         /* Since we only need the characters, it is necessary to check string size manually. */
       
   138         len = strlen((char*)vm + vm->vmt_data[VMT_OBJECT].vmt_off);
       
   139         bytes = (*env)->NewByteArray(env, len);
       
   140         if (bytes == NULL) {
       
   141             if (must_free_buf) {
       
   142                 free(buffer);
       
   143             }
       
   144             return NULL;
       
   145         }
       
   146         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_OBJECT].vmt_off));
       
   147         (*env)->SetObjectField(env, entry, entry_name, bytes);
       
   148 
       
   149         len = strlen((char*)vm + vm->vmt_data[VMT_STUB].vmt_off);
       
   150         bytes = (*env)->NewByteArray(env, len);
       
   151         if (bytes == NULL) {
       
   152             if (must_free_buf) {
       
   153                 free(buffer);
       
   154             }
       
   155             return NULL;
       
   156         }
       
   157         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_STUB].vmt_off));
       
   158         (*env)->SetObjectField(env, entry, entry_dir, bytes);
       
   159 
       
   160         switch (vm->vmt_gfstype) {
       
   161             case MNT_J2:
       
   162                 fstype = "jfs2";
       
   163                 break;
       
   164             case MNT_NAMEFS:
       
   165                 fstype = "namefs";
       
   166                 break;
       
   167             case MNT_NFS:
       
   168                 fstype = "nfs";
       
   169                 break;
       
   170             case MNT_JFS:
       
   171                 fstype = "jfs";
       
   172                 break;
       
   173             case MNT_CDROM:
       
   174                 fstype = "cdrom";
       
   175                 break;
       
   176             case MNT_PROCFS:
       
   177                 fstype = "procfs";
       
   178                 break;
       
   179             case MNT_NFS3:
       
   180                 fstype = "nfs3";
       
   181                 break;
       
   182             case MNT_AUTOFS:
       
   183                 fstype = "autofs";
       
   184                 break;
       
   185             case MNT_UDF:
       
   186                 fstype = "udfs";
       
   187                 break;
       
   188             case MNT_NFS4:
       
   189                 fstype = "nfs4";
       
   190                 break;
       
   191             case MNT_CIFS:
       
   192                 fstype = "smbfs";
       
   193                 break;
       
   194             default:
       
   195                 fstype = "unknown";
       
   196         }
       
   197         len = strlen(fstype);
       
   198         bytes = (*env)->NewByteArray(env, len);
       
   199         if (bytes == NULL) {
       
   200             if (must_free_buf) {
       
   201                 free(buffer);
       
   202             }
       
   203             return NULL;
       
   204         }
       
   205         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
       
   206         (*env)->SetObjectField(env, entry, entry_fstype, bytes);
       
   207 
       
   208         len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);
       
   209         bytes = (*env)->NewByteArray(env, len);
       
   210         if (bytes == NULL) {
       
   211             if (must_free_buf) {
       
   212                 free(buffer);
       
   213             }
       
   214             return NULL;
       
   215         }
       
   216         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));
       
   217         (*env)->SetObjectField(env, entry, entry_options, bytes);
       
   218 
       
   219         /* goto the next vmount structure: */
       
   220         vm = (struct vmount *)((char *)vm + vm->vmt_length);
       
   221     }
       
   222 
       
   223     if (must_free_buf) {
       
   224         free(buffer);
       
   225     }
       
   226     return ret;
       
   227 }