Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c
41134 views
1
/*
2
* Copyright (c) 2020, 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
29
#include "jni.h"
30
#include "jni_util.h"
31
#include "jvm.h"
32
#include "jlong.h"
33
#include "nio.h"
34
#include "nio_util.h"
35
#include "net_util.h"
36
37
#include "java_net_InetAddress.h"
38
#include "sun_nio_ch_Net.h"
39
#include "sun_nio_ch_PollArrayWrapper.h"
40
41
jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, socklen_t len)
42
{
43
if (sa->sun_family == AF_UNIX) {
44
int namelen = (int)strlen(sa->sun_path);
45
jbyteArray name = (*env)->NewByteArray(env, namelen);
46
if (name != NULL) {
47
(*env)->SetByteArrayRegion(env, name, 0, namelen, (jbyte*)sa->sun_path);
48
if ((*env)->ExceptionOccurred(env)) {
49
return NULL;
50
}
51
}
52
return name;
53
}
54
return NULL;
55
}
56
57
jint unixSocketAddressToSockaddr(JNIEnv *env, jbyteArray addr, struct sockaddr_un *sa, int *len)
58
{
59
memset(sa, 0, sizeof(struct sockaddr_un));
60
sa->sun_family = AF_UNIX;
61
if (addr == 0L) {
62
/* Do explicit bind on Windows */
63
*len = (int)(offsetof(struct sockaddr_un, sun_path));
64
return 0;
65
}
66
int ret;
67
jboolean isCopy;
68
char *pname = (*env)->GetByteArrayElements(env, addr, &isCopy);
69
if (pname == NULL) {
70
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Unix domain path not present");
71
return -1;
72
}
73
74
size_t name_len = (size_t)(*env)->GetArrayLength(env, addr);
75
if (name_len > MAX_UNIX_DOMAIN_PATH_LEN) {
76
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Unix domain path too long");
77
ret = -1;
78
} else {
79
strncpy(sa->sun_path, pname, name_len);
80
*len = (int)(offsetof(struct sockaddr_un, sun_path) + name_len);
81
ret = 0;
82
}
83
(*env)->ReleaseByteArrayElements(env, addr, pname, JNI_ABORT);
84
return ret;
85
}
86
87
JNIEXPORT jboolean JNICALL
88
Java_sun_nio_ch_UnixDomainSockets_socketSupported(JNIEnv *env, jclass cl)
89
{
90
SOCKET s = socket(PF_UNIX, SOCK_STREAM, 0);
91
if (s == INVALID_SOCKET) {
92
return JNI_FALSE;
93
}
94
closesocket(s);
95
return JNI_TRUE;
96
}
97
98
JNIEXPORT jint JNICALL
99
Java_sun_nio_ch_UnixDomainSockets_socket0(JNIEnv *env, jclass cl)
100
{
101
SOCKET s = socket(PF_UNIX, SOCK_STREAM, 0);
102
if (s == INVALID_SOCKET) {
103
return handleSocketError(env, WSAGetLastError());
104
}
105
SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
106
return (int)s;
107
}
108
109
/**
110
* Windows does not support auto bind. So, the windows version of unixSocketAddressToSockaddr
111
* looks out for a null 'uaddr' and handles it specially
112
*/
113
JNIEXPORT void JNICALL
114
Java_sun_nio_ch_UnixDomainSockets_bind0(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray addr)
115
{
116
struct sockaddr_un sa;
117
int sa_len = 0;
118
int rv = 0;
119
120
if (unixSocketAddressToSockaddr(env, addr, &sa, &sa_len) != 0)
121
return;
122
123
rv = bind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len);
124
if (rv == SOCKET_ERROR) {
125
int err = WSAGetLastError();
126
NET_ThrowNew(env, err, "bind");
127
}
128
}
129
130
JNIEXPORT jint JNICALL
131
Java_sun_nio_ch_UnixDomainSockets_connect0(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray addr)
132
{
133
struct sockaddr_un sa;
134
int sa_len = 0;
135
int rv;
136
137
if (unixSocketAddressToSockaddr(env, addr, &sa, &sa_len) != 0) {
138
return IOS_THROWN;
139
}
140
141
rv = connect(fdval(env, fdo), (const struct sockaddr *)&sa, sa_len);
142
if (rv != 0) {
143
int err = WSAGetLastError();
144
if (err == WSAEINPROGRESS || err == WSAEWOULDBLOCK) {
145
return IOS_UNAVAILABLE;
146
}
147
NET_ThrowNew(env, err, "connect");
148
return IOS_THROWN;
149
}
150
return 1;
151
}
152
153
JNIEXPORT jint JNICALL
154
Java_sun_nio_ch_UnixDomainSockets_accept0(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo,
155
jobjectArray array)
156
{
157
jint fd = fdval(env, fdo);
158
jint newfd;
159
struct sockaddr_un sa;
160
socklen_t sa_len = sizeof(sa);
161
jbyteArray address;
162
163
memset((char *)&sa, 0, sizeof(sa));
164
newfd = (jint) accept(fd, (struct sockaddr *)&sa, &sa_len);
165
if (newfd == INVALID_SOCKET) {
166
int theErr = (jint)WSAGetLastError();
167
if (theErr == WSAEWOULDBLOCK) {
168
return IOS_UNAVAILABLE;
169
}
170
JNU_ThrowIOExceptionWithLastError(env, "Accept failed");
171
return IOS_THROWN;
172
}
173
174
SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
175
setfdval(env, newfdo, newfd);
176
177
address = sockaddrToUnixAddressBytes(env, &sa, sa_len);
178
CHECK_NULL_RETURN(address, IOS_THROWN);
179
(*env)->SetObjectArrayElement(env, array, 0, address);
180
181
return 1;
182
}
183
184
JNIEXPORT jbyteArray JNICALL
185
Java_sun_nio_ch_UnixDomainSockets_localAddress0(JNIEnv *env, jclass clazz, jobject fdo)
186
{
187
struct sockaddr_un sa;
188
int sa_len = sizeof(sa);
189
190
if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) == SOCKET_ERROR) {
191
JNU_ThrowIOExceptionWithLastError(env, "getsockname");
192
return NULL;
193
}
194
return sockaddrToUnixAddressBytes(env, &sa, sa_len);
195
}
196
197
198