annotate src/solaris/native/java/io/UnixFileSystem_md.c @ 5116:d45bc4307996

7113349: Initial changeset for Macosx port to jdk Reviewed-by: jjh, alanb, dholmes, anthony, ohrstrom, ksrini, jrose, weijun, smarks Contributed-by: Alan Bateman <alan.bateman@oracle.com>, Alexander Potochkin <alexander.potochkin@oracle.com>, Alexander Zuev <alexander.zuev@oracle.com>, Andrew Brygin <andrew.brygin@oracle.com>, Artem Ananiev <artem.ananiev@oracle.com>, Alex Strange <astrange@apple.com>, Bino George <bino@apple.com>, Christine Lu <christine.lu@oracle.com>, David Katleman <david.katleman@oracle.com>, David Durrence <david_durrence@apple.com>, Dmitry Cherepanov <dmitry.cherepanov@oracle.com>, Greg Lewis <glewis@eyesbeyond.com>, Kevin Miller <kevin_m_miller@apple.com>, Kurt Miller <kurt@intricatesoftware.com>, Landon Fuller <landonf@plausiblelabs.com>, Leonid Romanov <leonid.romanov@oracle.com>, Loefty Walkowiak <loefty@apple.com>, Mark Reinhold <mark.reinhold@oracle.com>, Naoto Sato <naoto.sato@oracle.com>, Philip Race <philip.race@oracle.com>, Roger Hoover <rhoover@apple.com>, Scott Kovatch <scott.kovatch@oracle.com>, Sergey ByloKhov <sergey.bylokhov@oracle.com>, Mike Swingler <swingler@apple.com>, Tomas Hurka <tomas.hurka@oracle.com>
author michaelm
date Tue, 06 Mar 2012 20:34:38 +0000
parents a06412e13bf7
children 84cd98a5641c
rev   line source
duke@0 1 /*
ohair@3261 2 * Copyright (c) 1998, 2010, 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"
duke@0 41 #include "java_io_FileSystem.h"
duke@0 42 #include "java_io_UnixFileSystem.h"
duke@0 43
michaelm@5116 44 #if defined(_ALLBSD_SOURCE)
michaelm@5116 45 #define dirent64 dirent
michaelm@5116 46 #define readdir64_r readdir_r
michaelm@5116 47 #define stat64 stat
michaelm@5116 48 #define statvfs64 statvfs
michaelm@5116 49 #endif
duke@0 50
duke@0 51 /* -- Field IDs -- */
duke@0 52
duke@0 53 static struct {
duke@0 54 jfieldID path;
duke@0 55 } ids;
duke@0 56
duke@0 57
duke@0 58 JNIEXPORT void JNICALL
duke@0 59 Java_java_io_UnixFileSystem_initIDs(JNIEnv *env, jclass cls)
duke@0 60 {
duke@0 61 jclass fileClass = (*env)->FindClass(env, "java/io/File");
duke@0 62 if (!fileClass) return;
duke@0 63 ids.path = (*env)->GetFieldID(env, fileClass,
duke@0 64 "path", "Ljava/lang/String;");
duke@0 65 }
duke@0 66
duke@0 67 /* -- Path operations -- */
duke@0 68
duke@0 69 extern int canonicalize(char *path, const char *out, int len);
duke@0 70
duke@0 71 JNIEXPORT jstring JNICALL
duke@0 72 Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this,
duke@0 73 jstring pathname)
duke@0 74 {
duke@0 75 jstring rv = NULL;
duke@0 76
duke@0 77 WITH_PLATFORM_STRING(env, pathname, path) {
duke@0 78 char canonicalPath[JVM_MAXPATHLEN];
duke@0 79 if (canonicalize(JVM_NativePath((char *)path),
duke@0 80 canonicalPath, JVM_MAXPATHLEN) < 0) {
duke@0 81 JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
duke@0 82 } else {
duke@0 83 rv = JNU_NewStringPlatform(env, canonicalPath);
duke@0 84 }
duke@0 85 } END_PLATFORM_STRING(env, path);
duke@0 86 return rv;
duke@0 87 }
duke@0 88
duke@0 89
duke@0 90 /* -- Attribute accessors -- */
duke@0 91
duke@0 92
duke@0 93 static jboolean
duke@0 94 statMode(const char *path, int *mode)
duke@0 95 {
alanb@358 96 struct stat64 sb;
alanb@358 97 if (stat64(path, &sb) == 0) {
alanb@358 98 *mode = sb.st_mode;
alanb@358 99 return JNI_TRUE;
duke@0 100 }
duke@0 101 return JNI_FALSE;
duke@0 102 }
duke@0 103
duke@0 104
duke@0 105 JNIEXPORT jint JNICALL
duke@0 106 Java_java_io_UnixFileSystem_getBooleanAttributes0(JNIEnv *env, jobject this,
duke@0 107 jobject file)
duke@0 108 {
duke@0 109 jint rv = 0;
duke@0 110
duke@0 111 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 112 int mode;
duke@0 113 if (statMode(path, &mode)) {
duke@0 114 int fmt = mode & S_IFMT;
duke@0 115 rv = (jint) (java_io_FileSystem_BA_EXISTS
duke@0 116 | ((fmt == S_IFREG) ? java_io_FileSystem_BA_REGULAR : 0)
duke@0 117 | ((fmt == S_IFDIR) ? java_io_FileSystem_BA_DIRECTORY : 0));
duke@0 118 }
duke@0 119 } END_PLATFORM_STRING(env, path);
duke@0 120 return rv;
duke@0 121 }
duke@0 122
duke@0 123 JNIEXPORT jboolean JNICALL
duke@0 124 Java_java_io_UnixFileSystem_checkAccess(JNIEnv *env, jobject this,
duke@0 125 jobject file, jint a)
duke@0 126 {
duke@0 127 jboolean rv = JNI_FALSE;
alanb@2884 128 int mode = 0;
duke@0 129 switch (a) {
duke@0 130 case java_io_FileSystem_ACCESS_READ:
duke@0 131 mode = R_OK;
duke@0 132 break;
duke@0 133 case java_io_FileSystem_ACCESS_WRITE:
duke@0 134 mode = W_OK;
duke@0 135 break;
duke@0 136 case java_io_FileSystem_ACCESS_EXECUTE:
duke@0 137 mode = X_OK;
duke@0 138 break;
duke@0 139 default: assert(0);
duke@0 140 }
duke@0 141 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 142 if (access(path, mode) == 0) {
duke@0 143 rv = JNI_TRUE;
duke@0 144 }
duke@0 145 } END_PLATFORM_STRING(env, path);
duke@0 146 return rv;
duke@0 147 }
duke@0 148
duke@0 149
duke@0 150 JNIEXPORT jboolean JNICALL
duke@0 151 Java_java_io_UnixFileSystem_setPermission(JNIEnv *env, jobject this,
duke@0 152 jobject file,
duke@0 153 jint access,
duke@0 154 jboolean enable,
duke@0 155 jboolean owneronly)
duke@0 156 {
duke@0 157 jboolean rv = JNI_FALSE;
duke@0 158
duke@0 159 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@2884 160 int amode = 0;
alanb@2884 161 int mode;
duke@0 162 switch (access) {
duke@0 163 case java_io_FileSystem_ACCESS_READ:
duke@0 164 if (owneronly)
duke@0 165 amode = S_IRUSR;
duke@0 166 else
duke@0 167 amode = S_IRUSR | S_IRGRP | S_IROTH;
duke@0 168 break;
duke@0 169 case java_io_FileSystem_ACCESS_WRITE:
duke@0 170 if (owneronly)
duke@0 171 amode = S_IWUSR;
duke@0 172 else
duke@0 173 amode = S_IWUSR | S_IWGRP | S_IWOTH;
duke@0 174 break;
duke@0 175 case java_io_FileSystem_ACCESS_EXECUTE:
duke@0 176 if (owneronly)
duke@0 177 amode = S_IXUSR;
duke@0 178 else
duke@0 179 amode = S_IXUSR | S_IXGRP | S_IXOTH;
duke@0 180 break;
duke@0 181 default:
duke@0 182 assert(0);
duke@0 183 }
duke@0 184 if (statMode(path, &mode)) {
duke@0 185 if (enable)
duke@0 186 mode |= amode;
duke@0 187 else
duke@0 188 mode &= ~amode;
duke@0 189 if (chmod(path, mode) >= 0) {
duke@0 190 rv = JNI_TRUE;
duke@0 191 }
duke@0 192 }
duke@0 193 } END_PLATFORM_STRING(env, path);
duke@0 194 return rv;
duke@0 195 }
duke@0 196
duke@0 197 JNIEXPORT jlong JNICALL
duke@0 198 Java_java_io_UnixFileSystem_getLastModifiedTime(JNIEnv *env, jobject this,
duke@0 199 jobject file)
duke@0 200 {
duke@0 201 jlong rv = 0;
duke@0 202
duke@0 203 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@358 204 struct stat64 sb;
alanb@358 205 if (stat64(path, &sb) == 0) {
alanb@358 206 rv = 1000 * (jlong)sb.st_mtime;
duke@0 207 }
duke@0 208 } END_PLATFORM_STRING(env, path);
duke@0 209 return rv;
duke@0 210 }
duke@0 211
duke@0 212
duke@0 213 JNIEXPORT jlong JNICALL
duke@0 214 Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,
duke@0 215 jobject file)
duke@0 216 {
duke@0 217 jlong rv = 0;
duke@0 218
duke@0 219 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@358 220 struct stat64 sb;
alanb@358 221 if (stat64(path, &sb) == 0) {
alanb@358 222 rv = sb.st_size;
duke@0 223 }
duke@0 224 } END_PLATFORM_STRING(env, path);
duke@0 225 return rv;
duke@0 226 }
duke@0 227
duke@0 228
duke@0 229 /* -- File operations -- */
duke@0 230
duke@0 231
duke@0 232 JNIEXPORT jboolean JNICALL
duke@0 233 Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls,
duke@0 234 jstring pathname)
duke@0 235 {
duke@0 236 jboolean rv = JNI_FALSE;
duke@0 237
duke@0 238 WITH_PLATFORM_STRING(env, pathname, path) {
duke@0 239 int fd;
duke@0 240 if (!strcmp (path, "/")) {
duke@0 241 fd = JVM_EEXIST; /* The root directory always exists */
duke@0 242 } else {
duke@0 243 fd = JVM_Open(path, JVM_O_RDWR | JVM_O_CREAT | JVM_O_EXCL, 0666);
duke@0 244 }
duke@0 245 if (fd < 0) {
duke@0 246 if (fd != JVM_EEXIST) {
duke@0 247 JNU_ThrowIOExceptionWithLastError(env, path);
duke@0 248 }
duke@0 249 } else {
duke@0 250 JVM_Close(fd);
duke@0 251 rv = JNI_TRUE;
duke@0 252 }
duke@0 253 } END_PLATFORM_STRING(env, path);
duke@0 254 return rv;
duke@0 255 }
duke@0 256
duke@0 257
duke@0 258 JNIEXPORT jboolean JNICALL
duke@0 259 Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,
duke@0 260 jobject file)
duke@0 261 {
duke@0 262 jboolean rv = JNI_FALSE;
duke@0 263
duke@0 264 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 265 if (remove(path) == 0) {
duke@0 266 rv = JNI_TRUE;
duke@0 267 }
duke@0 268 } END_PLATFORM_STRING(env, path);
duke@0 269 return rv;
duke@0 270 }
duke@0 271
duke@0 272
duke@0 273 JNIEXPORT jobjectArray JNICALL
duke@0 274 Java_java_io_UnixFileSystem_list(JNIEnv *env, jobject this,
duke@0 275 jobject file)
duke@0 276 {
duke@0 277 DIR *dir = NULL;
duke@0 278 struct dirent64 *ptr;
duke@0 279 struct dirent64 *result;
duke@0 280 int len, maxlen;
duke@0 281 jobjectArray rv, old;
duke@0 282
duke@0 283 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 284 dir = opendir(path);
duke@0 285 } END_PLATFORM_STRING(env, path);
duke@0 286 if (dir == NULL) return NULL;
duke@0 287
duke@0 288 ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));
duke@0 289 if (ptr == NULL) {
duke@0 290 JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
duke@0 291 closedir(dir);
duke@0 292 return NULL;
duke@0 293 }
duke@0 294
duke@0 295 /* Allocate an initial String array */
duke@0 296 len = 0;
duke@0 297 maxlen = 16;
duke@0 298 rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL);
duke@0 299 if (rv == NULL) goto error;
duke@0 300
duke@0 301 /* Scan the directory */
duke@0 302 while ((readdir64_r(dir, ptr, &result) == 0) && (result != NULL)) {
duke@0 303 jstring name;
duke@0 304 if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
duke@0 305 continue;
duke@0 306 if (len == maxlen) {
duke@0 307 old = rv;
duke@0 308 rv = (*env)->NewObjectArray(env, maxlen <<= 1,
duke@0 309 JNU_ClassString(env), NULL);
duke@0 310 if (rv == NULL) goto error;
duke@0 311 if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
duke@0 312 (*env)->DeleteLocalRef(env, old);
duke@0 313 }
duke@0 314 name = JNU_NewStringPlatform(env, ptr->d_name);
duke@0 315 if (name == NULL) goto error;
duke@0 316 (*env)->SetObjectArrayElement(env, rv, len++, name);
duke@0 317 (*env)->DeleteLocalRef(env, name);
duke@0 318 }
duke@0 319 closedir(dir);
duke@0 320 free(ptr);
duke@0 321
duke@0 322 /* Copy the final results into an appropriately-sized array */
duke@0 323 old = rv;
duke@0 324 rv = (*env)->NewObjectArray(env, len, JNU_ClassString(env), NULL);
duke@0 325 if (rv == NULL) {
duke@0 326 return NULL;
duke@0 327 }
duke@0 328 if (JNU_CopyObjectArray(env, rv, old, len) < 0) {
duke@0 329 return NULL;
duke@0 330 }
duke@0 331 return rv;
duke@0 332
duke@0 333 error:
duke@0 334 closedir(dir);
duke@0 335 free(ptr);
duke@0 336 return NULL;
duke@0 337 }
duke@0 338
duke@0 339
duke@0 340 JNIEXPORT jboolean JNICALL
duke@0 341 Java_java_io_UnixFileSystem_createDirectory(JNIEnv *env, jobject this,
duke@0 342 jobject file)
duke@0 343 {
duke@0 344 jboolean rv = JNI_FALSE;
duke@0 345
duke@0 346 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 347 if (mkdir(path, 0777) == 0) {
duke@0 348 rv = JNI_TRUE;
duke@0 349 }
duke@0 350 } END_PLATFORM_STRING(env, path);
duke@0 351 return rv;
duke@0 352 }
duke@0 353
duke@0 354
duke@0 355 JNIEXPORT jboolean JNICALL
duke@0 356 Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
duke@0 357 jobject from, jobject to)
duke@0 358 {
duke@0 359 jboolean rv = JNI_FALSE;
duke@0 360
duke@0 361 WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {
duke@0 362 WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {
duke@0 363 if (rename(fromPath, toPath) == 0) {
duke@0 364 rv = JNI_TRUE;
duke@0 365 }
duke@0 366 } END_PLATFORM_STRING(env, toPath);
duke@0 367 } END_PLATFORM_STRING(env, fromPath);
duke@0 368 return rv;
duke@0 369 }
duke@0 370
duke@0 371 JNIEXPORT jboolean JNICALL
duke@0 372 Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
duke@0 373 jobject file, jlong time)
duke@0 374 {
duke@0 375 jboolean rv = JNI_FALSE;
duke@0 376
duke@0 377 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@358 378 struct stat64 sb;
duke@0 379
alanb@358 380 if (stat64(path, &sb) == 0) {
alanb@358 381 struct timeval tv[2];
alanb@358 382
alanb@358 383 /* Preserve access time */
alanb@358 384 tv[0].tv_sec = sb.st_atime;
alanb@358 385 tv[0].tv_usec = 0;
alanb@358 386
alanb@358 387 /* Change last-modified time */
alanb@358 388 tv[1].tv_sec = time / 1000;
alanb@358 389 tv[1].tv_usec = (time % 1000) * 1000;
alanb@358 390
alanb@358 391 if (utimes(path, tv) == 0)
alanb@358 392 rv = JNI_TRUE;
duke@0 393 }
duke@0 394 } END_PLATFORM_STRING(env, path);
duke@0 395
duke@0 396 return rv;
duke@0 397 }
duke@0 398
duke@0 399
duke@0 400 JNIEXPORT jboolean JNICALL
duke@0 401 Java_java_io_UnixFileSystem_setReadOnly(JNIEnv *env, jobject this,
duke@0 402 jobject file)
duke@0 403 {
duke@0 404 jboolean rv = JNI_FALSE;
duke@0 405
duke@0 406 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
duke@0 407 int mode;
duke@0 408 if (statMode(path, &mode)) {
duke@0 409 if (chmod(path, mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)) >= 0) {
duke@0 410 rv = JNI_TRUE;
duke@0 411 }
duke@0 412 }
duke@0 413 } END_PLATFORM_STRING(env, path);
duke@0 414 return rv;
duke@0 415 }
duke@0 416
duke@0 417 JNIEXPORT jlong JNICALL
duke@0 418 Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,
duke@0 419 jobject file, jint t)
duke@0 420 {
duke@0 421 jlong rv = 0L;
duke@0 422
duke@0 423 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
alanb@2193 424 struct statvfs64 fsstat;
alanb@2193 425 memset(&fsstat, 0, sizeof(fsstat));
alanb@2193 426 if (statvfs64(path, &fsstat) == 0) {
duke@0 427 switch(t) {
duke@0 428 case java_io_FileSystem_SPACE_TOTAL:
duke@0 429 rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
duke@0 430 long_to_jlong(fsstat.f_blocks));
duke@0 431 break;
duke@0 432 case java_io_FileSystem_SPACE_FREE:
duke@0 433 rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
duke@0 434 long_to_jlong(fsstat.f_bfree));
duke@0 435 break;
duke@0 436 case java_io_FileSystem_SPACE_USABLE:
duke@0 437 rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
duke@0 438 long_to_jlong(fsstat.f_bavail));
duke@0 439 break;
duke@0 440 default:
duke@0 441 assert(0);
duke@0 442 }
duke@0 443 }
duke@0 444 } END_PLATFORM_STRING(env, path);
duke@0 445 return rv;
duke@0 446 }