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)
|