Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/native/libnio/ch/SocketDispatcher.c
41134 views
1
/*
2
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* 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
42
JNIEXPORT jint JNICALL
43
Java_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
/* limit size */
54
if (len > MAX_BUFFER_SIZE)
55
len = MAX_BUFFER_SIZE;
56
57
/* destination buffer and size */
58
buf.buf = (char *)address;
59
buf.len = (u_long)len;
60
61
/* read into the buffers */
62
i = WSARecv((SOCKET)fd, /* Socket */
63
&buf, /* pointers to the buffers */
64
(DWORD)1, /* number of buffers to process */
65
&read, /* receives number of bytes read */
66
&flags, /* no flags */
67
0, /* no overlapped sockets */
68
0); /* no completion routine */
69
70
if (i == SOCKET_ERROR) {
71
int theErr = (jint)WSAGetLastError();
72
if (theErr == WSAEWOULDBLOCK) {
73
return IOS_UNAVAILABLE;
74
}
75
if (theErr == WSAECONNRESET) {
76
JNU_ThrowByName(env, "sun/net/ConnectionResetException", "Connection reset");
77
} else {
78
JNU_ThrowIOExceptionWithLastError(env, "Read failed");
79
}
80
return IOS_THROWN;
81
}
82
83
return convertReturnVal(env, (jint)read, JNI_TRUE);
84
}
85
86
JNIEXPORT jlong JNICALL
87
Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
88
jlong address, jint len)
89
{
90
/* set up */
91
int i = 0;
92
DWORD read = 0;
93
DWORD flags = 0;
94
jint fd = fdval(env, fdo);
95
struct iovec *iovp = (struct iovec *)address;
96
WSABUF *bufs = malloc(len * sizeof(WSABUF));
97
jint rem = MAX_BUFFER_SIZE;
98
99
if (bufs == 0) {
100
JNU_ThrowOutOfMemoryError(env, 0);
101
return IOS_THROWN;
102
}
103
104
/* copy iovec into WSABUF */
105
for(i=0; i<len; i++) {
106
jint iov_len = iovp[i].iov_len;
107
if (iov_len > rem)
108
iov_len = rem;
109
bufs[i].buf = (char *)iovp[i].iov_base;
110
bufs[i].len = (u_long)iov_len;
111
rem -= iov_len;
112
if (rem == 0) {
113
len = i+1;
114
break;
115
}
116
}
117
118
/* read into the buffers */
119
i = WSARecv((SOCKET)fd, /* Socket */
120
bufs, /* pointers to the buffers */
121
(DWORD)len, /* number of buffers to process */
122
&read, /* receives number of bytes read */
123
&flags, /* no flags */
124
0, /* no overlapped sockets */
125
0); /* no completion routine */
126
127
/* clean up */
128
free(bufs);
129
130
if (i != 0) {
131
int theErr = (jint)WSAGetLastError();
132
if (theErr == WSAEWOULDBLOCK) {
133
return IOS_UNAVAILABLE;
134
}
135
if (theErr == WSAECONNRESET) {
136
JNU_ThrowByName(env, "sun/net/ConnectionResetException", "Connection reset");
137
} else {
138
JNU_ThrowIOExceptionWithLastError(env, "Vector read failed");
139
}
140
return IOS_THROWN;
141
}
142
143
return convertLongReturnVal(env, (jlong)read, JNI_TRUE);
144
}
145
146
JNIEXPORT jint JNICALL
147
Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
148
jlong address, jint total)
149
{
150
/* set up */
151
int i = 0;
152
DWORD written = 0;
153
jint count = 0;
154
jint fd = fdval(env, fdo);
155
WSABUF buf;
156
157
do {
158
/* limit size */
159
jint len = total - count;
160
if (len > MAX_BUFFER_SIZE)
161
len = MAX_BUFFER_SIZE;
162
163
/* copy iovec into WSABUF */
164
buf.buf = (char *)address;
165
buf.len = (u_long)len;
166
167
/* write from the buffer */
168
i = WSASend((SOCKET)fd, /* Socket */
169
&buf, /* pointers to the buffers */
170
(DWORD)1, /* number of buffers to process */
171
&written, /* receives number of bytes written */
172
0, /* no flags */
173
0, /* no overlapped sockets */
174
0); /* no completion routine */
175
176
if (i == SOCKET_ERROR) {
177
if (count > 0) {
178
/* can't throw exception when some bytes have been written */
179
break;
180
} else {
181
int theErr = (jint)WSAGetLastError();
182
if (theErr == WSAEWOULDBLOCK) {
183
return IOS_UNAVAILABLE;
184
}
185
if (theErr == WSAECONNRESET) {
186
JNU_ThrowIOException(env, "Connection reset by peer");
187
} else {
188
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
189
}
190
return IOS_THROWN;
191
}
192
}
193
194
count += (jint)written;
195
address += written;
196
197
} while ((count < total) && (written == MAX_BUFFER_SIZE));
198
199
return count;
200
}
201
202
JNIEXPORT jlong JNICALL
203
Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
204
jobject fdo, jlong address, jint len)
205
{
206
/* set up */
207
int next_index, next_offset, ret=0;
208
DWORD written = 0;
209
jint fd = fdval(env, fdo);
210
struct iovec *iovp = (struct iovec *)address;
211
WSABUF *bufs = malloc(len * sizeof(WSABUF));
212
jlong count = 0;
213
214
if (bufs == 0) {
215
JNU_ThrowOutOfMemoryError(env, 0);
216
return IOS_THROWN;
217
}
218
219
// next buffer and offset to consume
220
next_index = 0;
221
next_offset = 0;
222
223
while (next_index < len) {
224
DWORD buf_count = 0;
225
226
/* Prepare the WSABUF array to a maximum total size of MAX_BUFFER_SIZE */
227
jint rem = MAX_BUFFER_SIZE;
228
while (next_index < len && rem > 0) {
229
jint iov_len = iovp[next_index].iov_len - next_offset;
230
char* ptr = (char *)iovp[next_index].iov_base;
231
ptr += next_offset;
232
if (iov_len > rem) {
233
iov_len = rem;
234
next_offset += rem;
235
} else {
236
next_index ++;
237
next_offset = 0;
238
}
239
240
bufs[buf_count].buf = ptr;
241
bufs[buf_count].len = (u_long)iov_len;
242
buf_count++;
243
244
rem -= iov_len;
245
}
246
247
/* write the buffers */
248
ret = WSASend((SOCKET)fd, /* Socket */
249
bufs, /* pointers to the buffers */
250
buf_count, /* number of buffers to process */
251
&written, /* receives number of bytes written */
252
0, /* no flags */
253
0, /* no overlapped sockets */
254
0); /* no completion routine */
255
256
if (ret == SOCKET_ERROR) {
257
break;
258
}
259
260
count += written;
261
}
262
263
/* clean up */
264
free(bufs);
265
266
if (ret == SOCKET_ERROR && count == 0) {
267
int theErr = (jint)WSAGetLastError();
268
if (theErr == WSAEWOULDBLOCK) {
269
return IOS_UNAVAILABLE;
270
}
271
if (theErr == WSAECONNRESET) {
272
JNU_ThrowIOException(env, "Connection reset by peer");
273
} else {
274
JNU_ThrowIOExceptionWithLastError(env, "Vector write failed");
275
}
276
return IOS_THROWN;
277
}
278
279
return convertLongReturnVal(env, count, JNI_FALSE);
280
}
281
282
JNIEXPORT void JNICALL
283
Java_sun_nio_ch_SocketDispatcher_close0(JNIEnv *env, jclass clazz, jint fd)
284
{
285
if (closesocket(fd) == SOCKET_ERROR) {
286
JNU_ThrowIOExceptionWithLastError(env, "Socket close failed");
287
}
288
}
289
290