Path: blob/jdk8u272-b10-aarch32-20201026/jdk/src/solaris/native/java/io/UnixFileSystem_md.c
48795 views
/*1* Copyright (c) 1998, 2013, 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) {210rv = 1000 * (jlong)sb.st_mtime;211}212} END_PLATFORM_STRING(env, path);213return rv;214}215216217JNIEXPORT jlong JNICALL218Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,219jobject file)220{221jlong rv = 0;222223WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {224struct stat64 sb;225if (stat64(path, &sb) == 0) {226rv = sb.st_size;227}228} END_PLATFORM_STRING(env, path);229return rv;230}231232233/* -- File operations -- */234235236JNIEXPORT jboolean JNICALL237Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls,238jstring pathname)239{240jboolean rv = JNI_FALSE;241242WITH_PLATFORM_STRING(env, pathname, path) {243FD fd;244/* The root directory always exists */245if (strcmp (path, "/")) {246fd = handleOpen(path, O_RDWR | O_CREAT | O_EXCL, 0666);247if (fd < 0) {248if (errno != EEXIST)249JNU_ThrowIOExceptionWithLastError(env, path);250} else {251if (close(fd) == -1)252JNU_ThrowIOExceptionWithLastError(env, path);253rv = JNI_TRUE;254}255}256} END_PLATFORM_STRING(env, path);257return rv;258}259260261JNIEXPORT jboolean JNICALL262Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,263jobject file)264{265jboolean rv = JNI_FALSE;266267WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {268if (remove(path) == 0) {269rv = JNI_TRUE;270}271} END_PLATFORM_STRING(env, path);272return rv;273}274275276JNIEXPORT jobjectArray JNICALL277Java_java_io_UnixFileSystem_list(JNIEnv *env, jobject this,278jobject file)279{280DIR *dir = NULL;281struct dirent64 *ptr;282struct dirent64 *result;283int len, maxlen;284jobjectArray rv, old;285jclass str_class;286287str_class = JNU_ClassString(env);288CHECK_NULL_RETURN(str_class, NULL);289290WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {291dir = opendir(path);292} END_PLATFORM_STRING(env, path);293if (dir == NULL) return NULL;294295ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));296if (ptr == NULL) {297JNU_ThrowOutOfMemoryError(env, "heap allocation failed");298closedir(dir);299return NULL;300}301302/* Allocate an initial String array */303len = 0;304maxlen = 16;305rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);306if (rv == NULL) goto error;307308/* Scan the directory */309while ((readdir64_r(dir, ptr, &result) == 0) && (result != NULL)) {310jstring name;311if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))312continue;313if (len == maxlen) {314old = rv;315rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);316if (rv == NULL) goto error;317if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;318(*env)->DeleteLocalRef(env, old);319}320#ifdef MACOSX321name = newStringPlatform(env, ptr->d_name);322#else323name = JNU_NewStringPlatform(env, ptr->d_name);324#endif325if (name == NULL) goto error;326(*env)->SetObjectArrayElement(env, rv, len++, name);327(*env)->DeleteLocalRef(env, name);328}329closedir(dir);330free(ptr);331332/* Copy the final results into an appropriately-sized array */333old = rv;334rv = (*env)->NewObjectArray(env, len, str_class, NULL);335if (rv == NULL) {336return NULL;337}338if (JNU_CopyObjectArray(env, rv, old, len) < 0) {339return NULL;340}341return rv;342343error:344closedir(dir);345free(ptr);346return NULL;347}348349350JNIEXPORT jboolean JNICALL351Java_java_io_UnixFileSystem_createDirectory(JNIEnv *env, jobject this,352jobject file)353{354jboolean rv = JNI_FALSE;355356WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {357if (mkdir(path, 0777) == 0) {358rv = JNI_TRUE;359}360} END_PLATFORM_STRING(env, path);361return rv;362}363364365JNIEXPORT jboolean JNICALL366Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,367jobject from, jobject to)368{369jboolean rv = JNI_FALSE;370371WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {372WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {373if (rename(fromPath, toPath) == 0) {374rv = JNI_TRUE;375}376} END_PLATFORM_STRING(env, toPath);377} END_PLATFORM_STRING(env, fromPath);378return rv;379}380381JNIEXPORT jboolean JNICALL382Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,383jobject file, jlong time)384{385jboolean rv = JNI_FALSE;386387WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {388struct stat64 sb;389390if (stat64(path, &sb) == 0) {391struct timeval tv[2];392393/* Preserve access time */394tv[0].tv_sec = sb.st_atime;395tv[0].tv_usec = 0;396397/* Change last-modified time */398tv[1].tv_sec = time / 1000;399tv[1].tv_usec = (time % 1000) * 1000;400401if (utimes(path, tv) == 0)402rv = JNI_TRUE;403}404} END_PLATFORM_STRING(env, path);405406return rv;407}408409410JNIEXPORT jboolean JNICALL411Java_java_io_UnixFileSystem_setReadOnly(JNIEnv *env, jobject this,412jobject file)413{414jboolean rv = JNI_FALSE;415416WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {417int mode;418if (statMode(path, &mode)) {419if (chmod(path, mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)) >= 0) {420rv = JNI_TRUE;421}422}423} END_PLATFORM_STRING(env, path);424return rv;425}426427JNIEXPORT jlong JNICALL428Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,429jobject file, jint t)430{431jlong rv = 0L;432433WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {434struct statvfs64 fsstat;435memset(&fsstat, 0, sizeof(fsstat));436if (statvfs64(path, &fsstat) == 0) {437switch(t) {438case java_io_FileSystem_SPACE_TOTAL:439rv = jlong_mul(long_to_jlong(fsstat.f_frsize),440long_to_jlong(fsstat.f_blocks));441break;442case java_io_FileSystem_SPACE_FREE:443rv = jlong_mul(long_to_jlong(fsstat.f_frsize),444long_to_jlong(fsstat.f_bfree));445break;446case java_io_FileSystem_SPACE_USABLE:447rv = jlong_mul(long_to_jlong(fsstat.f_frsize),448long_to_jlong(fsstat.f_bavail));449break;450default:451assert(0);452}453}454} END_PLATFORM_STRING(env, path);455return rv;456}457458459