annotate src/solaris/native/java/io/UnixFileSystem_md.c @ 10983:935758609767

Added tag jdk8u60-b28 for changeset 48e79820c798
author asaha
date Tue, 13 Oct 2015 08:18:35 -0700
parents ef0c60b93a17
children
rev   line source
duke@0 1 /*
dxu@6785 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
ohair@2362 7 * published by the Free Software Foundation. Oracle designates this
duke@0 8 * particular file as subject to the "Classpath" exception as provided
ohair@2362 9 * by Oracle in the LICENSE file that accompanied this code.
duke@0 10 *
duke@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 15 * accompanied this code).
duke@0 16 *
duke@0 17 * You should have received a copy of the GNU General Public License version
duke@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 20 *
ohair@2362 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@2362 22 * or visit www.oracle.com if you need additional information or have any
ohair@2362 23 * questions.
duke@0 24 */
duke@0 25
duke@0 26 #include <assert.h>
duke@0 27 #include <sys/types.h>
duke@0 28 #include <sys/time.h>
duke@0 29 #include <sys/stat.h>
duke@0 30 #include <sys/statvfs.h>
duke@0 31 #include <string.h>
duke@0 32 #include <stdlib.h>
duke@0 33 #include <dlfcn.h>
duke@0 34 #include <limits.h>
duke@0 35
duke@0 36 #include "jni.h"
duke@0 37 #include "jni_util.h"
duke@0 38 #include "jlong.h"
duke@0 39 #include "jvm.h"
duke@0 40 #include "io_util.h"
sherman@5649 41 #include "io_util_md.h"
duke@0 42 #include "java_io_FileSystem.h"
duke@0 43 #include "java_io_UnixFileSystem.h"
duke@0 44
michaelm@5116 45 #if defined(_ALLBSD_SOURCE)
michaelm@5116 46 #define dirent64 dirent
michaelm@5116 47 #define readdir64_r readdir_r
michaelm@5116 48 #define stat64 stat
michaelm@5116 49 #define statvfs64 statvfs
michaelm@5116 50 #endif
duke@0 51
duke@0 52 /* -- Field IDs -- */
duke@0 53
duke@0 54 static struct {
duke@0 55 jfieldID path;
duke@0 56 } ids;
duke@0 57
duke@0 58
duke@0 59 JNIEXPORT void JNICALL
duke@0 60 Java_java_io_UnixFileSystem_initIDs(JNIEnv *env, jclass cls)
duke@0 61 {
duke@0 62 jclass fileClass = (*env)->FindClass(env, "java/io/File");
duke@0 63 if (!fileClass) return;
duke@0 64 ids.path = (*env)->GetFieldID(env, fileClass,
duke@0 65 "path", "Ljava/lang/String;");
duke@0 66 }
duke@0 67
duke@0 68 /* -- Path operations -- */
duke@0 69
duke@0 70 extern int canonicalize(char *path, const char *out, int len);
duke@0 71
duke@0 72 JNIEXPORT jstring JNICALL
duke@0 73 Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this,
duke@0 74 jstring pathname)
duke@0 75 {
duke@0 76 jstring rv = NULL;
duke@0 77
duke@0 78 WITH_PLATFORM_STRING(env, pathname, path) {
duke@0 79 char canonicalPath[JVM_MAXPATHLEN];
dxu@6785 80 if (canonicalize((char *)path,
duke@0 81 canonicalPath, JVM_MAXPATHLEN) < 0) {
duke@0 82 JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
duke@0 83 } else {
sherman@5649 84 #ifdef MACOSX
sherman@5649 85 rv = newStringPlatform(env, canonicalPath);
sherman@5649 86 #else
duke@0 87 rv = JNU_NewStringPlatform(env, canonicalPath);
sherman@5649 88 #endif
duke@0 89 }
duke@0 90 } END_PLATFORM_STRING(env, path);
duke@0 91 return rv;
duke@0 92 }
duke@0 93
duke@0 94
duke@0 95 /* -- Attribute accessors -- */
duke@0 96
duke@0 97
duke@0 98 static jboolean
duke@0 99 statMode(const char *path, int *mode)
duke@0 100 {
alanb@358 101 struct stat64 sb;
alanb@358 102 if (stat64(path, &sb) == 0) {
alanb@358 103 *mode = sb.st_mode;
alanb@358 104 return JNI_TRUE;
duke@0 105 }
duke@0 106 return JNI_FALSE;
duke@0 107 }
duke@0 108
duke@0 109
duke@0 110 JNIEXPORT jint JNICALL
duke@0 111 Java_java_io_UnixFileSystem_getBooleanAttributes0(JNIEnv *env, jobject this,
duke@0 112 jobject file)
duke@0 113 {
duke@0 114 jint rv = 0;
duke@0 115
duke@0 116 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 117 int mode;
duke@0 118 if (statMode(path, &mode)) {
duke@0 119 int fmt = mode & S_IFMT;
duke@0 120 rv = (jint) (java_io_FileSystem_BA_EXISTS
duke@0 121 | ((fmt == S_IFREG) ? java_io_FileSystem_BA_REGULAR : 0)
duke@0 122 | ((fmt == S_IFDIR) ? java_io_FileSystem_BA_DIRECTORY : 0));
duke@0 123 }
duke@0 124 } END_PLATFORM_STRING(env, path);
duke@0 125 return rv;
duke@0 126 }
duke@0 127
duke@0 128 JNIEXPORT jboolean JNICALL
duke@0 129 Java_java_io_UnixFileSystem_checkAccess(JNIEnv *env, jobject this,
duke@0 130 jobject file, jint a)
duke@0 131 {
duke@0 132 jboolean rv = JNI_FALSE;
alanb@2884 133 int mode = 0;
duke@0 134 switch (a) {
duke@0 135 case java_io_FileSystem_ACCESS_READ:
duke@0 136 mode = R_OK;
duke@0 137 break;
duke@0 138 case java_io_FileSystem_ACCESS_WRITE:
duke@0 139 mode = W_OK;
duke@0 140 break;
duke@0 141 case java_io_FileSystem_ACCESS_EXECUTE:
duke@0 142 mode = X_OK;
duke@0 143 break;
duke@0 144 default: assert(0);
duke@0 145 }
duke@0 146 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 147 if (access(path, mode) == 0) {
duke@0 148 rv = JNI_TRUE;
duke@0 149 }
duke@0 150 } END_PLATFORM_STRING(env, path);
duke@0 151 return rv;
duke@0 152 }
duke@0 153
duke@0 154
duke@0 155 JNIEXPORT jboolean JNICALL
duke@0 156 Java_java_io_UnixFileSystem_setPermission(JNIEnv *env, jobject this,
duke@0 157 jobject file,
duke@0 158 jint access,
duke@0 159 jboolean enable,
duke@0 160 jboolean owneronly)
duke@0 161 {
duke@0 162 jboolean rv = JNI_FALSE;
duke@0 163
duke@0 164 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@2884 165 int amode = 0;
alanb@2884 166 int mode;
duke@0 167 switch (access) {
duke@0 168 case java_io_FileSystem_ACCESS_READ:
duke@0 169 if (owneronly)
duke@0 170 amode = S_IRUSR;
duke@0 171 else
duke@0 172 amode = S_IRUSR | S_IRGRP | S_IROTH;
duke@0 173 break;
duke@0 174 case java_io_FileSystem_ACCESS_WRITE:
duke@0 175 if (owneronly)
duke@0 176 amode = S_IWUSR;
duke@0 177 else
duke@0 178 amode = S_IWUSR | S_IWGRP | S_IWOTH;
duke@0 179 break;
duke@0 180 case java_io_FileSystem_ACCESS_EXECUTE:
duke@0 181 if (owneronly)
duke@0 182 amode = S_IXUSR;
duke@0 183 else
duke@0 184 amode = S_IXUSR | S_IXGRP | S_IXOTH;
duke@0 185 break;
duke@0 186 default:
duke@0 187 assert(0);
duke@0 188 }
duke@0 189 if (statMode(path, &mode)) {
duke@0 190 if (enable)
duke@0 191 mode |= amode;
duke@0 192 else
duke@0 193 mode &= ~amode;
duke@0 194 if (chmod(path, mode) >= 0) {
duke@0 195 rv = JNI_TRUE;
duke@0 196 }
duke@0 197 }
duke@0 198 } END_PLATFORM_STRING(env, path);
duke@0 199 return rv;
duke@0 200 }
duke@0 201
duke@0 202 JNIEXPORT jlong JNICALL
duke@0 203 Java_java_io_UnixFileSystem_getLastModifiedTime(JNIEnv *env, jobject this,
duke@0 204 jobject file)
duke@0 205 {
duke@0 206 jlong rv = 0;
duke@0 207
duke@0 208 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@358 209 struct stat64 sb;
alanb@358 210 if (stat64(path, &sb) == 0) {
alanb@358 211 rv = 1000 * (jlong)sb.st_mtime;
duke@0 212 }
duke@0 213 } END_PLATFORM_STRING(env, path);
duke@0 214 return rv;
duke@0 215 }
duke@0 216
duke@0 217
duke@0 218 JNIEXPORT jlong JNICALL
duke@0 219 Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,
duke@0 220 jobject file)
duke@0 221 {
duke@0 222 jlong rv = 0;
duke@0 223
duke@0 224 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@358 225 struct stat64 sb;
alanb@358 226 if (stat64(path, &sb) == 0) {
alanb@358 227 rv = sb.st_size;
duke@0 228 }
duke@0 229 } END_PLATFORM_STRING(env, path);
duke@0 230 return rv;
duke@0 231 }
duke@0 232
duke@0 233
duke@0 234 /* -- File operations -- */
duke@0 235
duke@0 236
duke@0 237 JNIEXPORT jboolean JNICALL
duke@0 238 Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls,
duke@0 239 jstring pathname)
duke@0 240 {
duke@0 241 jboolean rv = JNI_FALSE;
duke@0 242
duke@0 243 WITH_PLATFORM_STRING(env, pathname, path) {
dxu@6785 244 FD fd;
dxu@6785 245 /* The root directory always exists */
dxu@6785 246 if (strcmp (path, "/")) {
dxu@6785 247 fd = handleOpen(path, O_RDWR | O_CREAT | O_EXCL, 0666);
dxu@6785 248 if (fd < 0) {
dxu@6785 249 if (errno != EEXIST)
dxu@6785 250 JNU_ThrowIOExceptionWithLastError(env, path);
dxu@6785 251 } else {
dxu@6785 252 if (close(fd) == -1)
dxu@6785 253 JNU_ThrowIOExceptionWithLastError(env, path);
dxu@6785 254 rv = JNI_TRUE;
duke@0 255 }
duke@0 256 }
duke@0 257 } END_PLATFORM_STRING(env, path);
duke@0 258 return rv;
duke@0 259 }
duke@0 260
duke@0 261
duke@0 262 JNIEXPORT jboolean JNICALL
duke@0 263 Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,
duke@0 264 jobject file)
duke@0 265 {
duke@0 266 jboolean rv = JNI_FALSE;
duke@0 267
duke@0 268 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 269 if (remove(path) == 0) {
duke@0 270 rv = JNI_TRUE;
duke@0 271 }
duke@0 272 } END_PLATFORM_STRING(env, path);
duke@0 273 return rv;
duke@0 274 }
duke@0 275
duke@0 276
duke@0 277 JNIEXPORT jobjectArray JNICALL
duke@0 278 Java_java_io_UnixFileSystem_list(JNIEnv *env, jobject this,
duke@0 279 jobject file)
duke@0 280 {
duke@0 281 DIR *dir = NULL;
duke@0 282 struct dirent64 *ptr;
duke@0 283 struct dirent64 *result;
duke@0 284 int len, maxlen;
duke@0 285 jobjectArray rv, old;
alanb@10473 286 jclass str_class;
alanb@10473 287
alanb@10473 288 str_class = JNU_ClassString(env);
alanb@10473 289 CHECK_NULL_RETURN(str_class, NULL);
duke@0 290
duke@0 291 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 292 dir = opendir(path);
duke@0 293 } END_PLATFORM_STRING(env, path);
duke@0 294 if (dir == NULL) return NULL;
duke@0 295
duke@0 296 ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));
duke@0 297 if (ptr == NULL) {
duke@0 298 JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
duke@0 299 closedir(dir);
duke@0 300 return NULL;
duke@0 301 }
duke@0 302
duke@0 303 /* Allocate an initial String array */
duke@0 304 len = 0;
duke@0 305 maxlen = 16;
alanb@10473 306 rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);
duke@0 307 if (rv == NULL) goto error;
duke@0 308
duke@0 309 /* Scan the directory */
duke@0 310 while ((readdir64_r(dir, ptr, &result) == 0) && (result != NULL)) {
duke@0 311 jstring name;
duke@0 312 if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
duke@0 313 continue;
duke@0 314 if (len == maxlen) {
duke@0 315 old = rv;
alanb@10473 316 rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);
duke@0 317 if (rv == NULL) goto error;
duke@0 318 if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
duke@0 319 (*env)->DeleteLocalRef(env, old);
duke@0 320 }
sherman@5649 321 #ifdef MACOSX
sherman@5649 322 name = newStringPlatform(env, ptr->d_name);
sherman@5649 323 #else
duke@0 324 name = JNU_NewStringPlatform(env, ptr->d_name);
sherman@5649 325 #endif
duke@0 326 if (name == NULL) goto error;
duke@0 327 (*env)->SetObjectArrayElement(env, rv, len++, name);
duke@0 328 (*env)->DeleteLocalRef(env, name);
duke@0 329 }
duke@0 330 closedir(dir);
duke@0 331 free(ptr);
duke@0 332
duke@0 333 /* Copy the final results into an appropriately-sized array */
duke@0 334 old = rv;
alanb@10473 335 rv = (*env)->NewObjectArray(env, len, str_class, NULL);
duke@0 336 if (rv == NULL) {
duke@0 337 return NULL;
duke@0 338 }
duke@0 339 if (JNU_CopyObjectArray(env, rv, old, len) < 0) {
duke@0 340 return NULL;
duke@0 341 }
duke@0 342 return rv;
duke@0 343
duke@0 344 error:
duke@0 345 closedir(dir);
duke@0 346 free(ptr);
duke@0 347 return NULL;
duke@0 348 }
duke@0 349
duke@0 350
duke@0 351 JNIEXPORT jboolean JNICALL
duke@0 352 Java_java_io_UnixFileSystem_createDirectory(JNIEnv *env, jobject this,
duke@0 353 jobject file)
duke@0 354 {
duke@0 355 jboolean rv = JNI_FALSE;
duke@0 356
duke@0 357 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 358 if (mkdir(path, 0777) == 0) {
duke@0 359 rv = JNI_TRUE;
duke@0 360 }
duke@0 361 } END_PLATFORM_STRING(env, path);
duke@0 362 return rv;
duke@0 363 }
duke@0 364
duke@0 365
duke@0 366 JNIEXPORT jboolean JNICALL
duke@0 367 Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
duke@0 368 jobject from, jobject to)
duke@0 369 {
duke@0 370 jboolean rv = JNI_FALSE;
duke@0 371
duke@0 372 WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {
duke@0 373 WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {
duke@0 374 if (rename(fromPath, toPath) == 0) {
duke@0 375 rv = JNI_TRUE;
duke@0 376 }
duke@0 377 } END_PLATFORM_STRING(env, toPath);
duke@0 378 } END_PLATFORM_STRING(env, fromPath);
duke@0 379 return rv;
duke@0 380 }
duke@0 381
duke@0 382 JNIEXPORT jboolean JNICALL
duke@0 383 Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
duke@0 384 jobject file, jlong time)
duke@0 385 {
duke@0 386 jboolean rv = JNI_FALSE;
duke@0 387
duke@0 388 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@358 389 struct stat64 sb;
duke@0 390
alanb@358 391 if (stat64(path, &sb) == 0) {
alanb@358 392 struct timeval tv[2];
alanb@358 393
alanb@358 394 /* Preserve access time */
alanb@358 395 tv[0].tv_sec = sb.st_atime;
alanb@358 396 tv[0].tv_usec = 0;
alanb@358 397
alanb@358 398 /* Change last-modified time */
alanb@358 399 tv[1].tv_sec = time / 1000;
alanb@358 400 tv[1].tv_usec = (time % 1000) * 1000;
alanb@358 401
alanb@358 402 if (utimes(path, tv) == 0)
alanb@358 403 rv = JNI_TRUE;
duke@0 404 }
duke@0 405 } END_PLATFORM_STRING(env, path);
duke@0 406
duke@0 407 return rv;
duke@0 408 }
duke@0 409
duke@0 410
duke@0 411 JNIEXPORT jboolean JNICALL
duke@0 412 Java_java_io_UnixFileSystem_setReadOnly(JNIEnv *env, jobject this,
duke@0 413 jobject file)
duke@0 414 {
duke@0 415 jboolean rv = JNI_FALSE;
duke@0 416
duke@0 417 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 418 int mode;
duke@0 419 if (statMode(path, &mode)) {
duke@0 420 if (chmod(path, mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)) >= 0) {
duke@0 421 rv = JNI_TRUE;
duke@0 422 }
duke@0 423 }
duke@0 424 } END_PLATFORM_STRING(env, path);
duke@0 425 return rv;
duke@0 426 }
duke@0 427
duke@0 428 JNIEXPORT jlong JNICALL
duke@0 429 Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,
duke@0 430 jobject file, jint t)
duke@0 431 {
duke@0 432 jlong rv = 0L;
duke@0 433
duke@0 434 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@2193 435 struct statvfs64 fsstat;
alanb@2193 436 memset(&fsstat, 0, sizeof(fsstat));
alanb@2193 437 if (statvfs64(path, &fsstat) == 0) {
duke@0 438 switch(t) {
duke@0 439 case java_io_FileSystem_SPACE_TOTAL:
duke@0 440 rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
duke@0 441 long_to_jlong(fsstat.f_blocks));
duke@0 442 break;
duke@0 443 case java_io_FileSystem_SPACE_FREE:
duke@0 444 rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
duke@0 445 long_to_jlong(fsstat.f_bfree));
duke@0 446 break;
duke@0 447 case java_io_FileSystem_SPACE_USABLE:
duke@0 448 rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
duke@0 449 long_to_jlong(fsstat.f_bavail));
duke@0 450 break;
duke@0 451 default:
duke@0 452 assert(0);
duke@0 453 }
duke@0 454 }
duke@0 455 } END_PLATFORM_STRING(env, path);
duke@0 456 return rv;
duke@0 457 }