blob: a3c3985e7a04900bd55511ede5098db5698b950d [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#include <windows.h>
27#include "jni.h"
28#include "jni_util.h"
29#include "jvm.h"
30#include "jlong.h"
31#include "sun_nio_ch_FileDispatcher.h"
32#include <io.h>
33#include "nio.h"
34#include "nio_util.h"
35
36
37/**************************************************************
38 * FileDispatcher.c
39 */
40
41JNIEXPORT jint JNICALL
42Java_sun_nio_ch_FileDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
43 jlong address, jint len)
44{
45 DWORD read = 0;
46 BOOL result = 0;
47 HANDLE h = (HANDLE)(handleval(env, fdo));
48
49 if (h == INVALID_HANDLE_VALUE) {
50 JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
51 return IOS_THROWN;
52 }
53 result = ReadFile(h, /* File handle to read */
54 (LPVOID)address, /* address to put data */
55 len, /* number of bytes to read */
56 &read, /* number of bytes read */
57 NULL); /* no overlapped struct */
58 if (result == 0) {
59 int error = GetLastError();
60 if (error == ERROR_BROKEN_PIPE) {
61 return IOS_EOF;
62 }
63 if (error == ERROR_NO_DATA) {
64 return IOS_UNAVAILABLE;
65 }
66 JNU_ThrowIOExceptionWithLastError(env, "Read failed");
67 return IOS_THROWN;
68 }
69 return convertReturnVal(env, (jint)read, JNI_TRUE);
70}
71
72JNIEXPORT jlong JNICALL
73Java_sun_nio_ch_FileDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
74 jlong address, jint len)
75{
76 DWORD read = 0;
77 BOOL result = 0;
78 jlong totalRead = 0;
79 LPVOID loc;
80 int i = 0;
81 DWORD num = 0;
82 struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);
83 HANDLE h = (HANDLE)(handleval(env, fdo));
84
85 if (h == INVALID_HANDLE_VALUE) {
86 JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
87 return IOS_THROWN;
88 }
89
90 for(i=0; i<len; i++) {
91 loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);
92 num = iovecp[i].iov_len;
93 result = ReadFile(h, /* File handle to read */
94 loc, /* address to put data */
95 num, /* number of bytes to read */
96 &read, /* number of bytes read */
97 NULL); /* no overlapped struct */
98 if (read > 0) {
99 totalRead += read;
100 }
101 if (read < num) {
102 break;
103 }
104 }
105
106 if (result == 0) {
107 int error = GetLastError();
108 if (error == ERROR_BROKEN_PIPE) {
109 return IOS_EOF;
110 }
111 if (error == ERROR_NO_DATA) {
112 return IOS_UNAVAILABLE;
113 }
114 JNU_ThrowIOExceptionWithLastError(env, "Read failed");
115 return IOS_THROWN;
116 }
117
118 return convertLongReturnVal(env, totalRead, JNI_TRUE);
119}
120
121JNIEXPORT jint JNICALL
122Java_sun_nio_ch_FileDispatcher_pread0(JNIEnv *env, jclass clazz, jobject fdo,
123 jlong address, jint len, jlong offset)
124{
125 DWORD read = 0;
126 BOOL result = 0;
127 HANDLE h = (HANDLE)(handleval(env, fdo));
128 DWORD lowPos = 0;
129 long highPos = 0;
130 DWORD lowOffset = 0;
131 long highOffset = 0;
132
133 if (h == INVALID_HANDLE_VALUE) {
134 JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
135 return IOS_THROWN;
136 }
137
138 lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
139 if (lowPos == ((DWORD)-1)) {
140 if (GetLastError() != ERROR_SUCCESS) {
141 JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
142 return IOS_THROWN;
143 }
144 }
145
146 lowOffset = (DWORD)offset;
147 highOffset = (DWORD)(offset >> 32);
148 lowOffset = SetFilePointer(h, lowOffset, &highOffset, FILE_BEGIN);
149 if (lowOffset == ((DWORD)-1)) {
150 if (GetLastError() != ERROR_SUCCESS) {
151 JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
152 return IOS_THROWN;
153 }
154 }
155
156 result = ReadFile(h, /* File handle to read */
157 (LPVOID)address, /* address to put data */
158 len, /* number of bytes to read */
159 &read, /* number of bytes read */
160 NULL); /* struct with offset */
161
162 if (result == 0) {
163 int error = GetLastError();
164 if (error == ERROR_BROKEN_PIPE) {
165 return IOS_EOF;
166 }
167 if (error == ERROR_NO_DATA) {
168 return IOS_UNAVAILABLE;
169 }
170 JNU_ThrowIOExceptionWithLastError(env, "Read failed");
171 return IOS_THROWN;
172 }
173
174 lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
175 if (lowPos == ((DWORD)-1)) {
176 if (GetLastError() != ERROR_SUCCESS) {
177 JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
178 return IOS_THROWN;
179 }
180 }
181 return convertReturnVal(env, (jint)read, JNI_TRUE);
182}
183
184JNIEXPORT jint JNICALL
185Java_sun_nio_ch_FileDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
186 jlong address, jint len)
187{
188 BOOL result = 0;
189 DWORD written = 0;
190 HANDLE h = (HANDLE)(handleval(env, fdo));
191
192 if (h != INVALID_HANDLE_VALUE) {
193 result = WriteFile(h, /* File handle to write */
194 (LPCVOID)address, /* pointers to the buffers */
195 len, /* number of bytes to write */
196 &written, /* receives number of bytes written */
197 NULL); /* no overlapped struct */
198 }
199
200 if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
201 JNU_ThrowIOExceptionWithLastError(env, "Write failed");
202 }
203
204 return convertReturnVal(env, (jint)written, JNI_FALSE);
205}
206
207JNIEXPORT jlong JNICALL
208Java_sun_nio_ch_FileDispatcher_writev0(JNIEnv *env, jclass clazz, jobject fdo,
209 jlong address, jint len)
210{
211 BOOL result = 0;
212 DWORD written = 0;
213 HANDLE h = (HANDLE)(handleval(env, fdo));
214 jlong totalWritten = 0;
215
216 if (h != INVALID_HANDLE_VALUE) {
217 LPVOID loc;
218 int i = 0;
219 DWORD num = 0;
220 struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);
221
222 for(i=0; i<len; i++) {
223 loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);
224 num = iovecp[i].iov_len;
225 result = WriteFile(h, /* File handle to write */
226 loc, /* pointers to the buffers */
227 num, /* number of bytes to write */
228 &written,/* receives number of bytes written */
229 NULL); /* no overlapped struct */
230 if (written > 0) {
231 totalWritten += written;
232 }
233 if (written < num) {
234 break;
235 }
236 }
237 }
238
239 if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
240 JNU_ThrowIOExceptionWithLastError(env, "Write failed");
241 }
242
243 return convertLongReturnVal(env, totalWritten, JNI_FALSE);
244}
245
246JNIEXPORT jint JNICALL
247Java_sun_nio_ch_FileDispatcher_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
248 jlong address, jint len, jlong offset)
249{
250 BOOL result = 0;
251 DWORD written = 0;
252 HANDLE h = (HANDLE)(handleval(env, fdo));
253 DWORD lowPos = 0;
254 long highPos = 0;
255 DWORD lowOffset = 0;
256 long highOffset = 0;
257
258 lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
259 if (lowPos == ((DWORD)-1)) {
260 if (GetLastError() != ERROR_SUCCESS) {
261 JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
262 return IOS_THROWN;
263 }
264 }
265
266 lowOffset = (DWORD)offset;
267 highOffset = (DWORD)(offset >> 32);
268 lowOffset = SetFilePointer(h, lowOffset, &highOffset, FILE_BEGIN);
269 if (lowOffset == ((DWORD)-1)) {
270 if (GetLastError() != ERROR_SUCCESS) {
271 JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
272 return IOS_THROWN;
273 }
274 }
275
276 result = WriteFile(h, /* File handle to write */
277 (LPCVOID)address, /* pointers to the buffers */
278 len, /* number of bytes to write */
279 &written, /* receives number of bytes written */
280 NULL); /* no overlapped struct */
281
282 if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
283 JNU_ThrowIOExceptionWithLastError(env, "Write failed");
284 return IOS_THROWN;
285 }
286
287 lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
288 if (lowPos == ((DWORD)-1)) {
289 if (GetLastError() != ERROR_SUCCESS) {
290 JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
291 return IOS_THROWN;
292 }
293 }
294
295 return convertReturnVal(env, (jint)written, JNI_FALSE);
296}
297
298static void closeFile(JNIEnv *env, jlong fd) {
299 HANDLE h = (HANDLE)fd;
300 if (h != INVALID_HANDLE_VALUE) {
301 int result = CloseHandle(h);
302 if (result < 0)
303 JNU_ThrowIOExceptionWithLastError(env, "Close failed");
304 }
305}
306
307JNIEXPORT void JNICALL
308Java_sun_nio_ch_FileDispatcher_close0(JNIEnv *env, jclass clazz, jobject fdo)
309{
310 jlong fd = handleval(env, fdo);
311 closeFile(env, fd);
312}
313
314JNIEXPORT void JNICALL
315Java_sun_nio_ch_FileDispatcher_closeByHandle(JNIEnv *env, jclass clazz,
316 jlong fd)
317{
318 closeFile(env, fd);
319}