Path: blob/master/src/java.base/aix/native/libnio/fs/AixNativeDispatcher.c
41133 views
/*1* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2013, 2019 SAP SE. 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 <string.h>28#include <errno.h>29#include <sys/types.h>30#include <sys/mntctl.h>3132#include "jni.h"33#include "jni_util.h"3435#include "sun_nio_fs_AixNativeDispatcher.h"3637static jfieldID entry_name;38static jfieldID entry_dir;39static jfieldID entry_fstype;40static jfieldID entry_options;4142static jclass entry_cls;4344/**45* Call this to throw an internal UnixException when a system/library46* call fails47*/48static void throwUnixException(JNIEnv* env, int errnum) {49jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",50"(I)V", errnum);51if (x != NULL) {52(*env)->Throw(env, x);53}54}5556/**57* Initialization58*/59JNIEXPORT void JNICALL60Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)61{62jclass clazz;6364clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");65CHECK_NULL(clazz);66entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");67CHECK_NULL(entry_name);68entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");69CHECK_NULL(entry_dir);70entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");71CHECK_NULL(entry_fstype);72entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");73CHECK_NULL(entry_options);74entry_cls = (*env)->NewGlobalRef(env, clazz);75if (entry_cls == NULL) {76JNU_ThrowOutOfMemoryError(env, NULL);77return;78}79}8081/**82* Special implementation of getextmntent (see SolarisNativeDispatcher.c)83* that returns all entries at once.84*/85JNIEXPORT jobjectArray JNICALL86Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)87{88int must_free_buf = 0;89char stack_buf[1024];90char* buffer = stack_buf;91size_t buffer_size = 1024;92int num_entries;93int i;94jobjectArray ret;95struct vmount * vm;9697for (i = 0; i < 5; i++) {98num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);99if (num_entries != 0) {100break;101}102if (must_free_buf) {103free(buffer);104}105buffer_size *= 8;106buffer = malloc(buffer_size);107must_free_buf = 1;108}109/* Treat zero entries like errors. */110if (num_entries <= 0) {111if (must_free_buf) {112free(buffer);113}114throwUnixException(env, errno);115return NULL;116}117ret = (*env)->NewObjectArray(env, num_entries, entry_cls, NULL);118if (ret == NULL) {119if (must_free_buf) {120free(buffer);121}122return NULL;123}124vm = (struct vmount*)buffer;125for (i = 0; i < num_entries; i++) {126jsize len;127jbyteArray bytes;128const char* fstype;129/* We set all relevant attributes so there is no need to call constructor. */130jobject entry = (*env)->AllocObject(env, entry_cls);131if (entry == NULL) {132if (must_free_buf) {133free(buffer);134}135return NULL;136}137(*env)->SetObjectArrayElement(env, ret, i, entry);138139/* vm->vmt_data[...].vmt_size is 32 bit aligned and also includes NULL byte. */140/* Since we only need the characters, it is necessary to check string size manually. */141len = strlen((char*)vm + vm->vmt_data[VMT_OBJECT].vmt_off);142bytes = (*env)->NewByteArray(env, len);143if (bytes == NULL) {144if (must_free_buf) {145free(buffer);146}147return NULL;148}149(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_OBJECT].vmt_off));150(*env)->SetObjectField(env, entry, entry_name, bytes);151152len = strlen((char*)vm + vm->vmt_data[VMT_STUB].vmt_off);153bytes = (*env)->NewByteArray(env, len);154if (bytes == NULL) {155if (must_free_buf) {156free(buffer);157}158return NULL;159}160(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_STUB].vmt_off));161(*env)->SetObjectField(env, entry, entry_dir, bytes);162163switch (vm->vmt_gfstype) {164case MNT_J2:165fstype = "jfs2";166break;167case MNT_NAMEFS:168fstype = "namefs";169break;170case MNT_NFS:171fstype = "nfs";172break;173case MNT_JFS:174fstype = "jfs";175break;176case MNT_CDROM:177fstype = "cdrom";178break;179case MNT_PROCFS:180fstype = "procfs";181break;182case MNT_NFS3:183fstype = "nfs3";184break;185case MNT_AUTOFS:186fstype = "autofs";187break;188case MNT_UDF:189fstype = "udfs";190break;191case MNT_NFS4:192fstype = "nfs4";193break;194case MNT_CIFS:195fstype = "smbfs";196break;197default:198fstype = "unknown";199}200len = strlen(fstype);201bytes = (*env)->NewByteArray(env, len);202if (bytes == NULL) {203if (must_free_buf) {204free(buffer);205}206return NULL;207}208(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);209(*env)->SetObjectField(env, entry, entry_fstype, bytes);210211len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);212bytes = (*env)->NewByteArray(env, len);213if (bytes == NULL) {214if (must_free_buf) {215free(buffer);216}217return 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);221222/* goto the next vmount structure: */223vm = (struct vmount *)((char *)vm + vm->vmt_length);224}225226if (must_free_buf) {227free(buffer);228}229return ret;230}231232233