Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/aix/native/sun/nio/fs/AixNativeDispatcher.c
38892 views
/*1* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.2* Copyright 2013 SAP AG. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation. Oracle designates this8* particular file as subject to the "Classpath" exception as provided9* by Oracle in the LICENSE file that accompanied this code.10*11* This code is distributed in the hope that it will be useful, but WITHOUT12* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or13* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License14* version 2 for more details (a copy is included in the LICENSE file that15* accompanied this code).16*17* You should have received a copy of the GNU General Public License version18* 2 along with this work; if not, write to the Free Software Foundation,19* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.20*21* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA22* or visit www.oracle.com if you need additional information or have any23* questions.24*/2526#include <stdlib.h>27#include <errno.h>28#include <sys/types.h>29#include <sys/mntctl.h>3031#include "jni.h"32#include "jni_util.h"3334#include "sun_nio_fs_AixNativeDispatcher.h"3536static jfieldID entry_name;37static jfieldID entry_dir;38static jfieldID entry_fstype;39static jfieldID entry_options;4041static jclass entry_cls;4243/**44* Call this to throw an internal UnixException when a system/library45* call fails46*/47static void throwUnixException(JNIEnv* env, int errnum) {48jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",49"(I)V", errnum);50if (x != NULL) {51(*env)->Throw(env, x);52}53}5455/**56* Initialization57*/58JNIEXPORT void JNICALL59Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)60{61jclass clazz;6263clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");64CHECK_NULL(clazz);65entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");66CHECK_NULL(entry_name);67entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");68CHECK_NULL(entry_dir);69entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");70CHECK_NULL(entry_fstype);71entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");72CHECK_NULL(entry_options);73entry_cls = (*env)->NewGlobalRef(env, clazz);74if (entry_cls == NULL) {75JNU_ThrowOutOfMemoryError(env, NULL);76return;77}78}7980/**81* Special implementation of getextmntent (see SolarisNativeDispatcher.c)82* that returns all entries at once.83*/84JNIEXPORT jobjectArray JNICALL85Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)86{87int must_free_buf = 0;88char stack_buf[1024];89char* buffer = stack_buf;90size_t buffer_size = 1024;91int num_entries;92int i;93jobjectArray ret;94struct vmount * vm;9596for (i = 0; i < 5; i++) {97num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);98if (num_entries != 0) {99break;100}101if (must_free_buf) {102free(buffer);103}104buffer_size *= 8;105buffer = malloc(buffer_size);106must_free_buf = 1;107}108/* Treat zero entries like errors. */109if (num_entries <= 0) {110if (must_free_buf) {111free(buffer);112}113throwUnixException(env, errno);114return NULL;115}116ret = (*env)->NewObjectArray(env, num_entries, entry_cls, NULL);117if (ret == NULL) {118if (must_free_buf) {119free(buffer);120}121return NULL;122}123vm = (struct vmount*)buffer;124for (i = 0; i < num_entries; i++) {125jsize len;126jbyteArray bytes;127const char* fstype;128/* We set all relevant attributes so there is no need to call constructor. */129jobject entry = (*env)->AllocObject(env, entry_cls);130if (entry == NULL) {131if (must_free_buf) {132free(buffer);133}134return NULL;135}136(*env)->SetObjectArrayElement(env, ret, i, entry);137138/* vm->vmt_data[...].vmt_size is 32 bit aligned and also includes NULL byte. */139/* Since we only need the characters, it is necessary to check string size manually. */140len = strlen((char*)vm + vm->vmt_data[VMT_OBJECT].vmt_off);141bytes = (*env)->NewByteArray(env, len);142if (bytes == NULL) {143if (must_free_buf) {144free(buffer);145}146return NULL;147}148(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_OBJECT].vmt_off));149(*env)->SetObjectField(env, entry, entry_name, bytes);150151len = strlen((char*)vm + vm->vmt_data[VMT_STUB].vmt_off);152bytes = (*env)->NewByteArray(env, len);153if (bytes == NULL) {154if (must_free_buf) {155free(buffer);156}157return NULL;158}159(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_STUB].vmt_off));160(*env)->SetObjectField(env, entry, entry_dir, bytes);161162switch (vm->vmt_gfstype) {163case MNT_J2:164fstype = "jfs2";165break;166case MNT_NAMEFS:167fstype = "namefs";168break;169case MNT_NFS:170fstype = "nfs";171break;172case MNT_JFS:173fstype = "jfs";174break;175case MNT_CDROM:176fstype = "cdrom";177break;178case MNT_PROCFS:179fstype = "procfs";180break;181case MNT_NFS3:182fstype = "nfs3";183break;184case MNT_AUTOFS:185fstype = "autofs";186break;187case MNT_UDF:188fstype = "udfs";189break;190case MNT_NFS4:191fstype = "nfs4";192break;193case MNT_CIFS:194fstype = "smbfs";195break;196default:197fstype = "unknown";198}199len = strlen(fstype);200bytes = (*env)->NewByteArray(env, len);201if (bytes == NULL) {202if (must_free_buf) {203free(buffer);204}205return NULL;206}207(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);208(*env)->SetObjectField(env, entry, entry_fstype, bytes);209210len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);211bytes = (*env)->NewByteArray(env, len);212if (bytes == NULL) {213if (must_free_buf) {214free(buffer);215}216return NULL;217}218(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));219(*env)->SetObjectField(env, entry, entry_options, bytes);220221/* goto the next vmount structure: */222vm = (struct vmount *)((char *)vm + vm->vmt_length);223}224225if (must_free_buf) {226free(buffer);227}228return ret;229}230231232