30 #include <unistd.h>
31
32 #if defined(__linux__) || defined(__solaris__)
33 #include <sys/sendfile.h>
34 #elif defined(_AIX)
35 #include <sys/socket.h>
36 #elif defined(_ALLBSD_SOURCE)
37 #include <sys/socket.h>
38 #include <sys/uio.h>
39 #define lseek64 lseek
40 #define mmap64 mmap
41 #endif
42
43 #include "jni.h"
44 #include "jni_util.h"
45 #include "jlong.h"
46 #include "nio.h"
47 #include "nio_util.h"
48 #include "sun_nio_ch_FileChannelImpl.h"
49 #include "java_lang_Integer.h"
50
51 static jfieldID chan_fd; /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
52
53 JNIEXPORT jlong JNICALL
54 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
55 {
56 jlong pageSize = sysconf(_SC_PAGESIZE);
57 chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
58 return pageSize;
59 }
60
61 static jlong
62 handle(JNIEnv *env, jlong rv, char *msg)
63 {
64 if (rv >= 0)
65 return rv;
66 if (errno == EINTR)
67 return IOS_INTERRUPTED;
68 JNU_ThrowIOExceptionWithLastError(env, msg);
69 return IOS_THROWN;
70 }
71
72
73 JNIEXPORT jlong JNICALL
74 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
75 jint prot, jlong off, jlong len)
76 {
77 void *mapAddress = 0;
78 jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
79 jint fd = fdval(env, fdo);
80 int protections = 0;
81 int flags = 0;
82
83 if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
84 protections = PROT_READ;
85 flags = MAP_SHARED;
86 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
87 protections = PROT_WRITE | PROT_READ;
88 flags = MAP_SHARED;
89 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
90 protections = PROT_WRITE | PROT_READ;
91 flags = MAP_PRIVATE;
92 }
93
94 mapAddress = mmap64(
95 0, /* Let OS decide location */
96 len, /* Number of bytes to map */
97 protections, /* File permissions */
98 flags, /* Changes are shared */
99 fd, /* File descriptor of mapped file */
100 off); /* Offset into file */
101
102 if (mapAddress == MAP_FAILED) {
103 if (errno == ENOMEM) {
104 JNU_ThrowOutOfMemoryError(env, "Map failed");
105 return IOS_THROWN;
106 }
107 return handle(env, -1, "Map failed");
108 }
109
110 return ((jlong) (unsigned long) mapAddress);
111 }
112
113
114 JNIEXPORT jint JNICALL
115 Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
116 jlong address, jlong len)
117 {
118 void *a = (void *)jlong_to_ptr(address);
119 return handle(env,
120 munmap(a, (size_t)len),
121 "Unmap failed");
122 }
|
30 #include <unistd.h>
31
32 #if defined(__linux__) || defined(__solaris__)
33 #include <sys/sendfile.h>
34 #elif defined(_AIX)
35 #include <sys/socket.h>
36 #elif defined(_ALLBSD_SOURCE)
37 #include <sys/socket.h>
38 #include <sys/uio.h>
39 #define lseek64 lseek
40 #define mmap64 mmap
41 #endif
42
43 #include "jni.h"
44 #include "jni_util.h"
45 #include "jlong.h"
46 #include "nio.h"
47 #include "nio_util.h"
48 #include "sun_nio_ch_FileChannelImpl.h"
49 #include "java_lang_Integer.h"
50 #include <assert.h>
51
52 static jfieldID chan_fd; /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
53
54 JNIEXPORT jlong JNICALL
55 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
56 {
57 jlong pageSize = sysconf(_SC_PAGESIZE);
58 chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
59 return pageSize;
60 }
61
62 static jlong
63 handle(JNIEnv *env, jlong rv, char *msg)
64 {
65 if (rv >= 0)
66 return rv;
67 if (errno == EINTR)
68 return IOS_INTERRUPTED;
69 JNU_ThrowIOExceptionWithLastError(env, msg);
70 return IOS_THROWN;
71 }
72
73
74 JNIEXPORT jlong JNICALL
75 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
76 jint prot, jlong off, jlong len, jboolean map_sync)
77 {
78 void *mapAddress = 0;
79 jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
80 jint fd = fdval(env, fdo);
81 int protections = 0;
82 int flags = 0;
83
84 // should never be called with map_sync and prot == PRIVATE
85 assert((prot != sun_nio_ch_FileChannelImpl_MAP_PV) ||! map_sync);
86
87 if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
88 protections = PROT_READ;
89 flags = MAP_SHARED;
90 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
91 protections = PROT_WRITE | PROT_READ;
92 flags = MAP_SHARED;
93 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
94 protections = PROT_WRITE | PROT_READ;
95 flags = MAP_PRIVATE;
96 }
97
98 // if MAP_SYNC and MAP_SHARED_VALIDATE are not defined then it is
99 // best to define them here. This ensures the code compiles on old
100 // OS releases which do not provide the relevant headers. If run
101 // on the same machine then it will work if the kernel contains
102 // the necessary support otherwise mmap should fail with an
103 // invalid argument error
104
105 #ifndef MAP_SYNC
106 #define MAP_SYNC 0x80000
107 #endif
108 #ifndef MAP_SHARED_VALIDATE
109 #define MAP_SHARED_VALIDATE 0x03
110 #endif
111
112 if (map_sync) {
113 // ensure
114 // 1) this is Linux on AArch64 or x86_64
115 // 2) the mmap APIs are available/ at compile time
116 #if !defined(LINUX) || ! (defined(aarch64) || (defined(amd64) && defined(_LP64)))
117 // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
118 JNU_ThrowIOException(env, "map_persistent is not implemented");
119 return IOS_THROWN;
120 #else
121 flags |= MAP_SYNC | MAP_SHARED_VALIDATE;
122 #endif
123 }
124
125 mapAddress = mmap64(
126 0, /* Let OS decide location */
127 len, /* Number of bytes to map */
128 protections, /* File permissions */
129 flags, /* Changes are shared */
130 fd, /* File descriptor of mapped file */
131 off); /* Offset into file */
132
133 if (mapAddress == MAP_FAILED) {
134 if (map_sync && errno == ENOTSUP) {
135 JNU_ThrowIOExceptionWithLastError(env, "map_persistent is not supported");
136 return IOS_THROWN;
137 }
138
139 if (errno == ENOMEM) {
140 JNU_ThrowOutOfMemoryError(env, "Map failed");
141 return IOS_THROWN;
142 }
143 return handle(env, -1, "Map failed");
144 }
145
146 return ((jlong) (unsigned long) mapAddress);
147 }
148
149
150 JNIEXPORT jint JNICALL
151 Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
152 jlong address, jlong len)
153 {
154 void *a = (void *)jlong_to_ptr(address);
155 return handle(env,
156 munmap(a, (size_t)len),
157 "Unmap failed");
158 }
|