blob: 15dc7054f8b4f132e692987f08bf1e83c94fc08d [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 <winsock2.h>
28#include <ctype.h>
29#include "jni.h"
30#include "jni_util.h"
31#include "jvm.h"
32#include "jlong.h"
33#include "sun_nio_ch_SocketDispatcher.h"
34#include "nio.h"
35#include "nio_util.h"
36
37
38/**************************************************************
39 * SocketDispatcher.c
40 */
41
42JNIEXPORT jint JNICALL
43Java_sun_nio_ch_SocketDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
44 jlong address, jint len)
45{
46 /* set up */
47 int i = 0;
48 DWORD read = 0;
49 DWORD flags = 0;
50 jint fd = fdval(env, fdo);
51 WSABUF buf;
52
53 /* destination buffer and size */
54 buf.buf = (char *)address;
55 buf.len = (u_long)len;
56
57 /* read into the buffers */
58 i = WSARecv((SOCKET)fd, /* Socket */
59 &buf, /* pointers to the buffers */
60 (DWORD)1, /* number of buffers to process */
61 &read, /* receives number of bytes read */
62 &flags, /* no flags */
63 0, /* no overlapped sockets */
64 0); /* no completion routine */
65
66 if (i == SOCKET_ERROR) {
67 int theErr = (jint)WSAGetLastError();
68 if (theErr == WSAEWOULDBLOCK) {
69 return IOS_UNAVAILABLE;
70 }
71 JNU_ThrowIOExceptionWithLastError(env, "Read failed");
72 return IOS_THROWN;
73 }
74
75 return convertReturnVal(env, (jint)read, JNI_TRUE);
76}
77
78JNIEXPORT jlong JNICALL
79Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
80 jlong address, jint len)
81{
82 /* set up */
83 int i = 0;
84 DWORD read = 0;
85 DWORD flags = 0;
86 jint fd = fdval(env, fdo);
87 struct iovec *iovp = (struct iovec *)address;
88 WSABUF *bufs = malloc(len * sizeof(WSABUF));
89
90 if (bufs == 0) {
91 JNU_ThrowOutOfMemoryError(env, 0);
92 return IOS_THROWN;
93 }
94
95 if ((isNT() == JNI_FALSE) && (len > 16)) {
96 len = 16;
97 }
98
99 /* copy iovec into WSABUF */
100 for(i=0; i<len; i++) {
101 bufs[i].buf = (char *)iovp[i].iov_base;
102 bufs[i].len = (u_long)iovp[i].iov_len;
103 }
104
105 /* read into the buffers */
106 i = WSARecv((SOCKET)fd, /* Socket */
107 bufs, /* pointers to the buffers */
108 (DWORD)len, /* number of buffers to process */
109 &read, /* receives number of bytes read */
110 &flags, /* no flags */
111 0, /* no overlapped sockets */
112 0); /* no completion routine */
113
114 /* clean up */
115 free(bufs);
116
117 if (i != 0) {
118 int theErr = (jint)WSAGetLastError();
119 if (theErr == WSAEWOULDBLOCK) {
120 return IOS_UNAVAILABLE;
121 }
122 JNU_ThrowIOExceptionWithLastError(env, "Vector read failed");
123 return IOS_THROWN;
124 }
125
126 return convertLongReturnVal(env, (jlong)read, JNI_TRUE);
127}
128
129JNIEXPORT jint JNICALL
130Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
131 jlong address, jint len)
132{
133 /* set up */
134 int i = 0;
135 DWORD written = 0;
136 jint fd = fdval(env, fdo);
137 WSABUF buf;
138
139 /* copy iovec into WSABUF */
140 buf.buf = (char *)address;
141 buf.len = (u_long)len;
142
143 /* read into the buffers */
144 i = WSASend((SOCKET)fd, /* Socket */
145 &buf, /* pointers to the buffers */
146 (DWORD)1, /* number of buffers to process */
147 &written, /* receives number of bytes written */
148 0, /* no flags */
149 0, /* no overlapped sockets */
150 0); /* no completion routine */
151
152 if (i == SOCKET_ERROR) {
153 int theErr = (jint)WSAGetLastError();
154 if (theErr == WSAEWOULDBLOCK) {
155 return IOS_UNAVAILABLE;
156 }
157 JNU_ThrowIOExceptionWithLastError(env, "Write failed");
158 return IOS_THROWN;
159 }
160
161 return convertReturnVal(env, (jint)written, JNI_FALSE);
162}
163
164JNIEXPORT jlong JNICALL
165Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
166 jobject fdo, jlong address, jint len)
167{
168 /* set up */
169 int i = 0;
170 DWORD written = 0;
171 jint fd = fdval(env, fdo);
172 struct iovec *iovp = (struct iovec *)address;
173 WSABUF *bufs = malloc(len * sizeof(WSABUF));
174
175 if (bufs == 0) {
176 JNU_ThrowOutOfMemoryError(env, 0);
177 return IOS_THROWN;
178 }
179
180 if ((isNT() == JNI_FALSE) && (len > 16)) {
181 len = 16;
182 }
183
184 /* copy iovec into WSABUF */
185 for(i=0; i<len; i++) {
186 bufs[i].buf = (char *)iovp[i].iov_base;
187 bufs[i].len = (u_long)iovp[i].iov_len;
188 }
189
190 /* read into the buffers */
191 i = WSASend((SOCKET)fd, /* Socket */
192 bufs, /* pointers to the buffers */
193 (DWORD)len, /* number of buffers to process */
194 &written, /* receives number of bytes written */
195 0, /* no flags */
196 0, /* no overlapped sockets */
197 0); /* no completion routine */
198
199 /* clean up */
200 free(bufs);
201
202 if (i != 0) {
203 int theErr = (jint)WSAGetLastError();
204 if (theErr == WSAEWOULDBLOCK) {
205 return IOS_UNAVAILABLE;
206 }
207 JNU_ThrowIOExceptionWithLastError(env, "Vector write failed");
208 return IOS_THROWN;
209 }
210
211 return convertLongReturnVal(env, (jlong)written, JNI_FALSE);
212}
213
214JNIEXPORT void JNICALL
215Java_sun_nio_ch_SocketDispatcher_close0(JNIEnv *env, jclass clazz,
216 jobject fdo)
217{
218 jint fd = fdval(env, fdo);
219 struct linger l;
220 int len = sizeof(l);
221
222 if (fd != -1) {
223 int result = 0;
224 if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
225 if (l.l_onoff == 0) {
226 WSASendDisconnect(fd, NULL);
227 }
228 }
229 result = closesocket(fd);
230 if (result == SOCKET_ERROR) {
231 JNU_ThrowIOExceptionWithLastError(env, "Socket close failed");
232 }
233 }
234}