Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/unix/native/libnio/ch/UnixDomainSockets.c
41133 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 <poll.h>
27
#include <sys/types.h>
28
#include <sys/socket.h>
29
#include <string.h>
30
#include <stddef.h>
31
#include <netinet/in.h>
32
#include <netinet/tcp.h>
33
#include <limits.h>
34
35
#include "jni.h"
36
#include "java_props.h"
37
#include "jni_util.h"
38
#include "jvm.h"
39
#include "jlong.h"
40
#include "sun_nio_ch_Net.h"
41
#include "nio_util.h"
42
#include "nio.h"
43
44
/* Subtle platform differences in how unnamed sockets (empty path)
45
* are returned from getsockname()
46
*/
47
#ifdef MACOSX
48
#define ZERO_PATHLEN(len) (JNI_FALSE)
49
#else
50
#define ZERO_PATHLEN(len) (len == offsetof(struct sockaddr_un, sun_path))
51
#endif
52
53
jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, socklen_t len)
54
{
55
if (sa->sun_family == AF_UNIX) {
56
int namelen;
57
if (ZERO_PATHLEN(len)) {
58
namelen = 0;
59
} else {
60
namelen = strlen(sa->sun_path);
61
}
62
jbyteArray name = (*env)->NewByteArray(env, namelen);
63
if (namelen != 0) {
64
(*env)->SetByteArrayRegion(env, name, 0, namelen, (jbyte*)sa->sun_path);
65
if ((*env)->ExceptionOccurred(env)) {
66
return NULL;
67
}
68
}
69
return name;
70
}
71
return NULL;
72
}
73
74
jint unixSocketAddressToSockaddr(JNIEnv *env, jbyteArray path, struct sockaddr_un *sa, int *len)
75
{
76
memset(sa, 0, sizeof(struct sockaddr_un));
77
sa->sun_family = AF_UNIX;
78
int ret;
79
const char* pname = (const char *)(*env)->GetByteArrayElements(env, path, NULL);
80
if (pname == NULL) {
81
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Unix domain path not present");
82
return -1;
83
}
84
size_t name_len = (*env)->GetArrayLength(env, path);
85
if (name_len > MAX_UNIX_DOMAIN_PATH_LEN) {
86
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Unix domain path too long");
87
ret = -1;
88
} else {
89
memcpy(sa->sun_path, pname, name_len);
90
*len = (int)(offsetof(struct sockaddr_un, sun_path) + name_len + 1);
91
ret = 0;
92
}
93
(*env)->ReleaseByteArrayElements(env, path, (jbyte *)pname, 0);
94
return ret;
95
}
96
97
JNIEXPORT jboolean JNICALL
98
Java_sun_nio_ch_UnixDomainSockets_socketSupported(JNIEnv *env, jclass cl)
99
{
100
return JNI_TRUE;
101
}
102
103
JNIEXPORT jint JNICALL
104
Java_sun_nio_ch_UnixDomainSockets_socket0(JNIEnv *env, jclass cl)
105
{
106
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
107
if (fd < 0) {
108
return handleSocketError(env, errno);
109
}
110
return fd;
111
}
112
113
JNIEXPORT void JNICALL
114
Java_sun_nio_ch_UnixDomainSockets_bind0(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray path)
115
{
116
struct sockaddr_un sa;
117
int sa_len = 0;
118
int rv = 0;
119
120
if (unixSocketAddressToSockaddr(env, path, &sa, &sa_len) != 0)
121
return;
122
123
rv = bind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len);
124
if (rv != 0) {
125
handleSocketError(env, errno);
126
}
127
}
128
129
JNIEXPORT jint JNICALL
130
Java_sun_nio_ch_UnixDomainSockets_connect0(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray path)
131
{
132
struct sockaddr_un sa;
133
int sa_len = 0;
134
int rv;
135
136
if (unixSocketAddressToSockaddr(env, path, &sa, &sa_len) != 0) {
137
return IOS_THROWN;
138
}
139
140
rv = connect(fdval(env, fdo), (struct sockaddr *)&sa, sa_len);
141
if (rv != 0) {
142
if (errno == EINPROGRESS) {
143
return IOS_UNAVAILABLE;
144
} else if (errno == EINTR) {
145
return IOS_INTERRUPTED;
146
}
147
return handleSocketError(env, errno);
148
}
149
return 1;
150
}
151
152
JNIEXPORT jint JNICALL
153
Java_sun_nio_ch_UnixDomainSockets_accept0(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo,
154
jobjectArray array)
155
{
156
jint fd = fdval(env, fdo);
157
jint newfd;
158
struct sockaddr_un sa;
159
socklen_t sa_len = sizeof(struct sockaddr_un);
160
jbyteArray address;
161
162
newfd = accept(fd, (struct sockaddr *)&sa, &sa_len);
163
if (newfd < 0) {
164
if (errno == EAGAIN || errno == EWOULDBLOCK)
165
return IOS_UNAVAILABLE;
166
if (errno == EINTR)
167
return IOS_INTERRUPTED;
168
JNU_ThrowIOExceptionWithLastError(env, "Accept failed");
169
return IOS_THROWN;
170
}
171
172
setfdval(env, newfdo, newfd);
173
174
address = sockaddrToUnixAddressBytes(env, &sa, sa_len);
175
CHECK_NULL_RETURN(address, IOS_THROWN);
176
177
(*env)->SetObjectArrayElement(env, array, 0, address);
178
179
return 1;
180
}
181
182
JNIEXPORT jbyteArray JNICALL
183
Java_sun_nio_ch_UnixDomainSockets_localAddress0(JNIEnv *env, jclass clazz, jobject fdo)
184
{
185
struct sockaddr_un sa;
186
socklen_t sa_len = sizeof(struct sockaddr_un);
187
int port;
188
if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
189
handleSocketError(env, errno);
190
return NULL;
191
}
192
return sockaddrToUnixAddressBytes(env, &sa, sa_len);
193
}
194
195
196