1 /* |
1 /* |
2 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. |
2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Sun designates this |
7 * published by the Free Software Foundation. Sun designates this |
32 #include "nio_util.h" |
32 #include "nio_util.h" |
33 #include "sun_nio_ch_FileChannelImpl.h" |
33 #include "sun_nio_ch_FileChannelImpl.h" |
34 |
34 |
35 static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */ |
35 static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */ |
36 |
36 |
37 |
|
38 /* false for 95/98/ME, true for NT/W2K */ |
|
39 static jboolean onNT = JNI_FALSE; |
|
40 |
|
41 /************************************************************** |
37 /************************************************************** |
42 * static method to store field ID's in initializers |
38 * static method to store field ID's in initializers |
43 * and retrieve the allocation granularity |
39 * and retrieve the allocation granularity |
44 */ |
40 */ |
45 JNIEXPORT jlong JNICALL |
41 JNIEXPORT jlong JNICALL |
46 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz) |
42 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz) |
47 { |
43 { |
48 SYSTEM_INFO si; |
44 SYSTEM_INFO si; |
49 jint align; |
45 jint align; |
50 OSVERSIONINFO ver; |
|
51 GetSystemInfo(&si); |
46 GetSystemInfo(&si); |
52 align = si.dwAllocationGranularity; |
47 align = si.dwAllocationGranularity; |
53 chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;"); |
48 chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;"); |
54 ver.dwOSVersionInfoSize = sizeof(ver); |
|
55 GetVersionEx(&ver); |
|
56 if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) { |
|
57 onNT = JNI_TRUE; |
|
58 } |
|
59 return align; |
49 return align; |
60 } |
50 } |
61 |
51 |
62 |
52 |
63 /************************************************************** |
53 /************************************************************** |
144 return IOS_THROWN; |
134 return IOS_THROWN; |
145 } |
135 } |
146 return 0; |
136 return 0; |
147 } |
137 } |
148 |
138 |
149 JNIEXPORT jint JNICALL |
|
150 Java_sun_nio_ch_FileChannelImpl_truncate0(JNIEnv *env, jobject this, |
|
151 jobject fdo, jlong size) |
|
152 { |
|
153 DWORD lowPos = 0; |
|
154 long highPos = 0; |
|
155 BOOL result = 0; |
|
156 HANDLE h = (HANDLE)(handleval(env, fdo)); |
|
157 |
|
158 lowPos = (DWORD)size; |
|
159 highPos = (long)(size >> 32); |
|
160 lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN); |
|
161 if (lowPos == ((DWORD)-1)) { |
|
162 if (GetLastError() != ERROR_SUCCESS) { |
|
163 JNU_ThrowIOExceptionWithLastError(env, "Truncation failed"); |
|
164 return IOS_THROWN; |
|
165 } |
|
166 } |
|
167 result = SetEndOfFile(h); |
|
168 if (result == 0) { |
|
169 JNU_ThrowIOExceptionWithLastError(env, "Truncation failed"); |
|
170 return IOS_THROWN; |
|
171 } |
|
172 return 0; |
|
173 } |
|
174 |
|
175 |
|
176 JNIEXPORT jint JNICALL |
|
177 Java_sun_nio_ch_FileChannelImpl_force0(JNIEnv *env, jobject this, |
|
178 jobject fdo, jboolean md) |
|
179 { |
|
180 int result = 0; |
|
181 HANDLE h = (HANDLE)(handleval(env, fdo)); |
|
182 |
|
183 if (h != INVALID_HANDLE_VALUE) { |
|
184 result = FlushFileBuffers(h); |
|
185 if (result == 0) { |
|
186 int error = GetLastError(); |
|
187 if (error != ERROR_ACCESS_DENIED) { |
|
188 JNU_ThrowIOExceptionWithLastError(env, "Force failed"); |
|
189 return IOS_THROWN; |
|
190 } |
|
191 } |
|
192 } else { |
|
193 JNU_ThrowIOExceptionWithLastError(env, "Force failed"); |
|
194 return IOS_THROWN; |
|
195 } |
|
196 return 0; |
|
197 } |
|
198 |
|
199 JNIEXPORT jlong JNICALL |
139 JNIEXPORT jlong JNICALL |
200 Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this, |
140 Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this, |
201 jobject fdo, jlong offset) |
141 jobject fdo, jlong offset) |
202 { |
142 { |
203 DWORD lowPos = 0; |
143 DWORD lowPos = 0; |
218 } |
158 } |
219 } |
159 } |
220 return (((jlong)highPos) << 32) | lowPos; |
160 return (((jlong)highPos) << 32) | lowPos; |
221 } |
161 } |
222 |
162 |
223 JNIEXPORT jlong JNICALL |
|
224 Java_sun_nio_ch_FileChannelImpl_size0(JNIEnv *env, jobject this, jobject fdo) |
|
225 { |
|
226 DWORD sizeLow = 0; |
|
227 DWORD sizeHigh = 0; |
|
228 HANDLE h = (HANDLE)(handleval(env, fdo)); |
|
229 |
|
230 sizeLow = GetFileSize(h, &sizeHigh); |
|
231 if (sizeLow == ((DWORD)-1)) { |
|
232 if (GetLastError() != ERROR_SUCCESS) { |
|
233 JNU_ThrowIOExceptionWithLastError(env, "Size failed"); |
|
234 return IOS_THROWN; |
|
235 } |
|
236 } |
|
237 return (((jlong)sizeHigh) << 32) | sizeLow; |
|
238 } |
|
239 |
|
240 JNIEXPORT void JNICALL |
163 JNIEXPORT void JNICALL |
241 Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo) |
164 Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo) |
242 { |
165 { |
243 HANDLE h = (HANDLE)(handleval(env, fdo)); |
166 HANDLE h = (HANDLE)(handleval(env, fdo)); |
244 if (h != INVALID_HANDLE_VALUE) { |
167 if (h != INVALID_HANDLE_VALUE) { |
255 jlong position, jlong count, |
178 jlong position, jlong count, |
256 jint dstFD) |
179 jint dstFD) |
257 { |
180 { |
258 return IOS_UNSUPPORTED; |
181 return IOS_UNSUPPORTED; |
259 } |
182 } |
260 |
|
261 JNIEXPORT jint JNICALL |
|
262 Java_sun_nio_ch_FileChannelImpl_lock0(JNIEnv *env, jobject this, jobject fdo, |
|
263 jboolean block, jlong pos, jlong size, |
|
264 jboolean shared) |
|
265 { |
|
266 HANDLE h = (HANDLE)(handleval(env, fdo)); |
|
267 DWORD lowPos = (DWORD)pos; |
|
268 long highPos = (long)(pos >> 32); |
|
269 DWORD lowNumBytes = (DWORD)size; |
|
270 DWORD highNumBytes = (DWORD)(size >> 32); |
|
271 jint result = 0; |
|
272 if (onNT) { |
|
273 DWORD flags = 0; |
|
274 OVERLAPPED o; |
|
275 o.hEvent = 0; |
|
276 o.Offset = lowPos; |
|
277 o.OffsetHigh = highPos; |
|
278 if (block == JNI_FALSE) { |
|
279 flags |= LOCKFILE_FAIL_IMMEDIATELY; |
|
280 } |
|
281 if (shared == JNI_FALSE) { |
|
282 flags |= LOCKFILE_EXCLUSIVE_LOCK; |
|
283 } |
|
284 result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o); |
|
285 if (result == 0) { |
|
286 int error = GetLastError(); |
|
287 if (error != ERROR_LOCK_VIOLATION) { |
|
288 JNU_ThrowIOExceptionWithLastError(env, "Lock failed"); |
|
289 return sun_nio_ch_FileChannelImpl_NO_LOCK; |
|
290 } |
|
291 if (flags & LOCKFILE_FAIL_IMMEDIATELY) { |
|
292 return sun_nio_ch_FileChannelImpl_NO_LOCK; |
|
293 } |
|
294 JNU_ThrowIOExceptionWithLastError(env, "Lock failed"); |
|
295 return sun_nio_ch_FileChannelImpl_NO_LOCK; |
|
296 } |
|
297 return sun_nio_ch_FileChannelImpl_LOCKED; |
|
298 } else { |
|
299 for(;;) { |
|
300 if (size > 0x7fffffff) { |
|
301 size = 0x7fffffff; |
|
302 } |
|
303 lowNumBytes = (DWORD)size; |
|
304 highNumBytes = 0; |
|
305 result = LockFile(h, lowPos, highPos, lowNumBytes, highNumBytes); |
|
306 if (result != 0) { |
|
307 if (shared == JNI_TRUE) { |
|
308 return sun_nio_ch_FileChannelImpl_RET_EX_LOCK; |
|
309 } else { |
|
310 return sun_nio_ch_FileChannelImpl_LOCKED; |
|
311 } |
|
312 } else { |
|
313 int error = GetLastError(); |
|
314 if (error != ERROR_LOCK_VIOLATION) { |
|
315 JNU_ThrowIOExceptionWithLastError(env, "Lock failed"); |
|
316 return sun_nio_ch_FileChannelImpl_NO_LOCK; |
|
317 } |
|
318 if (block == JNI_FALSE) { |
|
319 return sun_nio_ch_FileChannelImpl_NO_LOCK; |
|
320 } |
|
321 } |
|
322 Sleep(100); |
|
323 } |
|
324 } |
|
325 return sun_nio_ch_FileChannelImpl_NO_LOCK; |
|
326 } |
|
327 |
|
328 JNIEXPORT void JNICALL |
|
329 Java_sun_nio_ch_FileChannelImpl_release0(JNIEnv *env, jobject this, |
|
330 jobject fdo, jlong pos, jlong size) |
|
331 { |
|
332 HANDLE h = (HANDLE)(handleval(env, fdo)); |
|
333 DWORD lowPos = (DWORD)pos; |
|
334 long highPos = (long)(pos >> 32); |
|
335 DWORD lowNumBytes = (DWORD)size; |
|
336 DWORD highNumBytes = (DWORD)(size >> 32); |
|
337 jint result = 0; |
|
338 if (onNT) { |
|
339 OVERLAPPED o; |
|
340 o.hEvent = 0; |
|
341 o.Offset = lowPos; |
|
342 o.OffsetHigh = highPos; |
|
343 result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o); |
|
344 } else { |
|
345 if (size > 0x7fffffff) { |
|
346 size = 0x7fffffff; |
|
347 } |
|
348 lowNumBytes = (DWORD)size; |
|
349 highNumBytes = 0; |
|
350 result = UnlockFile(h, lowPos, highPos, lowNumBytes, highNumBytes); |
|
351 } |
|
352 if (result == 0) { |
|
353 JNU_ThrowIOExceptionWithLastError(env, "Release failed"); |
|
354 } |
|
355 } |
|