Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.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 <stdio.h>31#include <string.h>32#include <dlfcn.h>33#include <errno.h>34#include <mntent.h>3536#include "sun_nio_fs_LinuxNativeDispatcher.h"3738typedef size_t fgetxattr_func(int fd, const char* name, void* value, size_t size);39typedef int fsetxattr_func(int fd, const char* name, void* value, size_t size, int flags);40typedef int fremovexattr_func(int fd, const char* name);41typedef int flistxattr_func(int fd, char* list, size_t size);4243fgetxattr_func* my_fgetxattr_func = NULL;44fsetxattr_func* my_fsetxattr_func = NULL;45fremovexattr_func* my_fremovexattr_func = NULL;46flistxattr_func* my_flistxattr_func = NULL;4748static jfieldID entry_name;49static jfieldID entry_dir;50static jfieldID entry_fstype;51static jfieldID entry_options;5253static void throwUnixException(JNIEnv* env, int errnum) {54jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",55"(I)V", errnum);56if (x != NULL) {57(*env)->Throw(env, x);58}59}6061JNIEXPORT void JNICALL62Java_sun_nio_fs_LinuxNativeDispatcher_init(JNIEnv *env, jclass clazz)63{64my_fgetxattr_func = (fgetxattr_func*)dlsym(RTLD_DEFAULT, "fgetxattr");65my_fsetxattr_func = (fsetxattr_func*)dlsym(RTLD_DEFAULT, "fsetxattr");66my_fremovexattr_func = (fremovexattr_func*)dlsym(RTLD_DEFAULT, "fremovexattr");67my_flistxattr_func = (flistxattr_func*)dlsym(RTLD_DEFAULT, "flistxattr");6869clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");70CHECK_NULL(clazz);71entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");72CHECK_NULL(entry_name);73entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");74CHECK_NULL(entry_dir);75entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");76CHECK_NULL(entry_fstype);77entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");78CHECK_NULL(entry_options);79}8081JNIEXPORT jint JNICALL82Java_sun_nio_fs_LinuxNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,83jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)84{85size_t res = -1;86const char* name = jlong_to_ptr(nameAddress);87void* value = jlong_to_ptr(valueAddress);8889if (my_fgetxattr_func == NULL) {90errno = ENOTSUP;91} else {92/* EINTR not documented */93res = (*my_fgetxattr_func)(fd, name, value, valueLen);94}95if (res == (size_t)-1)96throwUnixException(env, errno);97return (jint)res;98}99100JNIEXPORT void JNICALL101Java_sun_nio_fs_LinuxNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,102jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)103{104int res = -1;105const char* name = jlong_to_ptr(nameAddress);106void* value = jlong_to_ptr(valueAddress);107108if (my_fsetxattr_func == NULL) {109errno = ENOTSUP;110} else {111/* EINTR not documented */112res = (*my_fsetxattr_func)(fd, name, value, valueLen, 0);113}114if (res == -1)115throwUnixException(env, errno);116}117118JNIEXPORT void JNICALL119Java_sun_nio_fs_LinuxNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,120jint fd, jlong nameAddress)121{122int res = -1;123const char* name = jlong_to_ptr(nameAddress);124125if (my_fremovexattr_func == NULL) {126errno = ENOTSUP;127} else {128/* EINTR not documented */129res = (*my_fremovexattr_func)(fd, name);130}131if (res == -1)132throwUnixException(env, errno);133}134135JNIEXPORT jint JNICALL136Java_sun_nio_fs_LinuxNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,137jint fd, jlong listAddress, jint size)138{139size_t res = -1;140char* list = jlong_to_ptr(listAddress);141142if (my_flistxattr_func == NULL) {143errno = ENOTSUP;144} else {145/* EINTR not documented */146res = (*my_flistxattr_func)(fd, list, (size_t)size);147}148if (res == (size_t)-1)149throwUnixException(env, errno);150return (jint)res;151}152153JNIEXPORT jlong JNICALL154Java_sun_nio_fs_LinuxNativeDispatcher_setmntent0(JNIEnv* env, jclass this, jlong pathAddress,155jlong modeAddress)156{157FILE* fp = NULL;158const char* path = (const char*)jlong_to_ptr(pathAddress);159const char* mode = (const char*)jlong_to_ptr(modeAddress);160161do {162fp = setmntent(path, mode);163} while (fp == NULL && errno == EINTR);164if (fp == NULL) {165throwUnixException(env, errno);166}167return ptr_to_jlong(fp);168}169170JNIEXPORT jint JNICALL171Java_sun_nio_fs_LinuxNativeDispatcher_getmntent0(JNIEnv* env, jclass this,172jlong value, jobject entry, jlong buffer, jint bufLen)173{174struct mntent ent;175char * buf = (char*)jlong_to_ptr(buffer);176struct mntent* m;177FILE* fp = jlong_to_ptr(value);178jsize len;179jbyteArray bytes;180char* name;181char* dir;182char* fstype;183char* options;184185m = getmntent_r(fp, &ent, buf, (int)bufLen);186if (m == NULL)187return -1;188name = m->mnt_fsname;189dir = m->mnt_dir;190fstype = m->mnt_type;191options = m->mnt_opts;192193len = strlen(name);194bytes = (*env)->NewByteArray(env, len);195if (bytes == NULL)196return -1;197(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);198(*env)->SetObjectField(env, entry, entry_name, bytes);199200len = strlen(dir);201bytes = (*env)->NewByteArray(env, len);202if (bytes == NULL)203return -1;204(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);205(*env)->SetObjectField(env, entry, entry_dir, bytes);206207len = strlen(fstype);208bytes = (*env)->NewByteArray(env, len);209if (bytes == NULL)210return -1;211(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);212(*env)->SetObjectField(env, entry, entry_fstype, bytes);213214len = strlen(options);215bytes = (*env)->NewByteArray(env, len);216if (bytes == NULL)217return -1;218(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);219(*env)->SetObjectField(env, entry, entry_options, bytes);220221return 0;222}223224JNIEXPORT void JNICALL225Java_sun_nio_fs_LinuxNativeDispatcher_endmntent(JNIEnv* env, jclass this, jlong stream)226{227FILE* fp = jlong_to_ptr(stream);228/* FIXME - man page doesn't explain how errors are returned */229endmntent(fp);230}231232/**233* This function returns line length without NUL terminator or -1 on EOF.234* Since getline is missing on Solaris10 this function was moved from235* UnixNativeDispatcher to LinuxNativeDispatcher as part of backport form jdk11.236*/237JNIEXPORT jint JNICALL238Java_sun_nio_fs_LinuxNativeDispatcher_getlinelen(JNIEnv* env, jclass this, jlong stream)239{240FILE* fp = jlong_to_ptr(stream);241size_t lineSize = 0;242char * lineBuffer = NULL;243int saved_errno;244245ssize_t res = getline(&lineBuffer, &lineSize, fp);246saved_errno = errno;247248/* Should free lineBuffer no matter result, according to man page */249if (lineBuffer != NULL)250free(lineBuffer);251252if (feof(fp))253return -1;254255/* On successfull return res >= 0, otherwise res is -1 */256if (res == -1)257throwUnixException(env, saved_errno);258259if (res > INT_MAX)260throwUnixException(env, EOVERFLOW);261262return (jint)res;263}264265266267