Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
32288 views
/*1* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "jni.h"26#include "jni_util.h"27#include "jvm.h"28#include "jlong.h"2930#include <sys/param.h>31#include <sys/mount.h>32#ifdef ST_RDONLY33#define statfs statvfs34#define getfsstat getvfsstat35#define f_flags f_flag36#define ISREADONLY ST_RDONLY37#else38#define ISREADONLY MNT_RDONLY39#endif4041#include <stdlib.h>42#include <string.h>4344static jfieldID entry_name;45static jfieldID entry_dir;46static jfieldID entry_fstype;47static jfieldID entry_options;4849struct fsstat_iter {50struct statfs *buf;51int pos;52int nentries;53};5455#include "sun_nio_fs_BsdNativeDispatcher.h"5657static void throwUnixException(JNIEnv* env, int errnum) {58jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",59"(I)V", errnum);60if (x != NULL) {61(*env)->Throw(env, x);62}63}6465/**66* Initialize jfieldIDs67*/68JNIEXPORT void JNICALL69Java_sun_nio_fs_BsdNativeDispatcher_initIDs(JNIEnv* env, jclass this)70{71jclass clazz;7273clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");74CHECK_NULL(clazz);75entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");76CHECK_NULL(entry_name);77entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");78CHECK_NULL(entry_dir);79entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");80CHECK_NULL(entry_fstype);81entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");82CHECK_NULL(entry_options);83}8485JNIEXPORT jlong JNICALL86Java_sun_nio_fs_BsdNativeDispatcher_getfsstat(JNIEnv* env, jclass this)87{88int nentries;89size_t bufsize;90struct fsstat_iter *iter = malloc(sizeof(*iter));9192if (iter == NULL) {93JNU_ThrowOutOfMemoryError(env, "native heap");94return 0;95}9697iter->pos = 0;98iter->nentries = 0;99iter->buf = NULL;100101nentries = getfsstat(NULL, 0, MNT_NOWAIT);102103if (nentries <= 0) {104free(iter);105throwUnixException(env, errno);106return 0;107}108109// It's possible that a new filesystem gets mounted between110// the first getfsstat and the second so loop until consistant111112while (nentries != iter->nentries) {113if (iter->buf != NULL)114free(iter->buf);115116bufsize = nentries * sizeof(struct statfs);117iter->nentries = nentries;118119iter->buf = malloc(bufsize);120if (iter->buf == NULL) {121free(iter);122JNU_ThrowOutOfMemoryError(env, "native heap");123return 0;124}125126nentries = getfsstat(iter->buf, bufsize, MNT_WAIT);127if (nentries <= 0) {128free(iter->buf);129free(iter);130throwUnixException(env, errno);131return 0;132}133}134135return (jlong)iter;136}137138JNIEXPORT jint JNICALL139Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry(JNIEnv* env, jclass this,140jlong value, jobject entry)141{142struct fsstat_iter *iter = jlong_to_ptr(value);143jsize len;144jbyteArray bytes;145char* name;146char* dir;147char* fstype;148char* options;149dev_t dev;150151if (iter == NULL || iter->pos >= iter->nentries)152return -1;153154name = iter->buf[iter->pos].f_mntfromname;155dir = iter->buf[iter->pos].f_mntonname;156fstype = iter->buf[iter->pos].f_fstypename;157if (iter->buf[iter->pos].f_flags & ISREADONLY)158options="ro";159else160options="";161162iter->pos++;163164len = strlen(name);165bytes = (*env)->NewByteArray(env, len);166if (bytes == NULL)167return -1;168(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);169(*env)->SetObjectField(env, entry, entry_name, bytes);170171len = strlen(dir);172bytes = (*env)->NewByteArray(env, len);173if (bytes == NULL)174return -1;175(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);176(*env)->SetObjectField(env, entry, entry_dir, bytes);177178len = strlen(fstype);179bytes = (*env)->NewByteArray(env, len);180if (bytes == NULL)181return -1;182(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);183(*env)->SetObjectField(env, entry, entry_fstype, bytes);184185len = strlen(options);186bytes = (*env)->NewByteArray(env, len);187if (bytes == NULL)188return -1;189(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);190(*env)->SetObjectField(env, entry, entry_options, bytes);191192return 0;193}194195JNIEXPORT void JNICALL196Java_sun_nio_fs_BsdNativeDispatcher_endfsstat(JNIEnv* env, jclass this, jlong value)197{198struct fsstat_iter *iter = jlong_to_ptr(value);199200if (iter != NULL) {201free(iter->buf);202free(iter);203}204}205206JNIEXPORT jbyteArray JNICALL207Java_sun_nio_fs_BsdNativeDispatcher_getmntonname0(JNIEnv *env, jclass this,208jlong pathAddress)209{210struct statfs buf;211const char* path = (const char*)jlong_to_ptr(pathAddress);212213if (statfs(path, &buf) != 0) {214throwUnixException(env, errno);215}216217jsize len = strlen(buf.f_mntonname);218jbyteArray mntonname = (*env)->NewByteArray(env, len);219if (mntonname != NULL) {220(*env)->SetByteArrayRegion(env, mntonname, 0, len,221(jbyte*)buf.f_mntonname);222}223224return mntonname;225}226227228