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