< prev index next >

src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c

Print this page
rev 8219 : 8024900: PPC64: Enable new build on AIX (jdk part)
8024854: PPC64: Basic changes and files to build the class library on AIX
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan, art, erikj
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com


  42 #include <strings.h>
  43 #endif
  44 
  45 #ifdef __linux__
  46 #include <string.h>
  47 #endif
  48 
  49 #ifdef _ALLBSD_SOURCE
  50 #include <string.h>
  51 
  52 #define stat64 stat
  53 #define statvfs64 statvfs
  54 
  55 #define open64 open
  56 #define fstat64 fstat
  57 #define lstat64 lstat
  58 #define dirent64 dirent
  59 #define readdir64_r readdir_r
  60 #endif
  61 





  62 #include "jni.h"
  63 #include "jni_util.h"
  64 #include "jlong.h"
  65 
  66 #include "sun_nio_fs_UnixNativeDispatcher.h"
  67 
  68 /**
  69  * Size of password or group entry when not available via sysconf
  70  */
  71 #define ENT_BUF_SIZE   1024
  72 
  73 #define RESTARTABLE(_cmd, _result) do { \
  74   do { \
  75     _result = _cmd; \
  76   } while((_result == -1) && (errno == EINTR)); \
  77 } while(0)
  78 
  79 #define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
  80   do { \
  81     _result = _cmd; \


  88 static jfieldID attrs_st_rdev;
  89 static jfieldID attrs_st_nlink;
  90 static jfieldID attrs_st_uid;
  91 static jfieldID attrs_st_gid;
  92 static jfieldID attrs_st_size;
  93 static jfieldID attrs_st_atime;
  94 static jfieldID attrs_st_mtime;
  95 static jfieldID attrs_st_ctime;
  96 
  97 static jfieldID attrs_f_frsize;
  98 static jfieldID attrs_f_blocks;
  99 static jfieldID attrs_f_bfree;
 100 static jfieldID attrs_f_bavail;
 101 
 102 static jfieldID entry_name;
 103 static jfieldID entry_dir;
 104 static jfieldID entry_fstype;
 105 static jfieldID entry_options;
 106 static jfieldID entry_dev;
 107 







 108 /**
 109  * System calls that may not be available at run time.
 110  */
 111 typedef int openat64_func(int, const char *, int, ...);
 112 typedef int fstatat64_func(int, const char *, struct stat64 *, int);
 113 typedef int unlinkat_func(int, const char*, int);
 114 typedef int renameat_func(int, const char*, int, const char*);
 115 typedef int futimesat_func(int, const char *, const struct timeval *);
 116 typedef DIR* fdopendir_func(int);
 117 
 118 static openat64_func* my_openat64_func = NULL;
 119 static fstatat64_func* my_fstatat64_func = NULL;
 120 static unlinkat_func* my_unlinkat_func = NULL;
 121 static renameat_func* my_renameat_func = NULL;
 122 static futimesat_func* my_futimesat_func = NULL;
 123 static fdopendir_func* my_fdopendir_func = NULL;
 124 
 125 /**
 126  * fstatat missing from glibc on Linux. Temporary workaround
 127  * for x86/x64.


 189 
 190     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
 191     if (clazz == NULL) {
 192         return 0;
 193     }
 194     attrs_f_frsize = (*env)->GetFieldID(env, clazz, "f_frsize", "J");
 195     attrs_f_blocks = (*env)->GetFieldID(env, clazz, "f_blocks", "J");
 196     attrs_f_bfree = (*env)->GetFieldID(env, clazz, "f_bfree", "J");
 197     attrs_f_bavail = (*env)->GetFieldID(env, clazz, "f_bavail", "J");
 198 
 199     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
 200     if (clazz == NULL) {
 201         return 0;
 202     }
 203     entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
 204     entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
 205     entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
 206     entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
 207     entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
 208 











 209     /* system calls that might not be available at run time */
 210 
 211 #if (defined(__solaris__) && defined(_LP64)) || defined(_ALLBSD_SOURCE)
 212     /* Solaris 64-bit does not have openat64/fstatat64 */
 213     my_openat64_func = (openat64_func*)dlsym(RTLD_DEFAULT, "openat");
 214     my_fstatat64_func = (fstatat64_func*)dlsym(RTLD_DEFAULT, "fstatat");
 215 #else
 216     my_openat64_func = (openat64_func*) dlsym(RTLD_DEFAULT, "openat64");
 217     my_fstatat64_func = (fstatat64_func*) dlsym(RTLD_DEFAULT, "fstatat64");
 218 #endif
 219     my_unlinkat_func = (unlinkat_func*) dlsym(RTLD_DEFAULT, "unlinkat");
 220     my_renameat_func = (renameat_func*) dlsym(RTLD_DEFAULT, "renameat");
 221     my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
 222     my_fdopendir_func = (fdopendir_func*) dlsym(RTLD_DEFAULT, "fdopendir");
 223 
 224 #if defined(FSTATAT64_SYSCALL_AVAILABLE)
 225     /* fstatat64 missing from glibc */
 226     if (my_fstatat64_func == NULL)
 227         my_fstatat64_func = (fstatat64_func*)&fstatat64_wrapper;
 228 #endif


 246     char* cwd = getcwd(buf, sizeof(buf));
 247     if (cwd == NULL) {
 248         throwUnixException(env, errno);
 249     } else {
 250         jsize len = (jsize)strlen(buf);
 251         result = (*env)->NewByteArray(env, len);
 252         if (result != NULL) {
 253             (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)buf);
 254         }
 255     }
 256     return result;
 257 }
 258 
 259 JNIEXPORT jbyteArray
 260 Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
 261 {
 262     char* msg;
 263     jsize len;
 264     jbyteArray bytes;
 265 





 266     msg = strerror((int)error);

 267     len = strlen(msg);
 268     bytes = (*env)->NewByteArray(env, len);
 269     if (bytes != NULL) {
 270         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
 271     }
 272     return bytes;
 273 }
 274 
 275 JNIEXPORT jint
 276 Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
 277 
 278     int res = -1;
 279 
 280     RESTARTABLE(dup((int)fd), res);
 281     if (res == -1) {
 282         throwUnixException(env, errno);
 283     }
 284     return (jint)res;
 285 }
 286 


 533 JNIEXPORT void JNICALL
 534 Java_sun_nio_fs_UnixNativeDispatcher_utimes0(JNIEnv* env, jclass this,
 535     jlong pathAddress, jlong accessTime, jlong modificationTime)
 536 {
 537     int err;
 538     struct timeval times[2];
 539     const char* path = (const char*)jlong_to_ptr(pathAddress);
 540 
 541     times[0].tv_sec = accessTime / 1000000;
 542     times[0].tv_usec = accessTime % 1000000;
 543 
 544     times[1].tv_sec = modificationTime / 1000000;
 545     times[1].tv_usec = modificationTime % 1000000;
 546 
 547     RESTARTABLE(utimes(path, &times[0]), err);
 548     if (err == -1) {
 549         throwUnixException(env, errno);
 550     }
 551 }
 552 

 553 JNIEXPORT void JNICALL
 554 Java_sun_nio_fs_UnixNativeDispatcher_futimes(JNIEnv* env, jclass this, jint filedes,
 555     jlong accessTime, jlong modificationTime)
 556 {
 557     struct timeval times[2];
 558     int err = 0;
 559 
 560     times[0].tv_sec = accessTime / 1000000;
 561     times[0].tv_usec = accessTime % 1000000;
 562 
 563     times[1].tv_sec = modificationTime / 1000000;
 564     times[1].tv_usec = modificationTime % 1000000;
 565 
 566 #ifdef _ALLBSD_SOURCE
 567     RESTARTABLE(futimes(filedes, &times[0]), err);
 568 #else
 569     if (my_futimesat_func == NULL) {
 570         JNU_ThrowInternalError(env, "my_ftimesat_func is NULL");
 571         return;
 572     }


 573     RESTARTABLE((*my_futimesat_func)(filedes, NULL, &times[0]), err);
 574 #endif
 575     if (err == -1) {
 576         throwUnixException(env, errno);
 577     }





















 578 }
 579 
 580 JNIEXPORT jlong JNICALL
 581 Java_sun_nio_fs_UnixNativeDispatcher_opendir0(JNIEnv* env, jclass this,
 582     jlong pathAddress)
 583 {
 584     DIR* dir;
 585     const char* path = (const char*)jlong_to_ptr(pathAddress);
 586 
 587     /* EINTR not listed as a possible error */
 588     dir = opendir(path);
 589     if (dir == NULL) {
 590         throwUnixException(env, errno);
 591     }
 592     return ptr_to_jlong(dir);
 593 }
 594 
 595 JNIEXPORT jlong JNICALL
 596 Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
 597     DIR* dir;


 609     return ptr_to_jlong(dir);
 610 }
 611 
 612 JNIEXPORT void JNICALL
 613 Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {
 614     DIR* dirp = jlong_to_ptr(dir);
 615 
 616     if (closedir(dirp) == -1 && errno != EINTR) {
 617         throwUnixException(env, errno);
 618     }
 619 }
 620 
 621 JNIEXPORT jbyteArray JNICALL
 622 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
 623     struct dirent64* result;
 624     struct {
 625         struct dirent64 buf;
 626         char name_extra[PATH_MAX + 1 - sizeof result->d_name];
 627     } entry;
 628     struct dirent64* ptr = &entry.buf;

 629     int res;
 630     DIR* dirp = jlong_to_ptr(value);
 631 
 632     /* EINTR not listed as a possible error */
 633     /* TDB: reentrant version probably not required here */
 634     res = readdir64_r(dirp, ptr, &result);








 635     if (res != 0) {
 636         throwUnixException(env, res);
 637         return NULL;
 638     } else {
 639         if (result == NULL) {
 640             return NULL;
 641         } else {
 642             jsize len = strlen(ptr->d_name);
 643             jbyteArray bytes = (*env)->NewByteArray(env, len);
 644             if (bytes != NULL) {
 645                 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
 646             }
 647             return bytes;
 648         }
 649     }
 650 }
 651 
 652 JNIEXPORT void JNICALL
 653 Java_sun_nio_fs_UnixNativeDispatcher_mkdir0(JNIEnv* env, jclass this,
 654     jlong pathAddress, jint mode)


 818 
 819     RESTARTABLE(access(path, (int)amode), err);
 820     if (err == -1) {
 821         throwUnixException(env, errno);
 822     }
 823 }
 824 
 825 JNIEXPORT void JNICALL
 826 Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
 827     jlong pathAddress, jobject attrs)
 828 {
 829     int err;
 830     struct statvfs64 buf;
 831     const char* path = (const char*)jlong_to_ptr(pathAddress);
 832 
 833 
 834     RESTARTABLE(statvfs64(path, &buf), err);
 835     if (err == -1) {
 836         throwUnixException(env, errno);
 837     } else {











 838         (*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
 839         (*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
 840         (*env)->SetLongField(env, attrs, attrs_f_bfree,  long_to_jlong(buf.f_bfree));
 841         (*env)->SetLongField(env, attrs, attrs_f_bavail, long_to_jlong(buf.f_bavail));
 842     }
 843 }
 844 
 845 JNIEXPORT jlong JNICALL
 846 Java_sun_nio_fs_UnixNativeDispatcher_pathconf0(JNIEnv* env, jclass this,
 847     jlong pathAddress, jint name)
 848 {
 849     long err;
 850     const char* path = (const char*)jlong_to_ptr(pathAddress);
 851 
 852     err = pathconf(path, (int)name);
 853     if (err == -1) {
 854         throwUnixException(env, errno);
 855     }
 856     return (jlong)err;
 857 }


 894     if (buflen == -1)
 895         buflen = ENT_BUF_SIZE;
 896     pwbuf = (char*)malloc(buflen);
 897     if (pwbuf == NULL) {
 898         JNU_ThrowOutOfMemoryError(env, "native heap");
 899     } else {
 900         struct passwd pwent;
 901         struct passwd* p = NULL;
 902         int res = 0;
 903 
 904         errno = 0;
 905         #ifdef __solaris__
 906             RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
 907         #else
 908             RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
 909         #endif
 910 
 911         if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
 912             /* not found or error */
 913             if (errno == 0)




 914                 errno = ENOENT;

 915             throwUnixException(env, errno);
 916         } else {
 917             jsize len = strlen(p->pw_name);
 918             result = (*env)->NewByteArray(env, len);
 919             if (result != NULL) {
 920                 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
 921             }
 922         }
 923         free(pwbuf);
 924     }
 925 
 926     return result;
 927 }
 928 
 929 
 930 JNIEXPORT jbyteArray JNICALL
 931 Java_sun_nio_fs_UnixNativeDispatcher_getgrgid(JNIEnv* env, jclass this, jint gid)
 932 {
 933     jbyteArray result = NULL;
 934     int buflen;


 949             JNU_ThrowOutOfMemoryError(env, "native heap");
 950             return NULL;
 951         }
 952 
 953         errno = 0;
 954         #ifdef __solaris__
 955             RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
 956         #else
 957             RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
 958         #endif
 959 
 960         retry = 0;
 961         if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
 962             /* not found or error */
 963             if (errno == ERANGE) {
 964                 /* insufficient buffer size so need larger buffer */
 965                 buflen += ENT_BUF_SIZE;
 966                 retry = 1;
 967             } else {
 968                 if (errno == 0)




 969                     errno = ENOENT;

 970                 throwUnixException(env, errno);
 971             }
 972         } else {
 973             jsize len = strlen(g->gr_name);
 974             result = (*env)->NewByteArray(env, len);
 975             if (result != NULL) {
 976                 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
 977             }
 978         }
 979 
 980         free(grbuf);
 981 
 982     } while (retry);
 983 
 984     return result;
 985 }
 986 
 987 JNIEXPORT jint JNICALL
 988 Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0(JNIEnv* env, jclass this,
 989     jlong nameAddress)




  42 #include <strings.h>
  43 #endif
  44 
  45 #ifdef __linux__
  46 #include <string.h>
  47 #endif
  48 
  49 #ifdef _ALLBSD_SOURCE
  50 #include <string.h>
  51 
  52 #define stat64 stat
  53 #define statvfs64 statvfs
  54 
  55 #define open64 open
  56 #define fstat64 fstat
  57 #define lstat64 lstat
  58 #define dirent64 dirent
  59 #define readdir64_r readdir_r
  60 #endif
  61 
  62 /* Needed for strerror */
  63 #if defined(_AIX) || defined (__hpux__)
  64 #include <string.h>
  65 #endif
  66 
  67 #include "jni.h"
  68 #include "jni_util.h"
  69 #include "jlong.h"
  70 
  71 #include "sun_nio_fs_UnixNativeDispatcher.h"
  72 
  73 /**
  74  * Size of password or group entry when not available via sysconf
  75  */
  76 #define ENT_BUF_SIZE   1024
  77 
  78 #define RESTARTABLE(_cmd, _result) do { \
  79   do { \
  80     _result = _cmd; \
  81   } while((_result == -1) && (errno == EINTR)); \
  82 } while(0)
  83 
  84 #define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
  85   do { \
  86     _result = _cmd; \


  93 static jfieldID attrs_st_rdev;
  94 static jfieldID attrs_st_nlink;
  95 static jfieldID attrs_st_uid;
  96 static jfieldID attrs_st_gid;
  97 static jfieldID attrs_st_size;
  98 static jfieldID attrs_st_atime;
  99 static jfieldID attrs_st_mtime;
 100 static jfieldID attrs_st_ctime;
 101 
 102 static jfieldID attrs_f_frsize;
 103 static jfieldID attrs_f_blocks;
 104 static jfieldID attrs_f_bfree;
 105 static jfieldID attrs_f_bavail;
 106 
 107 static jfieldID entry_name;
 108 static jfieldID entry_dir;
 109 static jfieldID entry_fstype;
 110 static jfieldID entry_options;
 111 static jfieldID entry_dev;
 112 
 113 /* AIX and HP-UX need a couple more references for futimes emulation */
 114 #if defined(_AIX) || defined (__hpux__)
 115 static jmethodID disp_copy2buf;
 116 static jfieldID buffer_address;
 117 static jmethodID buffer_release;
 118 #endif
 119 
 120 /**
 121  * System calls that may not be available at run time.
 122  */
 123 typedef int openat64_func(int, const char *, int, ...);
 124 typedef int fstatat64_func(int, const char *, struct stat64 *, int);
 125 typedef int unlinkat_func(int, const char*, int);
 126 typedef int renameat_func(int, const char*, int, const char*);
 127 typedef int futimesat_func(int, const char *, const struct timeval *);
 128 typedef DIR* fdopendir_func(int);
 129 
 130 static openat64_func* my_openat64_func = NULL;
 131 static fstatat64_func* my_fstatat64_func = NULL;
 132 static unlinkat_func* my_unlinkat_func = NULL;
 133 static renameat_func* my_renameat_func = NULL;
 134 static futimesat_func* my_futimesat_func = NULL;
 135 static fdopendir_func* my_fdopendir_func = NULL;
 136 
 137 /**
 138  * fstatat missing from glibc on Linux. Temporary workaround
 139  * for x86/x64.


 201 
 202     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
 203     if (clazz == NULL) {
 204         return 0;
 205     }
 206     attrs_f_frsize = (*env)->GetFieldID(env, clazz, "f_frsize", "J");
 207     attrs_f_blocks = (*env)->GetFieldID(env, clazz, "f_blocks", "J");
 208     attrs_f_bfree = (*env)->GetFieldID(env, clazz, "f_bfree", "J");
 209     attrs_f_bavail = (*env)->GetFieldID(env, clazz, "f_bavail", "J");
 210 
 211     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
 212     if (clazz == NULL) {
 213         return 0;
 214     }
 215     entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
 216     entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
 217     entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
 218     entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
 219     entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
 220 
 221     /* AIX and HP-UX need a couple more references for futimes emulation */
 222 #if defined(_AIX) || defined (__hpux__)
 223     disp_copy2buf = (*env)->GetStaticMethodID(env, this, "copyToNativeBuffer", "(Lsun/nio/fs/UnixPath;)Lsun/nio/fs/NativeBuffer;");
 224     clazz = (*env)->FindClass(env, "sun/nio/fs/NativeBuffer");
 225     if (clazz == NULL) {
 226         return 0;
 227     }
 228     buffer_address = (*env)->GetFieldID(env, clazz, "address", "J");
 229     buffer_release = (*env)->GetMethodID(env, clazz, "release", "()V");
 230 #endif
 231 
 232     /* system calls that might not be available at run time */
 233 
 234 #if (defined(__solaris__) && defined(_LP64)) || defined(_ALLBSD_SOURCE)
 235     /* Solaris 64-bit does not have openat64/fstatat64 */
 236     my_openat64_func = (openat64_func*)dlsym(RTLD_DEFAULT, "openat");
 237     my_fstatat64_func = (fstatat64_func*)dlsym(RTLD_DEFAULT, "fstatat");
 238 #else
 239     my_openat64_func = (openat64_func*) dlsym(RTLD_DEFAULT, "openat64");
 240     my_fstatat64_func = (fstatat64_func*) dlsym(RTLD_DEFAULT, "fstatat64");
 241 #endif
 242     my_unlinkat_func = (unlinkat_func*) dlsym(RTLD_DEFAULT, "unlinkat");
 243     my_renameat_func = (renameat_func*) dlsym(RTLD_DEFAULT, "renameat");
 244     my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
 245     my_fdopendir_func = (fdopendir_func*) dlsym(RTLD_DEFAULT, "fdopendir");
 246 
 247 #if defined(FSTATAT64_SYSCALL_AVAILABLE)
 248     /* fstatat64 missing from glibc */
 249     if (my_fstatat64_func == NULL)
 250         my_fstatat64_func = (fstatat64_func*)&fstatat64_wrapper;
 251 #endif


 269     char* cwd = getcwd(buf, sizeof(buf));
 270     if (cwd == NULL) {
 271         throwUnixException(env, errno);
 272     } else {
 273         jsize len = (jsize)strlen(buf);
 274         result = (*env)->NewByteArray(env, len);
 275         if (result != NULL) {
 276             (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)buf);
 277         }
 278     }
 279     return result;
 280 }
 281 
 282 JNIEXPORT jbyteArray
 283 Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
 284 {
 285     char* msg;
 286     jsize len;
 287     jbyteArray bytes;
 288 
 289     /* strerror is not thread-safe on AIX */
 290 #ifdef _AIX
 291     char buffer[256];
 292     msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r";
 293 #else
 294     msg = strerror((int)error);
 295 #endif
 296     len = strlen(msg);
 297     bytes = (*env)->NewByteArray(env, len);
 298     if (bytes != NULL) {
 299         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
 300     }
 301     return bytes;
 302 }
 303 
 304 JNIEXPORT jint
 305 Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
 306 
 307     int res = -1;
 308 
 309     RESTARTABLE(dup((int)fd), res);
 310     if (res == -1) {
 311         throwUnixException(env, errno);
 312     }
 313     return (jint)res;
 314 }
 315 


 562 JNIEXPORT void JNICALL
 563 Java_sun_nio_fs_UnixNativeDispatcher_utimes0(JNIEnv* env, jclass this,
 564     jlong pathAddress, jlong accessTime, jlong modificationTime)
 565 {
 566     int err;
 567     struct timeval times[2];
 568     const char* path = (const char*)jlong_to_ptr(pathAddress);
 569 
 570     times[0].tv_sec = accessTime / 1000000;
 571     times[0].tv_usec = accessTime % 1000000;
 572 
 573     times[1].tv_sec = modificationTime / 1000000;
 574     times[1].tv_usec = modificationTime % 1000000;
 575 
 576     RESTARTABLE(utimes(path, &times[0]), err);
 577     if (err == -1) {
 578         throwUnixException(env, errno);
 579     }
 580 }
 581 
 582 /* Added path of file "filedes" for platform ports (only needed on AIX and HPUX) */
 583 JNIEXPORT void JNICALL
 584 Java_sun_nio_fs_UnixNativeDispatcher_futimes(JNIEnv* env, jclass this, jint filedes,
 585     jlong accessTime, jlong modificationTime, jobject path)
 586 {
 587     struct timeval times[2];
 588     int err = 0;
 589 
 590     times[0].tv_sec = accessTime / 1000000;
 591     times[0].tv_usec = accessTime % 1000000;
 592 
 593     times[1].tv_sec = modificationTime / 1000000;
 594     times[1].tv_usec = modificationTime % 1000000;
 595 
 596 #ifdef _ALLBSD_SOURCE
 597     RESTARTABLE(futimes(filedes, &times[0]), err);
 598 
 599     if (err == -1) {
 600         throwUnixException(env, errno);

 601     }
 602 #else
 603     if (my_futimesat_func != NULL) {
 604         RESTARTABLE((*my_futimesat_func)(filedes, NULL, &times[0]), err);
 605 
 606         if (err == -1) {
 607             throwUnixException(env, errno);
 608         }
 609     }
 610     /* AIX and HP-UX does not provide futimes as system call => use utimes instead */
 611 #if defined(_AIX) || defined (__hpux__)
 612     else {
 613         jobject buffer = (*env)->CallStaticObjectMethod(env, this, disp_copy2buf, path);
 614         jlong path_address = (*env)->GetLongField(env, buffer, buffer_address);
 615         const char* path = (const char*)jlong_to_ptr(path_address);
 616         RESTARTABLE(utimes(path, &times[0]), err);
 617         if (err == -1) {
 618             throwUnixException(env, errno);
 619         }
 620         (*env)->CallVoidMethod(env, buffer, buffer_release);
 621     }
 622 #else
 623     else {
 624         JNU_ThrowInternalError(env, "my_ftimesat_func is NULL");
 625         return;
 626     }
 627 #endif
 628 
 629 #endif
 630 }
 631 
 632 JNIEXPORT jlong JNICALL
 633 Java_sun_nio_fs_UnixNativeDispatcher_opendir0(JNIEnv* env, jclass this,
 634     jlong pathAddress)
 635 {
 636     DIR* dir;
 637     const char* path = (const char*)jlong_to_ptr(pathAddress);
 638 
 639     /* EINTR not listed as a possible error */
 640     dir = opendir(path);
 641     if (dir == NULL) {
 642         throwUnixException(env, errno);
 643     }
 644     return ptr_to_jlong(dir);
 645 }
 646 
 647 JNIEXPORT jlong JNICALL
 648 Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
 649     DIR* dir;


 661     return ptr_to_jlong(dir);
 662 }
 663 
 664 JNIEXPORT void JNICALL
 665 Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {
 666     DIR* dirp = jlong_to_ptr(dir);
 667 
 668     if (closedir(dirp) == -1 && errno != EINTR) {
 669         throwUnixException(env, errno);
 670     }
 671 }
 672 
 673 JNIEXPORT jbyteArray JNICALL
 674 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
 675     struct dirent64* result;
 676     struct {
 677         struct dirent64 buf;
 678         char name_extra[PATH_MAX + 1 - sizeof result->d_name];
 679     } entry;
 680     struct dirent64* ptr = &entry.buf;
 681 
 682     int res;
 683     DIR* dirp = jlong_to_ptr(value);
 684 
 685     /* EINTR not listed as a possible error */
 686     /* TDB: reentrant version probably not required here */
 687     res = readdir64_r(dirp, ptr, &result);
 688 
 689     /* AIX returns EBADF for directory stream end which is no error. */
 690 #ifdef _AIX
 691     if (res != 0) {
 692         res = (result == NULL && res == EBADF) ? 0 : errno;
 693     }
 694 #endif
 695 
 696     if (res != 0) {
 697         throwUnixException(env, res);
 698         return NULL;
 699     } else {
 700         if (result == NULL) {
 701             return NULL;
 702         } else {
 703             jsize len = strlen(ptr->d_name);
 704             jbyteArray bytes = (*env)->NewByteArray(env, len);
 705             if (bytes != NULL) {
 706                 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
 707             }
 708             return bytes;
 709         }
 710     }
 711 }
 712 
 713 JNIEXPORT void JNICALL
 714 Java_sun_nio_fs_UnixNativeDispatcher_mkdir0(JNIEnv* env, jclass this,
 715     jlong pathAddress, jint mode)


 879 
 880     RESTARTABLE(access(path, (int)amode), err);
 881     if (err == -1) {
 882         throwUnixException(env, errno);
 883     }
 884 }
 885 
 886 JNIEXPORT void JNICALL
 887 Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
 888     jlong pathAddress, jobject attrs)
 889 {
 890     int err;
 891     struct statvfs64 buf;
 892     const char* path = (const char*)jlong_to_ptr(pathAddress);
 893 
 894 
 895     RESTARTABLE(statvfs64(path, &buf), err);
 896     if (err == -1) {
 897         throwUnixException(env, errno);
 898     } else {
 899         /* Number of blocks (f_blocks) may be too big for signed long on AIX for /proc. */
 900 #ifdef _AIX
 901         if (buf.f_blocks == ULONG_MAX) {
 902             buf.f_blocks = 0;
 903         }
 904         /* Number of free or available blocks can never exceed total number of blocks (seen on /QOpt as400) */
 905         if (buf.f_blocks == 0) {
 906                 buf.f_bfree = 0;
 907             buf.f_bavail = 0;
 908         }
 909 #endif
 910         (*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
 911         (*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
 912         (*env)->SetLongField(env, attrs, attrs_f_bfree,  long_to_jlong(buf.f_bfree));
 913         (*env)->SetLongField(env, attrs, attrs_f_bavail, long_to_jlong(buf.f_bavail));
 914     }
 915 }
 916 
 917 JNIEXPORT jlong JNICALL
 918 Java_sun_nio_fs_UnixNativeDispatcher_pathconf0(JNIEnv* env, jclass this,
 919     jlong pathAddress, jint name)
 920 {
 921     long err;
 922     const char* path = (const char*)jlong_to_ptr(pathAddress);
 923 
 924     err = pathconf(path, (int)name);
 925     if (err == -1) {
 926         throwUnixException(env, errno);
 927     }
 928     return (jlong)err;
 929 }


 966     if (buflen == -1)
 967         buflen = ENT_BUF_SIZE;
 968     pwbuf = (char*)malloc(buflen);
 969     if (pwbuf == NULL) {
 970         JNU_ThrowOutOfMemoryError(env, "native heap");
 971     } else {
 972         struct passwd pwent;
 973         struct passwd* p = NULL;
 974         int res = 0;
 975 
 976         errno = 0;
 977         #ifdef __solaris__
 978             RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
 979         #else
 980             RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
 981         #endif
 982 
 983         if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
 984             /* not found or error */
 985             if (errno == 0)
 986                 /* getpwuid_r returns ESRCH if user does not exist on AIX */
 987 #ifdef _AIX
 988                 errno = ESRCH;
 989 #else
 990                 errno = ENOENT;
 991 #endif
 992             throwUnixException(env, errno);
 993         } else {
 994             jsize len = strlen(p->pw_name);
 995             result = (*env)->NewByteArray(env, len);
 996             if (result != NULL) {
 997                 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
 998             }
 999         }
1000         free(pwbuf);
1001     }
1002 
1003     return result;
1004 }
1005 
1006 
1007 JNIEXPORT jbyteArray JNICALL
1008 Java_sun_nio_fs_UnixNativeDispatcher_getgrgid(JNIEnv* env, jclass this, jint gid)
1009 {
1010     jbyteArray result = NULL;
1011     int buflen;


1026             JNU_ThrowOutOfMemoryError(env, "native heap");
1027             return NULL;
1028         }
1029 
1030         errno = 0;
1031         #ifdef __solaris__
1032             RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
1033         #else
1034             RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
1035         #endif
1036 
1037         retry = 0;
1038         if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
1039             /* not found or error */
1040             if (errno == ERANGE) {
1041                 /* insufficient buffer size so need larger buffer */
1042                 buflen += ENT_BUF_SIZE;
1043                 retry = 1;
1044             } else {
1045                 if (errno == 0)
1046                     /* getgrgid_r returns ESRCH if group does not exist on AIX */
1047 #ifdef _AIX
1048                     errno = ESRCH;
1049 #else
1050                     errno = ENOENT;
1051 #endif
1052                 throwUnixException(env, errno);
1053             }
1054         } else {
1055             jsize len = strlen(g->gr_name);
1056             result = (*env)->NewByteArray(env, len);
1057             if (result != NULL) {
1058                 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
1059             }
1060         }
1061 
1062         free(grbuf);
1063 
1064     } while (retry);
1065 
1066     return result;
1067 }
1068 
1069 JNIEXPORT jint JNICALL
1070 Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0(JNIEnv* env, jclass this,
1071     jlong nameAddress)


< prev index next >