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

Print this page
rev 8725 : 8024854: Basic changes and files to build the class library on AIX
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan


  25 
  26 #include <stdio.h>
  27 #include <stdlib.h>
  28 #include <limits.h>
  29 #include <fcntl.h>
  30 #include <dirent.h>
  31 #include <unistd.h>
  32 #include <pwd.h>
  33 #include <grp.h>
  34 #include <errno.h>
  35 #include <dlfcn.h>
  36 #include <sys/types.h>
  37 #include <sys/stat.h>
  38 #include <sys/statvfs.h>
  39 #include <sys/time.h>
  40 
  41 #ifdef __solaris__
  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 


 277     char* cwd = getcwd(buf, sizeof(buf));
 278     if (cwd == NULL) {
 279         throwUnixException(env, errno);
 280     } else {
 281         jsize len = (jsize)strlen(buf);
 282         result = (*env)->NewByteArray(env, len);
 283         if (result != NULL) {
 284             (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)buf);
 285         }
 286     }
 287     return result;
 288 }
 289 
 290 JNIEXPORT jbyteArray
 291 Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
 292 {
 293     char* msg;
 294     jsize len;
 295     jbyteArray bytes;
 296 





 297     msg = strerror((int)error);

 298     len = strlen(msg);
 299     bytes = (*env)->NewByteArray(env, len);
 300     if (bytes != NULL) {
 301         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
 302     }
 303     return bytes;
 304 }
 305 
 306 JNIEXPORT jint
 307 Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
 308 
 309     int res = -1;
 310 
 311     RESTARTABLE(dup((int)fd), res);
 312     if (fd == -1) {
 313         throwUnixException(env, errno);
 314     }
 315     return (jint)res;
 316 }
 317 


 657     RESTARTABLE(closedir(dirp), err);
 658     if (errno == -1) {
 659         throwUnixException(env, errno);
 660     }
 661 }
 662 
 663 JNIEXPORT jbyteArray JNICALL
 664 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
 665     struct dirent64* result;
 666     struct {
 667         struct dirent64 buf;
 668         char name_extra[PATH_MAX + 1 - sizeof result->d_name];
 669     } entry;
 670     struct dirent64* ptr = &entry.buf;
 671     int res;
 672     DIR* dirp = jlong_to_ptr(value);
 673 
 674     /* EINTR not listed as a possible error */
 675     /* TDB: reentrant version probably not required here */
 676     res = readdir64_r(dirp, ptr, &result);









 677     if (res != 0) {
 678         throwUnixException(env, res);
 679         return NULL;
 680     } else {
 681         if (result == NULL) {
 682             return NULL;
 683         } else {
 684             jsize len = strlen(ptr->d_name);
 685             jbyteArray bytes = (*env)->NewByteArray(env, len);
 686             if (bytes != NULL) {
 687                 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
 688             }
 689             return bytes;
 690         }
 691     }
 692 }
 693 
 694 JNIEXPORT void JNICALL
 695 Java_sun_nio_fs_UnixNativeDispatcher_mkdir0(JNIEnv* env, jclass this,
 696     jlong pathAddress, jint mode)


 860 
 861     RESTARTABLE(access(path, (int)amode), err);
 862     if (err == -1) {
 863         throwUnixException(env, errno);
 864     }
 865 }
 866 
 867 JNIEXPORT void JNICALL
 868 Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
 869     jlong pathAddress, jobject attrs)
 870 {
 871     int err;
 872     struct statvfs64 buf;
 873     const char* path = (const char*)jlong_to_ptr(pathAddress);
 874 
 875 
 876     RESTARTABLE(statvfs64(path, &buf), err);
 877     if (err == -1) {
 878         throwUnixException(env, errno);
 879     } else {












 880         (*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
 881         (*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
 882         (*env)->SetLongField(env, attrs, attrs_f_bfree,  long_to_jlong(buf.f_bfree));
 883         (*env)->SetLongField(env, attrs, attrs_f_bavail, long_to_jlong(buf.f_bavail));
 884     }
 885 }
 886 
 887 JNIEXPORT jlong JNICALL
 888 Java_sun_nio_fs_UnixNativeDispatcher_pathconf0(JNIEnv* env, jclass this,
 889     jlong pathAddress, jint name)
 890 {
 891     long err;
 892     const char* path = (const char*)jlong_to_ptr(pathAddress);
 893 
 894     err = pathconf(path, (int)name);
 895     if (err == -1) {
 896         throwUnixException(env, errno);
 897     }
 898     return (jlong)err;
 899 }


 936     if (buflen == -1)
 937         buflen = ENT_BUF_SIZE;
 938     pwbuf = (char*)malloc(buflen);
 939     if (pwbuf == NULL) {
 940         JNU_ThrowOutOfMemoryError(env, "native heap");
 941     } else {
 942         struct passwd pwent;
 943         struct passwd* p = NULL;
 944         int res = 0;
 945 
 946         errno = 0;
 947         #ifdef __solaris__
 948             RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
 949         #else
 950             RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
 951         #endif
 952 
 953         if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
 954             /* not found or error */
 955             if (errno == 0)




 956                 errno = ENOENT;

 957             throwUnixException(env, errno);
 958         } else {
 959             jsize len = strlen(p->pw_name);
 960             result = (*env)->NewByteArray(env, len);
 961             if (result != NULL) {
 962                 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
 963             }
 964         }
 965         free(pwbuf);
 966     }
 967 
 968     return result;
 969 }
 970 
 971 
 972 JNIEXPORT jbyteArray JNICALL
 973 Java_sun_nio_fs_UnixNativeDispatcher_getgrgid(JNIEnv* env, jclass this, jint gid)
 974 {
 975     jbyteArray result = NULL;
 976     int buflen;


 991             JNU_ThrowOutOfMemoryError(env, "native heap");
 992             return NULL;
 993         }
 994 
 995         errno = 0;
 996         #ifdef __solaris__
 997             RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
 998         #else
 999             RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
1000         #endif
1001 
1002         retry = 0;
1003         if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
1004             /* not found or error */
1005             if (errno == ERANGE) {
1006                 /* insufficient buffer size so need larger buffer */
1007                 buflen += ENT_BUF_SIZE;
1008                 retry = 1;
1009             } else {
1010                 if (errno == 0)




1011                     errno = ENOENT;

1012                 throwUnixException(env, errno);
1013             }
1014         } else {
1015             jsize len = strlen(g->gr_name);
1016             result = (*env)->NewByteArray(env, len);
1017             if (result != NULL) {
1018                 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
1019             }
1020         }
1021 
1022         free(grbuf);
1023 
1024     } while (retry);
1025 
1026     return result;
1027 }
1028 
1029 JNIEXPORT jint JNICALL
1030 Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0(JNIEnv* env, jclass this,
1031     jlong nameAddress)




  25 
  26 #include <stdio.h>
  27 #include <stdlib.h>
  28 #include <limits.h>
  29 #include <fcntl.h>
  30 #include <dirent.h>
  31 #include <unistd.h>
  32 #include <pwd.h>
  33 #include <grp.h>
  34 #include <errno.h>
  35 #include <dlfcn.h>
  36 #include <sys/types.h>
  37 #include <sys/stat.h>
  38 #include <sys/statvfs.h>
  39 #include <sys/time.h>
  40 
  41 #ifdef __solaris__
  42 #include <strings.h>
  43 #endif
  44 
  45 #if defined(__linux__) || defined(_AIX)
  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 


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


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


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


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


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