annotate src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c @ 5299:37377dcd43d0

7191556: (fs) UnixNativeDispatcher.getextmntent should be moved into platform specific code Reviewed-by: andrew
author alanb
date Thu, 16 Aug 2012 11:14:42 +0100
parents a18d0a3ac45b
children fd940a08ec2d
rev   line source
alanb@893 1 /*
ohair@3909 2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
alanb@893 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
alanb@893 4 *
alanb@893 5 * This code is free software; you can redistribute it and/or modify it
alanb@893 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
alanb@893 8 * particular file as subject to the "Classpath" exception as provided
ohair@2362 9 * by Oracle in the LICENSE file that accompanied this code.
alanb@893 10 *
alanb@893 11 * This code is distributed in the hope that it will be useful, but WITHOUT
alanb@893 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
alanb@893 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
alanb@893 14 * version 2 for more details (a copy is included in the LICENSE file that
alanb@893 15 * accompanied this code).
alanb@893 16 *
alanb@893 17 * You should have received a copy of the GNU General Public License version
alanb@893 18 * 2 along with this work; if not, write to the Free Software Foundation,
alanb@893 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
alanb@893 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.
alanb@893 24 */
alanb@893 25
alanb@893 26 #include <stdio.h>
alanb@893 27 #include <stdlib.h>
alanb@893 28 #include <limits.h>
alanb@893 29 #include <fcntl.h>
alanb@893 30 #include <dirent.h>
alanb@893 31 #include <unistd.h>
alanb@893 32 #include <pwd.h>
alanb@893 33 #include <grp.h>
alanb@893 34 #include <errno.h>
alanb@893 35 #include <dlfcn.h>
alanb@893 36 #include <sys/types.h>
alanb@893 37 #include <sys/stat.h>
alanb@893 38 #include <sys/statvfs.h>
alanb@893 39 #include <sys/time.h>
alanb@893 40
alanb@893 41 #ifdef __solaris__
alanb@893 42 #include <strings.h>
alanb@893 43 #endif
alanb@893 44
alanb@893 45 #ifdef __linux__
alanb@893 46 #include <string.h>
alanb@893 47 #endif
alanb@893 48
michaelm@4628 49 #ifdef _ALLBSD_SOURCE
michaelm@4628 50 #include <string.h>
michaelm@4628 51
michaelm@4628 52 #define stat64 stat
michaelm@4628 53 #define statvfs64 statvfs
michaelm@4628 54
michaelm@4628 55 #define open64 open
michaelm@4628 56 #define fstat64 fstat
michaelm@4628 57 #define lstat64 lstat
michaelm@4628 58 #define dirent64 dirent
michaelm@4628 59 #define readdir64_r readdir_r
michaelm@4628 60 #endif
michaelm@4628 61
alanb@893 62 #include "jni.h"
alanb@893 63 #include "jni_util.h"
alanb@893 64 #include "jlong.h"
alanb@893 65
alanb@893 66 #include "sun_nio_fs_UnixNativeDispatcher.h"
alanb@893 67
alanb@3484 68 /**
alanb@3484 69 * Size of password or group entry when not available via sysconf
alanb@3484 70 */
alanb@3484 71 #define ENT_BUF_SIZE 1024
alanb@3484 72
alanb@893 73 #define RESTARTABLE(_cmd, _result) do { \
alanb@893 74 do { \
alanb@893 75 _result = _cmd; \
alanb@893 76 } while((_result == -1) && (errno == EINTR)); \
alanb@893 77 } while(0)
alanb@893 78
alanb@3484 79 #define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
alanb@3484 80 do { \
alanb@3484 81 _result = _cmd; \
alanb@3484 82 } while((_result == NULL) && (errno == EINTR)); \
alanb@3484 83 } while(0)
alanb@3484 84
alanb@893 85 static jfieldID attrs_st_mode;
alanb@893 86 static jfieldID attrs_st_ino;
alanb@893 87 static jfieldID attrs_st_dev;
alanb@893 88 static jfieldID attrs_st_rdev;
alanb@893 89 static jfieldID attrs_st_nlink;
alanb@893 90 static jfieldID attrs_st_uid;
alanb@893 91 static jfieldID attrs_st_gid;
alanb@893 92 static jfieldID attrs_st_size;
alanb@893 93 static jfieldID attrs_st_atime;
alanb@893 94 static jfieldID attrs_st_mtime;
alanb@893 95 static jfieldID attrs_st_ctime;
alanb@893 96
alanb@893 97 static jfieldID attrs_f_frsize;
alanb@893 98 static jfieldID attrs_f_blocks;
alanb@893 99 static jfieldID attrs_f_bfree;
alanb@893 100 static jfieldID attrs_f_bavail;
alanb@893 101
alanb@893 102 static jfieldID entry_name;
alanb@893 103 static jfieldID entry_dir;
alanb@893 104 static jfieldID entry_fstype;
alanb@893 105 static jfieldID entry_options;
alanb@893 106 static jfieldID entry_dev;
alanb@893 107
alanb@893 108 /**
alanb@1435 109 * System calls that may not be available at run time.
alanb@893 110 */
alanb@893 111 typedef int openat64_func(int, const char *, int, ...);
alanb@893 112 typedef int fstatat64_func(int, const char *, struct stat64 *, int);
alanb@893 113 typedef int unlinkat_func(int, const char*, int);
alanb@893 114 typedef int renameat_func(int, const char*, int, const char*);
alanb@893 115 typedef int futimesat_func(int, const char *, const struct timeval *);
alanb@1435 116 typedef DIR* fdopendir_func(int);
alanb@893 117
alanb@893 118 static openat64_func* my_openat64_func = NULL;
alanb@893 119 static fstatat64_func* my_fstatat64_func = NULL;
alanb@893 120 static unlinkat_func* my_unlinkat_func = NULL;
alanb@893 121 static renameat_func* my_renameat_func = NULL;
alanb@893 122 static futimesat_func* my_futimesat_func = NULL;
alanb@1435 123 static fdopendir_func* my_fdopendir_func = NULL;
alanb@893 124
alanb@893 125 /**
alanb@893 126 * fstatat missing from glibc on Linux. Temporary workaround
alanb@893 127 * for x86/x64.
alanb@893 128 */
alanb@893 129 #if defined(__linux__) && defined(__i386)
alanb@893 130 #define FSTATAT64_SYSCALL_AVAILABLE
alanb@893 131 static int fstatat64_wrapper(int dfd, const char *path,
alanb@893 132 struct stat64 *statbuf, int flag)
alanb@893 133 {
alanb@893 134 #ifndef __NR_fstatat64
alanb@893 135 #define __NR_fstatat64 300
alanb@893 136 #endif
alanb@893 137 return syscall(__NR_fstatat64, dfd, path, statbuf, flag);
alanb@893 138 }
alanb@893 139 #endif
alanb@893 140
alanb@893 141 #if defined(__linux__) && defined(__x86_64__)
alanb@893 142 #define FSTATAT64_SYSCALL_AVAILABLE
alanb@893 143 static int fstatat64_wrapper(int dfd, const char *path,
alanb@893 144 struct stat64 *statbuf, int flag)
alanb@893 145 {
alanb@893 146 #ifndef __NR_newfstatat
alanb@893 147 #define __NR_newfstatat 262
alanb@893 148 #endif
alanb@893 149 return syscall(__NR_newfstatat, dfd, path, statbuf, flag);
alanb@893 150 }
alanb@893 151 #endif
alanb@893 152
alanb@893 153 /**
alanb@893 154 * Call this to throw an internal UnixException when a system/library
alanb@893 155 * call fails
alanb@893 156 */
alanb@893 157 static void throwUnixException(JNIEnv* env, int errnum) {
alanb@893 158 jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
alanb@893 159 "(I)V", errnum);
alanb@893 160 if (x != NULL) {
alanb@893 161 (*env)->Throw(env, x);
alanb@893 162 }
alanb@893 163 }
alanb@893 164
alanb@893 165 /**
alanb@1319 166 * Initialization
alanb@893 167 */
alanb@1319 168 JNIEXPORT jint JNICALL
alanb@1319 169 Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
alanb@893 170 {
alanb@1319 171 jint flags = 0;
alanb@893 172 jclass clazz;
alanb@893 173
alanb@893 174 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileAttributes");
alanb@893 175 if (clazz == NULL) {
alanb@1319 176 return 0;
alanb@893 177 }
alanb@893 178 attrs_st_mode = (*env)->GetFieldID(env, clazz, "st_mode", "I");
alanb@893 179 attrs_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J");
alanb@893 180 attrs_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J");
alanb@893 181 attrs_st_rdev = (*env)->GetFieldID(env, clazz, "st_rdev", "J");
alanb@893 182 attrs_st_nlink = (*env)->GetFieldID(env, clazz, "st_nlink", "I");
alanb@893 183 attrs_st_uid = (*env)->GetFieldID(env, clazz, "st_uid", "I");
alanb@893 184 attrs_st_gid = (*env)->GetFieldID(env, clazz, "st_gid", "I");
alanb@893 185 attrs_st_size = (*env)->GetFieldID(env, clazz, "st_size", "J");
alanb@893 186 attrs_st_atime = (*env)->GetFieldID(env, clazz, "st_atime", "J");
alanb@893 187 attrs_st_mtime = (*env)->GetFieldID(env, clazz, "st_mtime", "J");
alanb@893 188 attrs_st_ctime = (*env)->GetFieldID(env, clazz, "st_ctime", "J");
alanb@893 189
alanb@893 190 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
alanb@893 191 if (clazz == NULL) {
alanb@1319 192 return 0;
alanb@893 193 }
alanb@893 194 attrs_f_frsize = (*env)->GetFieldID(env, clazz, "f_frsize", "J");
alanb@893 195 attrs_f_blocks = (*env)->GetFieldID(env, clazz, "f_blocks", "J");
alanb@893 196 attrs_f_bfree = (*env)->GetFieldID(env, clazz, "f_bfree", "J");
alanb@893 197 attrs_f_bavail = (*env)->GetFieldID(env, clazz, "f_bavail", "J");
alanb@893 198
alanb@893 199 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
alanb@893 200 if (clazz == NULL) {
alanb@1319 201 return 0;
alanb@893 202 }
alanb@893 203 entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
alanb@893 204 entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
alanb@893 205 entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
alanb@893 206 entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
alanb@893 207 entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
alanb@893 208
alanb@1435 209 /* system calls that might not be available at run time */
alanb@893 210
michaelm@4628 211 #if (defined(__solaris__) && defined(_LP64)) || defined(_ALLBSD_SOURCE)
alanb@893 212 /* Solaris 64-bit does not have openat64/fstatat64 */
alanb@893 213 my_openat64_func = (openat64_func*)dlsym(RTLD_DEFAULT, "openat");
alanb@893 214 my_fstatat64_func = (fstatat64_func*)dlsym(RTLD_DEFAULT, "fstatat");
alanb@893 215 #else
alanb@893 216 my_openat64_func = (openat64_func*) dlsym(RTLD_DEFAULT, "openat64");
alanb@893 217 my_fstatat64_func = (fstatat64_func*) dlsym(RTLD_DEFAULT, "fstatat64");
alanb@893 218 #endif
alanb@893 219 my_unlinkat_func = (unlinkat_func*) dlsym(RTLD_DEFAULT, "unlinkat");
alanb@893 220 my_renameat_func = (renameat_func*) dlsym(RTLD_DEFAULT, "renameat");
alanb@893 221 my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
alanb@1435 222 my_fdopendir_func = (fdopendir_func*) dlsym(RTLD_DEFAULT, "fdopendir");
alanb@893 223
alanb@893 224 #if defined(FSTATAT64_SYSCALL_AVAILABLE)
alanb@893 225 /* fstatat64 missing from glibc */
alanb@893 226 if (my_fstatat64_func == NULL)
alanb@893 227 my_fstatat64_func = (fstatat64_func*)&fstatat64_wrapper;
alanb@893 228 #endif
alanb@1319 229
alanb@1319 230 if (my_openat64_func != NULL && my_fstatat64_func != NULL &&
alanb@1319 231 my_unlinkat_func != NULL && my_renameat_func != NULL &&
alanb@1435 232 my_futimesat_func != NULL && my_fdopendir_func != NULL)
alanb@1319 233 {
alanb@1319 234 flags |= sun_nio_fs_UnixNativeDispatcher_HAS_AT_SYSCALLS;
alanb@1319 235 }
alanb@1319 236
alanb@1319 237 return flags;
alanb@893 238 }
alanb@893 239
alanb@893 240 JNIEXPORT jbyteArray JNICALL
alanb@893 241 Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) {
alanb@893 242 jbyteArray result = NULL;
alanb@893 243 char buf[PATH_MAX+1];
alanb@893 244
alanb@893 245 /* EINTR not listed as a possible error */
alanb@893 246 char* cwd = getcwd(buf, sizeof(buf));
alanb@893 247 if (cwd == NULL) {
alanb@893 248 throwUnixException(env, errno);
alanb@893 249 } else {
alanb@893 250 jsize len = (jsize)strlen(buf);
alanb@893 251 result = (*env)->NewByteArray(env, len);
alanb@893 252 if (result != NULL) {
alanb@893 253 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)buf);
alanb@893 254 }
alanb@893 255 }
alanb@893 256 return result;
alanb@893 257 }
alanb@893 258
alanb@893 259 JNIEXPORT jbyteArray
alanb@893 260 Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
alanb@893 261 {
alanb@893 262 char* msg;
alanb@893 263 jsize len;
alanb@893 264 jbyteArray bytes;
alanb@893 265
alanb@893 266 msg = strerror((int)error);
alanb@893 267 len = strlen(msg);
alanb@893 268 bytes = (*env)->NewByteArray(env, len);
alanb@893 269 if (bytes != NULL) {
alanb@893 270 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
alanb@893 271 }
alanb@893 272 return bytes;
alanb@893 273 }
alanb@893 274
alanb@893 275 JNIEXPORT jint
alanb@893 276 Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
alanb@893 277
alanb@893 278 int res = -1;
alanb@893 279
alanb@893 280 RESTARTABLE(dup((int)fd), res);
alanb@893 281 if (fd == -1) {
alanb@893 282 throwUnixException(env, errno);
alanb@893 283 }
alanb@893 284 return (jint)res;
alanb@893 285 }
alanb@893 286
alanb@893 287 JNIEXPORT jlong JNICALL
alanb@893 288 Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this,
alanb@893 289 jlong pathAddress, jlong modeAddress)
alanb@893 290 {
alanb@893 291 FILE* fp = NULL;
alanb@893 292 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 293 const char* mode = (const char*)jlong_to_ptr(modeAddress);
alanb@893 294
alanb@893 295 do {
alanb@893 296 fp = fopen(path, mode);
alanb@893 297 } while (fp == NULL && errno == EINTR);
alanb@893 298
alanb@893 299 if (fp == NULL) {
alanb@893 300 throwUnixException(env, errno);
alanb@893 301 }
alanb@893 302
alanb@893 303 return ptr_to_jlong(fp);
alanb@893 304 }
alanb@893 305
alanb@893 306 JNIEXPORT void JNICALL
alanb@893 307 Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream)
alanb@893 308 {
alanb@893 309 int res;
alanb@893 310 FILE* fp = jlong_to_ptr(stream);
alanb@893 311
alanb@893 312 do {
alanb@893 313 res = fclose(fp);
alanb@893 314 } while (res == EOF && errno == EINTR);
alanb@893 315 if (res == EOF) {
alanb@893 316 throwUnixException(env, errno);
alanb@893 317 }
alanb@893 318 }
alanb@893 319
alanb@893 320 JNIEXPORT jint JNICALL
alanb@893 321 Java_sun_nio_fs_UnixNativeDispatcher_open0(JNIEnv* env, jclass this,
alanb@893 322 jlong pathAddress, jint oflags, jint mode)
alanb@893 323 {
alanb@893 324 jint fd;
alanb@893 325 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 326
alanb@893 327 RESTARTABLE(open64(path, (int)oflags, (mode_t)mode), fd);
alanb@893 328 if (fd == -1) {
alanb@893 329 throwUnixException(env, errno);
alanb@893 330 }
alanb@893 331 return fd;
alanb@893 332 }
alanb@893 333
alanb@893 334 JNIEXPORT jint JNICALL
alanb@893 335 Java_sun_nio_fs_UnixNativeDispatcher_openat0(JNIEnv* env, jclass this, jint dfd,
alanb@893 336 jlong pathAddress, jint oflags, jint mode)
alanb@893 337 {
alanb@893 338 jint fd;
alanb@893 339 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 340
alanb@893 341 if (my_openat64_func == NULL) {
alanb@893 342 JNU_ThrowInternalError(env, "should not reach here");
alanb@893 343 return -1;
alanb@893 344 }
alanb@893 345
alanb@893 346 RESTARTABLE((*my_openat64_func)(dfd, path, (int)oflags, (mode_t)mode), fd);
alanb@893 347 if (fd == -1) {
alanb@893 348 throwUnixException(env, errno);
alanb@893 349 }
alanb@893 350 return fd;
alanb@893 351 }
alanb@893 352
alanb@893 353 JNIEXPORT void JNICALL
alanb@893 354 Java_sun_nio_fs_UnixNativeDispatcher_close(JNIEnv* env, jclass this, jint fd) {
alanb@893 355 int err;
alanb@893 356 /* TDB - need to decide if EIO and other errors should cause exception */
alanb@893 357 RESTARTABLE(close((int)fd), err);
alanb@893 358 }
alanb@893 359
alanb@893 360 JNIEXPORT jint JNICALL
alanb@893 361 Java_sun_nio_fs_UnixNativeDispatcher_read(JNIEnv* env, jclass this, jint fd,
alanb@893 362 jlong address, jint nbytes)
alanb@893 363 {
alanb@893 364 ssize_t n;
alanb@893 365 void* bufp = jlong_to_ptr(address);
alanb@893 366 RESTARTABLE(read((int)fd, bufp, (size_t)nbytes), n);
alanb@893 367 if (n == -1) {
alanb@893 368 throwUnixException(env, errno);
alanb@893 369 }
alanb@893 370 return (jint)n;
alanb@893 371 }
alanb@893 372
alanb@893 373 JNIEXPORT jint JNICALL
alanb@893 374 Java_sun_nio_fs_UnixNativeDispatcher_write(JNIEnv* env, jclass this, jint fd,
alanb@893 375 jlong address, jint nbytes)
alanb@893 376 {
alanb@893 377 ssize_t n;
alanb@893 378 void* bufp = jlong_to_ptr(address);
alanb@893 379 RESTARTABLE(write((int)fd, bufp, (size_t)nbytes), n);
alanb@893 380 if (n == -1) {
alanb@893 381 throwUnixException(env, errno);
alanb@893 382 }
alanb@893 383 return (jint)n;
alanb@893 384 }
alanb@893 385
alanb@893 386 /**
alanb@893 387 * Copy stat64 members into sun.nio.fs.UnixFileAttributes
alanb@893 388 */
alanb@893 389 static void prepAttributes(JNIEnv* env, struct stat64* buf, jobject attrs) {
alanb@893 390 (*env)->SetIntField(env, attrs, attrs_st_mode, (jint)buf->st_mode);
alanb@893 391 (*env)->SetLongField(env, attrs, attrs_st_ino, (jlong)buf->st_ino);
alanb@893 392 (*env)->SetLongField(env, attrs, attrs_st_dev, (jlong)buf->st_dev);
alanb@893 393 (*env)->SetLongField(env, attrs, attrs_st_rdev, (jlong)buf->st_rdev);
alanb@893 394 (*env)->SetIntField(env, attrs, attrs_st_nlink, (jint)buf->st_nlink);
alanb@893 395 (*env)->SetIntField(env, attrs, attrs_st_uid, (jint)buf->st_uid);
alanb@893 396 (*env)->SetIntField(env, attrs, attrs_st_gid, (jint)buf->st_gid);
alanb@893 397 (*env)->SetLongField(env, attrs, attrs_st_size, (jlong)buf->st_size);
alanb@1319 398 (*env)->SetLongField(env, attrs, attrs_st_atime, (jlong)buf->st_atime);
alanb@1319 399 (*env)->SetLongField(env, attrs, attrs_st_mtime, (jlong)buf->st_mtime);
alanb@1319 400 (*env)->SetLongField(env, attrs, attrs_st_ctime, (jlong)buf->st_ctime);
alanb@893 401 }
alanb@893 402
alanb@893 403 JNIEXPORT void JNICALL
alanb@893 404 Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
alanb@893 405 jlong pathAddress, jobject attrs)
alanb@893 406 {
alanb@893 407 int err;
alanb@893 408 struct stat64 buf;
alanb@893 409 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 410
alanb@893 411 RESTARTABLE(stat64(path, &buf), err);
alanb@893 412 if (err == -1) {
alanb@893 413 throwUnixException(env, errno);
alanb@893 414 } else {
alanb@893 415 prepAttributes(env, &buf, attrs);
alanb@893 416 }
alanb@893 417 }
alanb@893 418
alanb@893 419 JNIEXPORT void JNICALL
alanb@893 420 Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
alanb@893 421 jlong pathAddress, jobject attrs)
alanb@893 422 {
alanb@893 423 int err;
alanb@893 424 struct stat64 buf;
alanb@893 425 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 426
alanb@893 427 RESTARTABLE(lstat64(path, &buf), err);
alanb@893 428 if (err == -1) {
alanb@893 429 throwUnixException(env, errno);
alanb@893 430 } else {
alanb@893 431 prepAttributes(env, &buf, attrs);
alanb@893 432 }
alanb@893 433 }
alanb@893 434
alanb@893 435 JNIEXPORT void JNICALL
alanb@893 436 Java_sun_nio_fs_UnixNativeDispatcher_fstat(JNIEnv* env, jclass this, jint fd,
alanb@893 437 jobject attrs)
alanb@893 438 {
alanb@893 439 int err;
alanb@893 440 struct stat64 buf;
alanb@893 441
alanb@893 442 RESTARTABLE(fstat64((int)fd, &buf), err);
alanb@893 443 if (err == -1) {
alanb@893 444 throwUnixException(env, errno);
alanb@893 445 } else {
alanb@893 446 prepAttributes(env, &buf, attrs);
alanb@893 447 }
alanb@893 448 }
alanb@893 449
alanb@893 450 JNIEXPORT void JNICALL
alanb@893 451 Java_sun_nio_fs_UnixNativeDispatcher_fstatat0(JNIEnv* env, jclass this, jint dfd,
alanb@893 452 jlong pathAddress, jint flag, jobject attrs)
alanb@893 453 {
alanb@893 454 int err;
alanb@893 455 struct stat64 buf;
alanb@893 456 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 457
alanb@893 458 if (my_fstatat64_func == NULL) {
alanb@893 459 JNU_ThrowInternalError(env, "should not reach here");
alanb@893 460 return;
alanb@893 461 }
alanb@893 462 RESTARTABLE((*my_fstatat64_func)((int)dfd, path, &buf, (int)flag), err);
alanb@893 463 if (err == -1) {
alanb@893 464 throwUnixException(env, errno);
alanb@893 465 } else {
alanb@893 466 prepAttributes(env, &buf, attrs);
alanb@893 467 }
alanb@893 468 }
alanb@893 469
alanb@893 470 JNIEXPORT void JNICALL
alanb@893 471 Java_sun_nio_fs_UnixNativeDispatcher_chmod0(JNIEnv* env, jclass this,
alanb@893 472 jlong pathAddress, jint mode)
alanb@893 473 {
alanb@893 474 int err;
alanb@893 475 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 476
alanb@893 477 RESTARTABLE(chmod(path, (mode_t)mode), err);
alanb@893 478 if (err == -1) {
alanb@893 479 throwUnixException(env, errno);
alanb@893 480 }
alanb@893 481 }
alanb@893 482
alanb@893 483 JNIEXPORT void JNICALL
alanb@893 484 Java_sun_nio_fs_UnixNativeDispatcher_fchmod(JNIEnv* env, jclass this, jint filedes,
alanb@893 485 jint mode)
alanb@893 486 {
alanb@893 487 int err;
alanb@893 488
alanb@893 489 RESTARTABLE(fchmod((int)filedes, (mode_t)mode), err);
alanb@893 490 if (err == -1) {
alanb@893 491 throwUnixException(env, errno);
alanb@893 492 }
alanb@893 493 }
alanb@893 494
alanb@893 495
alanb@893 496 JNIEXPORT void JNICALL
alanb@893 497 Java_sun_nio_fs_UnixNativeDispatcher_chown0(JNIEnv* env, jclass this,
alanb@893 498 jlong pathAddress, jint uid, jint gid)
alanb@893 499 {
alanb@893 500 int err;
alanb@893 501 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 502
alanb@893 503 RESTARTABLE(chown(path, (uid_t)uid, (gid_t)gid), err);
alanb@893 504 if (err == -1) {
alanb@893 505 throwUnixException(env, errno);
alanb@893 506 }
alanb@893 507 }
alanb@893 508
alanb@893 509 JNIEXPORT void JNICALL
alanb@893 510 Java_sun_nio_fs_UnixNativeDispatcher_lchown0(JNIEnv* env, jclass this, jlong pathAddress, jint uid, jint gid)
alanb@893 511 {
alanb@893 512 int err;
alanb@893 513 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 514
alanb@893 515 RESTARTABLE(lchown(path, (uid_t)uid, (gid_t)gid), err);
alanb@893 516 if (err == -1) {
alanb@893 517 throwUnixException(env, errno);
alanb@893 518 }
alanb@893 519 }
alanb@893 520
alanb@893 521 JNIEXPORT void JNICALL
alanb@893 522 Java_sun_nio_fs_UnixNativeDispatcher_fchown(JNIEnv* env, jclass this, jint filedes, jint uid, jint gid)
alanb@893 523 {
alanb@893 524 int err;
alanb@893 525
alanb@893 526 RESTARTABLE(fchown(filedes, (uid_t)uid, (gid_t)gid), err);
alanb@893 527 if (err == -1) {
alanb@893 528 throwUnixException(env, errno);
alanb@893 529 }
alanb@893 530 }
alanb@893 531
alanb@893 532 JNIEXPORT void JNICALL
alanb@893 533 Java_sun_nio_fs_UnixNativeDispatcher_utimes0(JNIEnv* env, jclass this,
alanb@893 534 jlong pathAddress, jlong accessTime, jlong modificationTime)
alanb@893 535 {
alanb@893 536 int err;
alanb@893 537 struct timeval times[2];
alanb@893 538 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 539
alanb@1319 540 times[0].tv_sec = accessTime / 1000000;
alanb@1319 541 times[0].tv_usec = accessTime % 1000000;
alanb@893 542
alanb@1319 543 times[1].tv_sec = modificationTime / 1000000;
alanb@1319 544 times[1].tv_usec = modificationTime % 1000000;
alanb@893 545
alanb@893 546 RESTARTABLE(utimes(path, &times[0]), err);
alanb@893 547 if (err == -1) {
alanb@893 548 throwUnixException(env, errno);
alanb@893 549 }
alanb@893 550 }
alanb@893 551
alanb@893 552 JNIEXPORT void JNICALL
alanb@893 553 Java_sun_nio_fs_UnixNativeDispatcher_futimes(JNIEnv* env, jclass this, jint filedes,
alanb@893 554 jlong accessTime, jlong modificationTime)
alanb@893 555 {
alanb@893 556 struct timeval times[2];
alanb@893 557 int err = 0;
alanb@893 558
alanb@1319 559 times[0].tv_sec = accessTime / 1000000;
alanb@1319 560 times[0].tv_usec = accessTime % 1000000;
alanb@893 561
alanb@1319 562 times[1].tv_sec = modificationTime / 1000000;
alanb@1319 563 times[1].tv_usec = modificationTime % 1000000;
alanb@893 564
michaelm@4628 565 #ifdef _ALLBSD_SOURCE
michaelm@4628 566 RESTARTABLE(futimes(filedes, &times[0]), err);
michaelm@4628 567 #else
michaelm@4628 568 if (my_futimesat_func == NULL) {
michaelm@4628 569 JNU_ThrowInternalError(env, "my_ftimesat_func is NULL");
michaelm@4628 570 return;
michaelm@4628 571 }
michaelm@4628 572 RESTARTABLE((*my_futimesat_func)(filedes, NULL, &times[0]), err);
michaelm@4628 573 #endif
michaelm@4628 574 if (err == -1) {
michaelm@4628 575 throwUnixException(env, errno);
alanb@893 576 }
alanb@893 577 }
alanb@893 578
alanb@893 579 JNIEXPORT jlong JNICALL
alanb@893 580 Java_sun_nio_fs_UnixNativeDispatcher_opendir0(JNIEnv* env, jclass this,
alanb@893 581 jlong pathAddress)
alanb@893 582 {
alanb@893 583 DIR* dir;
alanb@893 584 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 585
alanb@893 586 /* EINTR not listed as a possible error */
alanb@893 587 dir = opendir(path);
alanb@893 588 if (dir == NULL) {
alanb@893 589 throwUnixException(env, errno);
alanb@893 590 }
alanb@893 591 return ptr_to_jlong(dir);
alanb@893 592 }
alanb@893 593
alanb@893 594 JNIEXPORT jlong JNICALL
alanb@893 595 Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
alanb@893 596 DIR* dir;
alanb@893 597
alanb@1435 598 if (my_fdopendir_func == NULL) {
alanb@1435 599 JNU_ThrowInternalError(env, "should not reach here");
alanb@1435 600 return (jlong)-1;
alanb@1435 601 }
alanb@1435 602
alanb@893 603 /* EINTR not listed as a possible error */
alanb@1435 604 dir = (*my_fdopendir_func)((int)dfd);
alanb@893 605 if (dir == NULL) {
alanb@893 606 throwUnixException(env, errno);
alanb@893 607 }
alanb@893 608 return ptr_to_jlong(dir);
alanb@893 609 }
alanb@893 610
alanb@893 611 JNIEXPORT void JNICALL
alanb@893 612 Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {
alanb@893 613 int err;
alanb@893 614 DIR* dirp = jlong_to_ptr(dir);
alanb@893 615
alanb@893 616 RESTARTABLE(closedir(dirp), err);
alanb@893 617 if (errno == -1) {
alanb@893 618 throwUnixException(env, errno);
alanb@893 619 }
alanb@893 620 }
alanb@893 621
alanb@893 622 JNIEXPORT jbyteArray JNICALL
alanb@893 623 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
alanb@893 624 struct dirent64* result;
alanb@4786 625 struct {
alanb@4786 626 struct dirent64 buf;
alanb@4786 627 char name_extra[PATH_MAX + 1 - sizeof result->d_name];
alanb@4786 628 } entry;
alanb@4786 629 struct dirent64* ptr = &entry.buf;
alanb@893 630 int res;
alanb@893 631 DIR* dirp = jlong_to_ptr(value);
alanb@893 632
alanb@893 633 /* EINTR not listed as a possible error */
alanb@893 634 /* TDB: reentrant version probably not required here */
alanb@893 635 res = readdir64_r(dirp, ptr, &result);
alanb@893 636 if (res != 0) {
alanb@893 637 throwUnixException(env, res);
alanb@893 638 return NULL;
alanb@893 639 } else {
alanb@893 640 if (result == NULL) {
alanb@893 641 return NULL;
alanb@893 642 } else {
alanb@893 643 jsize len = strlen(ptr->d_name);
alanb@893 644 jbyteArray bytes = (*env)->NewByteArray(env, len);
alanb@893 645 if (bytes != NULL) {
alanb@893 646 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
alanb@893 647 }
alanb@893 648 return bytes;
alanb@893 649 }
alanb@893 650 }
alanb@893 651 }
alanb@893 652
alanb@893 653 JNIEXPORT void JNICALL
alanb@893 654 Java_sun_nio_fs_UnixNativeDispatcher_mkdir0(JNIEnv* env, jclass this,
alanb@893 655 jlong pathAddress, jint mode)
alanb@893 656 {
alanb@893 657 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 658
alanb@893 659 /* EINTR not listed as a possible error */
alanb@893 660 if (mkdir(path, (mode_t)mode) == -1) {
alanb@893 661 throwUnixException(env, errno);
alanb@893 662 }
alanb@893 663 }
alanb@893 664
alanb@893 665 JNIEXPORT void JNICALL
alanb@893 666 Java_sun_nio_fs_UnixNativeDispatcher_rmdir0(JNIEnv* env, jclass this,
alanb@893 667 jlong pathAddress)
alanb@893 668 {
alanb@893 669 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 670
alanb@893 671 /* EINTR not listed as a possible error */
alanb@893 672 if (rmdir(path) == -1) {
alanb@893 673 throwUnixException(env, errno);
alanb@893 674 }
alanb@893 675 }
alanb@893 676
alanb@893 677 JNIEXPORT void JNICALL
alanb@893 678 Java_sun_nio_fs_UnixNativeDispatcher_link0(JNIEnv* env, jclass this,
alanb@893 679 jlong existingAddress, jlong newAddress)
alanb@893 680 {
alanb@893 681 int err;
alanb@893 682 const char* existing = (const char*)jlong_to_ptr(existingAddress);
alanb@893 683 const char* newname = (const char*)jlong_to_ptr(newAddress);
alanb@893 684
alanb@893 685 RESTARTABLE(link(existing, newname), err);
alanb@893 686 if (err == -1) {
alanb@893 687 throwUnixException(env, errno);
alanb@893 688 }
alanb@893 689 }
alanb@893 690
alanb@893 691
alanb@893 692 JNIEXPORT void JNICALL
alanb@893 693 Java_sun_nio_fs_UnixNativeDispatcher_unlink0(JNIEnv* env, jclass this,
alanb@893 694 jlong pathAddress)
alanb@893 695 {
alanb@893 696 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 697
alanb@893 698 /* EINTR not listed as a possible error */
alanb@893 699 if (unlink(path) == -1) {
alanb@893 700 throwUnixException(env, errno);
alanb@893 701 }
alanb@893 702 }
alanb@893 703
alanb@893 704 JNIEXPORT void JNICALL
alanb@893 705 Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0(JNIEnv* env, jclass this, jint dfd,
alanb@893 706 jlong pathAddress, jint flags)
alanb@893 707 {
alanb@893 708 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 709
alanb@893 710 if (my_unlinkat_func == NULL) {
alanb@893 711 JNU_ThrowInternalError(env, "should not reach here");
alanb@893 712 return;
alanb@893 713 }
alanb@893 714
alanb@893 715 /* EINTR not listed as a possible error */
alanb@893 716 if ((*my_unlinkat_func)((int)dfd, path, (int)flags) == -1) {
alanb@893 717 throwUnixException(env, errno);
alanb@893 718 }
alanb@893 719 }
alanb@893 720
alanb@893 721 JNIEXPORT void JNICALL
alanb@893 722 Java_sun_nio_fs_UnixNativeDispatcher_rename0(JNIEnv* env, jclass this,
alanb@893 723 jlong fromAddress, jlong toAddress)
alanb@893 724 {
alanb@893 725 const char* from = (const char*)jlong_to_ptr(fromAddress);
alanb@893 726 const char* to = (const char*)jlong_to_ptr(toAddress);
alanb@893 727
alanb@893 728 /* EINTR not listed as a possible error */
alanb@893 729 if (rename(from, to) == -1) {
alanb@893 730 throwUnixException(env, errno);
alanb@893 731 }
alanb@893 732 }
alanb@893 733
alanb@893 734 JNIEXPORT void JNICALL
alanb@893 735 Java_sun_nio_fs_UnixNativeDispatcher_renameat0(JNIEnv* env, jclass this,
alanb@893 736 jint fromfd, jlong fromAddress, jint tofd, jlong toAddress)
alanb@893 737 {
alanb@893 738 const char* from = (const char*)jlong_to_ptr(fromAddress);
alanb@893 739 const char* to = (const char*)jlong_to_ptr(toAddress);
alanb@893 740
alanb@893 741 if (my_renameat_func == NULL) {
alanb@893 742 JNU_ThrowInternalError(env, "should not reach here");
alanb@893 743 return;
alanb@893 744 }
alanb@893 745
alanb@893 746 /* EINTR not listed as a possible error */
alanb@893 747 if ((*my_renameat_func)((int)fromfd, from, (int)tofd, to) == -1) {
alanb@893 748 throwUnixException(env, errno);
alanb@893 749 }
alanb@893 750 }
alanb@893 751
alanb@893 752 JNIEXPORT void JNICALL
alanb@893 753 Java_sun_nio_fs_UnixNativeDispatcher_symlink0(JNIEnv* env, jclass this,
alanb@893 754 jlong targetAddress, jlong linkAddress)
alanb@893 755 {
alanb@893 756 const char* target = (const char*)jlong_to_ptr(targetAddress);
alanb@893 757 const char* link = (const char*)jlong_to_ptr(linkAddress);
alanb@893 758
alanb@893 759 /* EINTR not listed as a possible error */
alanb@893 760 if (symlink(target, link) == -1) {
alanb@893 761 throwUnixException(env, errno);
alanb@893 762 }
alanb@893 763 }
alanb@893 764
alanb@893 765 JNIEXPORT jbyteArray JNICALL
alanb@893 766 Java_sun_nio_fs_UnixNativeDispatcher_readlink0(JNIEnv* env, jclass this,
alanb@893 767 jlong pathAddress)
alanb@893 768 {
alanb@893 769 jbyteArray result = NULL;
alanb@893 770 char target[PATH_MAX+1];
alanb@893 771 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 772
alanb@893 773 /* EINTR not listed as a possible error */
alanb@893 774 int n = readlink(path, target, sizeof(target));
alanb@893 775 if (n == -1) {
alanb@893 776 throwUnixException(env, errno);
alanb@893 777 } else {
alanb@893 778 jsize len;
alanb@893 779 if (n == sizeof(target)) {
alanb@893 780 n--;
alanb@893 781 }
alanb@893 782 target[n] = '\0';
alanb@893 783 len = (jsize)strlen(target);
alanb@893 784 result = (*env)->NewByteArray(env, len);
alanb@893 785 if (result != NULL) {
alanb@893 786 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)target);
alanb@893 787 }
alanb@893 788 }
alanb@893 789 return result;
alanb@893 790 }
alanb@893 791
alanb@893 792 JNIEXPORT jbyteArray JNICALL
alanb@893 793 Java_sun_nio_fs_UnixNativeDispatcher_realpath0(JNIEnv* env, jclass this,
alanb@893 794 jlong pathAddress)
alanb@893 795 {
alanb@893 796 jbyteArray result = NULL;
alanb@893 797 char resolved[PATH_MAX+1];
alanb@893 798 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 799
alanb@893 800 /* EINTR not listed as a possible error */
alanb@893 801 if (realpath(path, resolved) == NULL) {
alanb@893 802 throwUnixException(env, errno);
alanb@893 803 } else {
alanb@893 804 jsize len = (jsize)strlen(resolved);
alanb@893 805 result = (*env)->NewByteArray(env, len);
alanb@893 806 if (result != NULL) {
alanb@893 807 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)resolved);
alanb@893 808 }
alanb@893 809 }
alanb@893 810 return result;
alanb@893 811 }
alanb@893 812
alanb@893 813 JNIEXPORT void JNICALL
alanb@893 814 Java_sun_nio_fs_UnixNativeDispatcher_access0(JNIEnv* env, jclass this,
alanb@893 815 jlong pathAddress, jint amode)
alanb@893 816 {
alanb@893 817 int err;
alanb@893 818 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 819
alanb@893 820 RESTARTABLE(access(path, (int)amode), err);
alanb@893 821 if (err == -1) {
alanb@893 822 throwUnixException(env, errno);
alanb@893 823 }
alanb@893 824 }
alanb@893 825
alanb@893 826 JNIEXPORT void JNICALL
alanb@893 827 Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
alanb@893 828 jlong pathAddress, jobject attrs)
alanb@893 829 {
alanb@893 830 int err;
alanb@893 831 struct statvfs64 buf;
alanb@893 832 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 833
alanb@893 834
alanb@893 835 RESTARTABLE(statvfs64(path, &buf), err);
alanb@893 836 if (err == -1) {
alanb@893 837 throwUnixException(env, errno);
alanb@893 838 } else {
alanb@893 839 (*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
alanb@893 840 (*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
alanb@893 841 (*env)->SetLongField(env, attrs, attrs_f_bfree, long_to_jlong(buf.f_bfree));
alanb@893 842 (*env)->SetLongField(env, attrs, attrs_f_bavail, long_to_jlong(buf.f_bavail));
alanb@893 843 }
alanb@893 844 }
alanb@893 845
alanb@893 846 JNIEXPORT jlong JNICALL
alanb@893 847 Java_sun_nio_fs_UnixNativeDispatcher_pathconf0(JNIEnv* env, jclass this,
alanb@893 848 jlong pathAddress, jint name)
alanb@893 849 {
alanb@893 850 long err;
alanb@893 851 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 852
alanb@893 853 err = pathconf(path, (int)name);
alanb@893 854 if (err == -1) {
alanb@893 855 throwUnixException(env, errno);
alanb@893 856 }
alanb@893 857 return (jlong)err;
alanb@893 858 }
alanb@893 859
alanb@893 860 JNIEXPORT jlong JNICALL
alanb@893 861 Java_sun_nio_fs_UnixNativeDispatcher_fpathconf(JNIEnv* env, jclass this,
alanb@893 862 jint fd, jint name)
alanb@893 863 {
alanb@893 864 long err;
alanb@893 865
alanb@893 866 err = fpathconf((int)fd, (int)name);
alanb@893 867 if (err == -1) {
alanb@893 868 throwUnixException(env, errno);
alanb@893 869 }
alanb@893 870 return (jlong)err;
alanb@893 871 }
alanb@893 872
alanb@893 873 JNIEXPORT void JNICALL
alanb@893 874 Java_sun_nio_fs_UnixNativeDispatcher_mknod0(JNIEnv* env, jclass this,
alanb@893 875 jlong pathAddress, jint mode, jlong dev)
alanb@893 876 {
alanb@893 877 int err;
alanb@893 878 const char* path = (const char*)jlong_to_ptr(pathAddress);
alanb@893 879
alanb@893 880 RESTARTABLE(mknod(path, (mode_t)mode, (dev_t)dev), err);
alanb@893 881 if (err == -1) {
alanb@893 882 throwUnixException(env, errno);
alanb@893 883 }
alanb@893 884 }
alanb@893 885
alanb@893 886 JNIEXPORT jbyteArray JNICALL
alanb@893 887 Java_sun_nio_fs_UnixNativeDispatcher_getpwuid(JNIEnv* env, jclass this, jint uid)
alanb@893 888 {
alanb@893 889 jbyteArray result = NULL;
alanb@893 890 int buflen;
alanb@3484 891 char* pwbuf;
alanb@893 892
alanb@3484 893 /* allocate buffer for password record */
alanb@893 894 buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
alanb@3484 895 if (buflen == -1)
alanb@3484 896 buflen = ENT_BUF_SIZE;
alanb@3484 897 pwbuf = (char*)malloc(buflen);
alanb@3484 898 if (pwbuf == NULL) {
alanb@3484 899 JNU_ThrowOutOfMemoryError(env, "native heap");
alanb@893 900 } else {
alanb@3484 901 struct passwd pwent;
alanb@3484 902 struct passwd* p = NULL;
alanb@3484 903 int res = 0;
alanb@3484 904
alanb@3484 905 errno = 0;
alanb@3484 906 #ifdef __solaris__
alanb@3484 907 RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
alanb@3484 908 #else
alanb@3484 909 RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
alanb@3484 910 #endif
alanb@3484 911
alanb@3484 912 if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
alanb@3484 913 /* not found or error */
alanb@4225 914 if (errno == 0)
alanb@4225 915 errno = ENOENT;
alanb@4225 916 throwUnixException(env, errno);
alanb@893 917 } else {
alanb@3484 918 jsize len = strlen(p->pw_name);
alanb@3484 919 result = (*env)->NewByteArray(env, len);
alanb@3484 920 if (result != NULL) {
alanb@3484 921 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
alanb@3484 922 }
alanb@3484 923 }
alanb@3484 924 free(pwbuf);
alanb@3484 925 }
alanb@893 926
alanb@893 927 return result;
alanb@893 928 }
alanb@893 929
alanb@893 930
alanb@893 931 JNIEXPORT jbyteArray JNICALL
alanb@893 932 Java_sun_nio_fs_UnixNativeDispatcher_getgrgid(JNIEnv* env, jclass this, jint gid)
alanb@893 933 {
alanb@893 934 jbyteArray result = NULL;
alanb@893 935 int buflen;
alanb@3484 936 int retry;
alanb@893 937
alanb@3484 938 /* initial size of buffer for group record */
alanb@893 939 buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
alanb@3484 940 if (buflen == -1)
alanb@3484 941 buflen = ENT_BUF_SIZE;
alanb@3484 942
alanb@3484 943 do {
alanb@3484 944 struct group grent;
alanb@3484 945 struct group* g = NULL;
alanb@3484 946 int res = 0;
alanb@3484 947
alanb@893 948 char* grbuf = (char*)malloc(buflen);
alanb@893 949 if (grbuf == NULL) {
alanb@893 950 JNU_ThrowOutOfMemoryError(env, "native heap");
alanb@3484 951 return NULL;
alanb@3484 952 }
alanb@893 953
alanb@3484 954 errno = 0;
alanb@3484 955 #ifdef __solaris__
alanb@3484 956 RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
alanb@3484 957 #else
alanb@3484 958 RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
alanb@3484 959 #endif
alanb@3484 960
alanb@3484 961 retry = 0;
alanb@3484 962 if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
alanb@3484 963 /* not found or error */
alanb@4225 964 if (errno == ERANGE) {
alanb@4225 965 /* insufficient buffer size so need larger buffer */
alanb@4225 966 buflen += ENT_BUF_SIZE;
alanb@4225 967 retry = 1;
alanb@4225 968 } else {
alanb@4225 969 if (errno == 0)
alanb@4225 970 errno = ENOENT;
alanb@4225 971 throwUnixException(env, errno);
alanb@893 972 }
alanb@3484 973 } else {
alanb@3484 974 jsize len = strlen(g->gr_name);
alanb@3484 975 result = (*env)->NewByteArray(env, len);
alanb@3484 976 if (result != NULL) {
alanb@3484 977 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
alanb@3484 978 }
alanb@893 979 }
alanb@3484 980
alanb@3484 981 free(grbuf);
alanb@3484 982
alanb@3484 983 } while (retry);
alanb@3484 984
alanb@893 985 return result;
alanb@893 986 }
alanb@893 987
alanb@893 988 JNIEXPORT jint JNICALL
alanb@893 989 Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0(JNIEnv* env, jclass this,
alanb@893 990 jlong nameAddress)
alanb@893 991 {
alanb@893 992 jint uid = -1;
alanb@893 993 int buflen;
alanb@893 994 char* pwbuf;
alanb@893 995
alanb@3484 996 /* allocate buffer for password record */
alanb@893 997 buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
alanb@3484 998 if (buflen == -1)
alanb@3484 999 buflen = ENT_BUF_SIZE;
alanb@893 1000 pwbuf = (char*)malloc(buflen);
alanb@893 1001 if (pwbuf == NULL) {
alanb@893 1002 JNU_ThrowOutOfMemoryError(env, "native heap");
alanb@3484 1003 } else {
alanb@3484 1004 struct passwd pwent;
alanb@3484 1005 struct passwd* p = NULL;
alanb@3484 1006 int res = 0;
alanb@3484 1007 const char* name = (const char*)jlong_to_ptr(nameAddress);
alanb@3484 1008
alanb@3484 1009 errno = 0;
alanb@3484 1010 #ifdef __solaris__
alanb@3484 1011 RESTARTABLE_RETURN_PTR(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen), p);
alanb@3484 1012 #else
alanb@3484 1013 RESTARTABLE(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p), res);
alanb@3484 1014 #endif
alanb@3484 1015
alanb@3484 1016 if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
alanb@3484 1017 /* not found or error */
luchsh@5292 1018 if (errno != 0 && errno != ENOENT && errno != ESRCH)
alanb@3484 1019 throwUnixException(env, errno);
alanb@3484 1020 } else {
alanb@3484 1021 uid = p->pw_uid;
alanb@3484 1022 }
alanb@3484 1023 free(pwbuf);
alanb@893 1024 }
alanb@893 1025
alanb@893 1026 return uid;
alanb@893 1027 }
alanb@893 1028
alanb@893 1029 JNIEXPORT jint JNICALL
alanb@893 1030 Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0(JNIEnv* env, jclass this,
alanb@893 1031 jlong nameAddress)
alanb@893 1032 {
alanb@893 1033 jint gid = -1;
alanb@3484 1034 int buflen, retry;
alanb@893 1035
alanb@3484 1036 /* initial size of buffer for group record */
alanb@893 1037 buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
alanb@3484 1038 if (buflen == -1)
alanb@3484 1039 buflen = ENT_BUF_SIZE;
alanb@893 1040
alanb@3484 1041 do {
alanb@3484 1042 struct group grent;
alanb@3484 1043 struct group* g = NULL;
alanb@3484 1044 int res = 0;
alanb@3484 1045 char *grbuf;
alanb@3484 1046 const char* name = (const char*)jlong_to_ptr(nameAddress);
alanb@893 1047
alanb@3484 1048 grbuf = (char*)malloc(buflen);
alanb@3484 1049 if (grbuf == NULL) {
alanb@3484 1050 JNU_ThrowOutOfMemoryError(env, "native heap");
alanb@3484 1051 return -1;
alanb@3484 1052 }
alanb@3484 1053
alanb@3484 1054 errno = 0;
alanb@3484 1055 #ifdef __solaris__
alanb@3484 1056 RESTARTABLE_RETURN_PTR(getgrnam_r(name, &grent, grbuf, (size_t)buflen), g);
alanb@3484 1057 #else
alanb@3484 1058 RESTARTABLE(getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g), res);
alanb@3484 1059 #endif
alanb@3484 1060
alanb@3484 1061 retry = 0;
alanb@3484 1062 if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
alanb@3484 1063 /* not found or error */
luchsh@5292 1064 if (errno != 0 && errno != ENOENT && errno != ESRCH) {
alanb@3484 1065 if (errno == ERANGE) {
alanb@3484 1066 /* insufficient buffer size so need larger buffer */
alanb@3484 1067 buflen += ENT_BUF_SIZE;
alanb@3484 1068 retry = 1;
alanb@3484 1069 } else {
alanb@3484 1070 throwUnixException(env, errno);
alanb@3484 1071 }
alanb@3484 1072 }
alanb@3484 1073 } else {
alanb@3484 1074 gid = g->gr_gid;
alanb@3484 1075 }
alanb@3484 1076
alanb@3484 1077 free(grbuf);
alanb@3484 1078
alanb@3484 1079 } while (retry);
alanb@893 1080
alanb@893 1081 return gid;
alanb@893 1082 }