Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/java/io/UnixFileSystem_md.c
32287 views
/*1* Copyright (c) 1998, 2017, 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 <assert.h>26#include <sys/types.h>27#include <sys/time.h>28#include <sys/stat.h>29#include <sys/statvfs.h>30#include <string.h>31#include <stdlib.h>32#include <dlfcn.h>33#include <limits.h>3435#include "jni.h"36#include "jni_util.h"37#include "jlong.h"38#include "jvm.h"39#include "io_util.h"40#include "io_util_md.h"41#include "java_io_FileSystem.h"42#include "java_io_UnixFileSystem.h"4344#if defined(_ALLBSD_SOURCE)45#define dirent64 dirent46#define readdir64_r readdir_r47#define stat64 stat48#define statvfs64 statvfs49#endif5051/* -- Field IDs -- */5253static struct {54jfieldID path;55} ids;565758JNIEXPORT void JNICALL59Java_java_io_UnixFileSystem_initIDs(JNIEnv *env, jclass cls)60{61jclass fileClass = (*env)->FindClass(env, "java/io/File");62if (!fileClass) return;63ids.path = (*env)->GetFieldID(env, fileClass,64"path", "Ljava/lang/String;");65}6667/* -- Path operations -- */6869extern int canonicalize(char *path, const char *out, int len);7071JNIEXPORT jstring JNICALL72Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this,73jstring pathname)74{75jstring rv = NULL;7677WITH_PLATFORM_STRING(env, pathname, path) {78char canonicalPath[JVM_MAXPATHLEN];79if (canonicalize((char *)path,80canonicalPath, JVM_MAXPATHLEN) < 0) {81JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");82} else {83#ifdef MACOSX84rv = newStringPlatform(env, canonicalPath);85#else86rv = JNU_NewStringPlatform(env, canonicalPath);87#endif88}89} END_PLATFORM_STRING(env, path);90return rv;91}929394/* -- Attribute accessors -- */959697static jboolean98statMode(const char *path, int *mode)99{100struct stat64 sb;101if (stat64(path, &sb) == 0) {102*mode = sb.st_mode;103return JNI_TRUE;104}105return JNI_FALSE;106}107108109JNIEXPORT jint JNICALL110Java_java_io_UnixFileSystem_getBooleanAttributes0(JNIEnv *env, jobject this,111jobject file)112{113jint rv = 0;114115WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {116int mode;117if (statMode(path, &mode)) {118int fmt = mode & S_IFMT;119rv = (jint) (java_io_FileSystem_BA_EXISTS120| ((fmt == S_IFREG) ? java_io_FileSystem_BA_REGULAR : 0)121| ((fmt == S_IFDIR) ? java_io_FileSystem_BA_DIRECTORY : 0));122}123} END_PLATFORM_STRING(env, path);124return rv;125}126127JNIEXPORT jboolean JNICALL128Java_java_io_UnixFileSystem_checkAccess(JNIEnv *env, jobject this,129jobject file, jint a)130{131jboolean rv = JNI_FALSE;132int mode = 0;133switch (a) {134case java_io_FileSystem_ACCESS_READ:135mode = R_OK;136break;137case java_io_FileSystem_ACCESS_WRITE:138mode = W_OK;139break;140case java_io_FileSystem_ACCESS_EXECUTE:141mode = X_OK;142break;143default: assert(0);144}145WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {146if (access(path, mode) == 0) {147rv = JNI_TRUE;148}149} END_PLATFORM_STRING(env, path);150return rv;151}152153154JNIEXPORT jboolean JNICALL155Java_java_io_UnixFileSystem_setPermission(JNIEnv *env, jobject this,156jobject file,157jint access,158jboolean enable,159jboolean owneronly)160{161jboolean rv = JNI_FALSE;162163WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {164int amode = 0;165int mode;166switch (access) {167case java_io_FileSystem_ACCESS_READ:168if (owneronly)169amode = S_IRUSR;170else171amode = S_IRUSR | S_IRGRP | S_IROTH;172break;173case java_io_FileSystem_ACCESS_WRITE:174if (owneronly)175amode = S_IWUSR;176else177amode = S_IWUSR | S_IWGRP | S_IWOTH;178break;179case java_io_FileSystem_ACCESS_EXECUTE:180if (owneronly)181amode = S_IXUSR;182else183amode = S_IXUSR | S_IXGRP | S_IXOTH;184break;185default:186assert(0);187}188if (statMode(path, &mode)) {189if (enable)190mode |= amode;191else192mode &= ~amode;193if (chmod(path, mode) >= 0) {194rv = JNI_TRUE;195}196}197} END_PLATFORM_STRING(env, path);198return rv;199}200201JNIEXPORT jlong JNICALL202Java_java_io_UnixFileSystem_getLastModifiedTime(JNIEnv *env, jobject this,203jobject file)204{205jlong rv = 0;206207WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {208struct stat64 sb;209if (stat64(path, &sb) == 0) {210#ifndef MACOSX211rv = (jlong)sb.st_mtime * 1000;212rv += (jlong)sb.st_mtime_nsec / 1000000;213#else214rv = (jlong)sb.st_mtimespec.tv_sec * 1000;215rv += (jlong)sb.st_mtimespec.tv_nsec / 1000000;216#endif217}218} END_PLATFORM_STRING(env, path);219return rv;220}221222223JNIEXPORT jlong JNICALL224Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,225jobject file)226{227jlong rv = 0;228229WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {230struct stat64 sb;231if (stat64(path, &sb) == 0) {232rv = sb.st_size;233}234} END_PLATFORM_STRING(env, path);235return rv;236}237238239/* -- File operations -- */240241242JNIEXPORT jboolean JNICALL243Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls,244jstring pathname)245{246jboolean rv = JNI_FALSE;247248WITH_PLATFORM_STRING(env, pathname, path) {249FD fd;250/* The root directory always exists */251if (strcmp (path, "/")) {252fd = handleOpen(path, O_RDWR | O_CREAT | O_EXCL, 0666);253if (fd < 0) {254if (errno != EEXIST)255JNU_ThrowIOExceptionWithLastError(env, path);256} else {257if (close(fd) == -1)258JNU_ThrowIOExceptionWithLastError(env, path);259rv = JNI_TRUE;260}261}262} END_PLATFORM_STRING(env, path);263return rv;264}265266267JNIEXPORT jboolean JNICALL268Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,269jobject file)270{271jboolean rv = JNI_FALSE;272273WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {274if (remove(path) == 0) {275rv = JNI_TRUE;276}277} END_PLATFORM_STRING(env, path);278return rv;279}280281282JNIEXPORT jobjectArray JNICALL283Java_java_io_UnixFileSystem_list(JNIEnv *env, jobject this,284jobject file)285{286DIR *dir = NULL;287struct dirent64 *ptr;288struct dirent64 *result;289int len, maxlen;290jobjectArray rv, old;291jclass str_class;292293str_class = JNU_ClassString(env);294CHECK_NULL_RETURN(str_class, NULL);295296WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {297dir = opendir(path);298} END_PLATFORM_STRING(env, path);299if (dir == NULL) return NULL;300301ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));302if (ptr == NULL) {303JNU_ThrowOutOfMemoryError(env, "heap allocation failed");304closedir(dir);305return NULL;306}307308/* Allocate an initial String array */309len = 0;310maxlen = 16;311rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);312if (rv == NULL) goto error;313314/* Scan the directory */315while ((readdir64_r(dir, ptr, &result) == 0) && (result != NULL)) {316jstring name;317if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))318continue;319if (len == maxlen) {320old = rv;321rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);322if (rv == NULL) goto error;323if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;324(*env)->DeleteLocalRef(env, old);325}326#ifdef MACOSX327name = newStringPlatform(env, ptr->d_name);328#else329name = JNU_NewStringPlatform(env, ptr->d_name);330#endif331if (name == NULL) goto error;332(*env)->SetObjectArrayElement(env, rv, len++, name);333(*env)->DeleteLocalRef(env, name);334}335closedir(dir);336free(ptr);337338/* Copy the final results into an appropriately-sized array */339old = rv;340rv = (*env)->NewObjectArray(env, len, str_class, NULL);341if (rv == NULL) {342return NULL;343}344if (JNU_CopyObjectArray(env, rv, old, len) < 0) {345return NULL;346}347return rv;348349error:350closedir(dir);351free(ptr);352return NULL;353}354355356JNIEXPORT jboolean JNICALL357Java_java_io_UnixFileSystem_createDirectory(JNIEnv *env, jobject this,358jobject file)359{360jboolean rv = JNI_FALSE;361362WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {363if (mkdir(path, 0777) == 0) {364rv = JNI_TRUE;365}366} END_PLATFORM_STRING(env, path);367return rv;368}369370371JNIEXPORT jboolean JNICALL372Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,373jobject from, jobject to)374{375jboolean rv = JNI_FALSE;376377WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {378WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {379if (rename(fromPath, toPath) == 0) {380rv = JNI_TRUE;381}382} END_PLATFORM_STRING(env, toPath);383} END_PLATFORM_STRING(env, fromPath);384return rv;385}386387JNIEXPORT jboolean JNICALL388Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,389jobject file, jlong time)390{391jboolean rv = JNI_FALSE;392393WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {394struct stat64 sb;395396if (stat64(path, &sb) == 0) {397struct timeval tv[2];398399/* Preserve access time */400#ifndef MACOSX401tv[0].tv_sec = sb.st_atime;402tv[0].tv_usec = sb.st_atime_nsec / 1000;403#else404tv[0].tv_sec = sb.st_atimespec.tv_sec;405tv[0].tv_usec = sb.st_atimespec.tv_nsec / 1000;406#endif407408/* Change last-modified time */409tv[1].tv_sec = time / 1000;410tv[1].tv_usec = (time % 1000) * 1000;411412if (utimes(path, tv) == 0)413rv = JNI_TRUE;414}415} END_PLATFORM_STRING(env, path);416417return rv;418}419420421JNIEXPORT jboolean JNICALL422Java_java_io_UnixFileSystem_setReadOnly(JNIEnv *env, jobject this,423jobject file)424{425jboolean rv = JNI_FALSE;426427WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {428int mode;429if (statMode(path, &mode)) {430if (chmod(path, mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)) >= 0) {431rv = JNI_TRUE;432}433}434} END_PLATFORM_STRING(env, path);435return rv;436}437438JNIEXPORT jlong JNICALL439Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,440jobject file, jint t)441{442jlong rv = 0L;443444WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {445struct statvfs64 fsstat;446memset(&fsstat, 0, sizeof(fsstat));447if (statvfs64(path, &fsstat) == 0) {448switch(t) {449case java_io_FileSystem_SPACE_TOTAL:450rv = jlong_mul(long_to_jlong(fsstat.f_frsize),451long_to_jlong(fsstat.f_blocks));452break;453case java_io_FileSystem_SPACE_FREE:454rv = jlong_mul(long_to_jlong(fsstat.f_frsize),455long_to_jlong(fsstat.f_bfree));456break;457case java_io_FileSystem_SPACE_USABLE:458rv = jlong_mul(long_to_jlong(fsstat.f_frsize),459long_to_jlong(fsstat.f_bavail));460break;461default:462assert(0);463}464}465} END_PLATFORM_STRING(env, path);466return rv;467}468469470