mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 23:34:52 +02:00
8245194: Unix domain socket channel implementation
Reviewed-by: erikj, dfuchs, alanb, chegar
This commit is contained in:
parent
8bde2f4e3d
commit
6bb7e45e8e
73 changed files with 5434 additions and 1116 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -31,8 +31,14 @@ package sun.nio.ch;
|
|||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.UnixDomainSocketAddress;
|
||||
import java.net.StandardProtocolFamily;
|
||||
import java.net.StandardSocketOptions;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.channels.spi.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
@ -55,16 +61,17 @@ class PipeImpl
|
|||
private static final Random RANDOM_NUMBER_GENERATOR = new SecureRandom();
|
||||
|
||||
// Source and sink channels
|
||||
private SourceChannel source;
|
||||
private SinkChannel sink;
|
||||
private final SourceChannel source;
|
||||
private final SinkChannel sink;
|
||||
|
||||
private class Initializer
|
||||
implements PrivilegedExceptionAction<Void>
|
||||
{
|
||||
|
||||
private final SelectorProvider sp;
|
||||
|
||||
private IOException ioe = null;
|
||||
private IOException ioe;
|
||||
SourceChannelImpl source;
|
||||
SinkChannelImpl sink;
|
||||
|
||||
private Initializer(SelectorProvider sp) {
|
||||
this.sp = sp;
|
||||
|
@ -103,23 +110,20 @@ class PipeImpl
|
|||
ServerSocketChannel ssc = null;
|
||||
SocketChannel sc1 = null;
|
||||
SocketChannel sc2 = null;
|
||||
// Loopback address
|
||||
SocketAddress sa = null;
|
||||
|
||||
try {
|
||||
// Create secret with a backing array.
|
||||
ByteBuffer secret = ByteBuffer.allocate(NUM_SECRET_BYTES);
|
||||
ByteBuffer bb = ByteBuffer.allocate(NUM_SECRET_BYTES);
|
||||
|
||||
// Loopback address
|
||||
InetAddress lb = InetAddress.getLoopbackAddress();
|
||||
assert(lb.isLoopbackAddress());
|
||||
InetSocketAddress sa = null;
|
||||
for(;;) {
|
||||
// Bind ServerSocketChannel to a port on the loopback
|
||||
// address
|
||||
if (ssc == null || !ssc.isOpen()) {
|
||||
ssc = ServerSocketChannel.open();
|
||||
ssc.socket().bind(new InetSocketAddress(lb, 0));
|
||||
sa = new InetSocketAddress(lb, ssc.socket().getLocalPort());
|
||||
ssc = createListener();
|
||||
sa = ssc.getLocalAddress();
|
||||
}
|
||||
|
||||
// Establish connection (assume connections are eagerly
|
||||
|
@ -160,18 +164,43 @@ class PipeImpl
|
|||
try {
|
||||
if (ssc != null)
|
||||
ssc.close();
|
||||
if (sa instanceof UnixDomainSocketAddress) {
|
||||
Path path = ((UnixDomainSocketAddress) sa).getPath();
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
} catch (IOException e2) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PipeImpl(final SelectorProvider sp) throws IOException {
|
||||
/**
|
||||
* Creates a Pipe implementation that supports buffering.
|
||||
*/
|
||||
PipeImpl(SelectorProvider sp) throws IOException {
|
||||
this(sp, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Pipe implementation that supports optionally buffering.
|
||||
*
|
||||
* @implNote The pipe uses Unix domain sockets where possible. It uses a
|
||||
* loopback connection on older editions of Windows. When buffering is
|
||||
* disabled then it sets TCP_NODELAY on the sink channel.
|
||||
*/
|
||||
PipeImpl(SelectorProvider sp, boolean buffering) throws IOException {
|
||||
Initializer initializer = new Initializer(sp);
|
||||
try {
|
||||
AccessController.doPrivileged(new Initializer(sp));
|
||||
} catch (PrivilegedActionException x) {
|
||||
throw (IOException)x.getCause();
|
||||
AccessController.doPrivileged(initializer);
|
||||
SinkChannelImpl sink = initializer.sink;
|
||||
if (sink.isNetSocket() && !buffering) {
|
||||
sink.setOption(StandardSocketOptions.TCP_NODELAY, true);
|
||||
}
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw (IOException) pae.getCause();
|
||||
}
|
||||
this.source = initializer.source;
|
||||
this.sink = initializer.sink;
|
||||
}
|
||||
|
||||
public SourceChannel source() {
|
||||
|
@ -182,4 +211,25 @@ class PipeImpl
|
|||
return sink;
|
||||
}
|
||||
|
||||
private static volatile boolean noUnixDomainSockets;
|
||||
|
||||
private static ServerSocketChannel createListener() throws IOException {
|
||||
ServerSocketChannel listener = null;
|
||||
if (!noUnixDomainSockets) {
|
||||
try {
|
||||
listener = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
|
||||
return listener.bind(null);
|
||||
} catch (UnsupportedOperationException | IOException e) {
|
||||
// IOException is most likely to be caused by the temporary directory
|
||||
// name being too long. Possibly should log this.
|
||||
noUnixDomainSockets = true;
|
||||
if (listener != null)
|
||||
listener.close();
|
||||
}
|
||||
}
|
||||
listener = ServerSocketChannel.open();
|
||||
InetAddress lb = InetAddress.getLoopbackAddress();
|
||||
listener.bind(new InetSocketAddress(lb, 0));
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -30,6 +30,7 @@ package sun.nio.ch;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.FileDescriptor;
|
||||
import java.net.SocketOption;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.*;
|
||||
import java.nio.channels.spi.*;
|
||||
|
@ -44,19 +45,27 @@ class SinkChannelImpl
|
|||
implements SelChImpl
|
||||
{
|
||||
// The SocketChannel assoicated with this pipe
|
||||
final SocketChannel sc;
|
||||
private final SocketChannelImpl sc;
|
||||
|
||||
public FileDescriptor getFD() {
|
||||
return ((SocketChannelImpl)sc).getFD();
|
||||
return sc.getFD();
|
||||
}
|
||||
|
||||
public int getFDVal() {
|
||||
return ((SocketChannelImpl)sc).getFDVal();
|
||||
return sc.getFDVal();
|
||||
}
|
||||
|
||||
SinkChannelImpl(SelectorProvider sp, SocketChannel sc) {
|
||||
super(sp);
|
||||
this.sc = sc;
|
||||
this.sc = (SocketChannelImpl) sc;
|
||||
}
|
||||
|
||||
boolean isNetSocket() {
|
||||
return sc.isNetSocket();
|
||||
}
|
||||
|
||||
<T> void setOption(SocketOption<T> name, T value) throws IOException {
|
||||
sc.setOption(name, value);
|
||||
}
|
||||
|
||||
protected void implCloseSelectableChannel() throws IOException {
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.nio.ch;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import sun.net.NetProperties;
|
||||
import jdk.internal.util.StaticProperty;
|
||||
|
||||
class UnixDomainSocketsUtil {
|
||||
private UnixDomainSocketsUtil() { }
|
||||
|
||||
static Charset getCharset() {
|
||||
return StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temp directory for storing automatically bound
|
||||
* server sockets.
|
||||
*
|
||||
* On Windows we search the following directories in sequence:
|
||||
*
|
||||
* 1. ${jdk.net.unixdomain.tmpdir} if set as system property
|
||||
* 2. ${jdk.net.unixdomain.tmpdir} if set as net property
|
||||
* 3. %TEMP%
|
||||
* 4. ${java.io.tmpdir}
|
||||
*/
|
||||
static String getTempDir() {
|
||||
PrivilegedAction<String> action = () -> {
|
||||
String s = NetProperties.get("jdk.net.unixdomain.tmpdir");
|
||||
if (s != null) {
|
||||
return s;
|
||||
}
|
||||
String temp = System.getenv("TEMP");
|
||||
if (temp != null) {
|
||||
return temp;
|
||||
}
|
||||
return StaticProperty.javaIoTmpDir();
|
||||
};
|
||||
return AccessController.doPrivileged(action);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -30,6 +30,7 @@ import java.nio.channels.ClosedSelectorException;
|
|||
import java.nio.channels.Pipe;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
|
@ -139,14 +140,9 @@ class WindowsSelectorImpl extends SelectorImpl {
|
|||
WindowsSelectorImpl(SelectorProvider sp) throws IOException {
|
||||
super(sp);
|
||||
pollWrapper = new PollArrayWrapper(INIT_CAP);
|
||||
wakeupPipe = Pipe.open();
|
||||
wakeupPipe = new PipeImpl(sp, false);
|
||||
wakeupSourceFd = ((SelChImpl)wakeupPipe.source()).getFDVal();
|
||||
|
||||
// Disable the Nagle algorithm so that the wakeup is more immediate
|
||||
SinkChannelImpl sink = (SinkChannelImpl)wakeupPipe.sink();
|
||||
(sink.sc).socket().setTcpNoDelay(true);
|
||||
wakeupSinkFd = ((SelChImpl)sink).getFDVal();
|
||||
|
||||
wakeupSinkFd = ((SelChImpl)wakeupPipe.sink()).getFDVal();
|
||||
pollWrapper.addWakeupSocket(wakeupSourceFd, 0);
|
||||
}
|
||||
|
||||
|
@ -413,19 +409,19 @@ class WindowsSelectorImpl extends SelectorImpl {
|
|||
// processDeregisterQueue.
|
||||
if (me == null)
|
||||
continue;
|
||||
SelectionKeyImpl sk = me.ski;
|
||||
SelectionKeyImpl ski = me.ski;
|
||||
|
||||
// The descriptor may be in the exceptfds set because there is
|
||||
// OOB data queued to the socket. If there is OOB data then it
|
||||
// is discarded and the key is not added to the selected set.
|
||||
if (isExceptFds &&
|
||||
(sk.channel() instanceof SocketChannelImpl) &&
|
||||
discardUrgentData(desc))
|
||||
{
|
||||
SelectableChannel sc = ski.channel();
|
||||
if (isExceptFds && (sc instanceof SocketChannelImpl)
|
||||
&& ((SocketChannelImpl) sc).isNetSocket()
|
||||
&& discardUrgentData(desc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int updated = processReadyEvents(rOps, sk, action);
|
||||
int updated = processReadyEvents(rOps, ski, action);
|
||||
if (updated > 0 && me.updateCount != updateCount) {
|
||||
me.updateCount = updateCount;
|
||||
numKeysUpdated++;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -28,6 +28,7 @@ package sun.nio.fs;
|
|||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.*;
|
||||
import java.nio.channels.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.io.*;
|
||||
|
@ -622,4 +623,12 @@ class WindowsFileSystemProvider
|
|||
String target = WindowsLinkSupport.readLink(link);
|
||||
return WindowsPath.createFromNormalizedPath(fs, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getSunPathForSocketFile(Path obj) {
|
||||
WindowsPath file = WindowsPath.toWindowsPath(obj);
|
||||
String s = file.toString();
|
||||
return s.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
19
src/java.base/windows/conf/net.properties
Normal file
19
src/java.base/windows/conf/net.properties
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Default directory where automatically bound Unix domain server
|
||||
# sockets are stored. Sockets are automatically bound when bound
|
||||
# with a null address.
|
||||
#
|
||||
# The search order for the directory on Windows is:
|
||||
#
|
||||
# 1. System property "jdk.net.unixdomain.tmpdir"
|
||||
#
|
||||
# 2. Networking property "jdk.net.unixdomain.tmpdir" specified
|
||||
# in this file (not set by default)
|
||||
#
|
||||
# 3. The TEMP environment variable (the effective default)
|
||||
#
|
||||
# 4. The java.io.tmpdir system property
|
||||
#
|
||||
#jdk.net.unixdomain.tmpdir=
|
||||
#
|
||||
|
196
src/java.base/windows/native/libnio/ch/UnixDomainSockets.c
Normal file
196
src/java.base/windows/native/libnio/ch/UnixDomainSockets.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "nio.h"
|
||||
#include "nio_util.h"
|
||||
#include "net_util.h"
|
||||
|
||||
#include "java_net_InetAddress.h"
|
||||
#include "sun_nio_ch_Net.h"
|
||||
#include "sun_nio_ch_PollArrayWrapper.h"
|
||||
|
||||
jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, socklen_t len)
|
||||
{
|
||||
if (sa->sun_family == AF_UNIX) {
|
||||
int namelen = (int)strlen(sa->sun_path);
|
||||
jbyteArray name = (*env)->NewByteArray(env, namelen);
|
||||
if (name != NULL) {
|
||||
(*env)->SetByteArrayRegion(env, name, 0, namelen, (jbyte*)sa->sun_path);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jint unixSocketAddressToSockaddr(JNIEnv *env, jbyteArray addr, struct sockaddr_un *sa, int *len)
|
||||
{
|
||||
memset(sa, 0, sizeof(struct sockaddr_un));
|
||||
sa->sun_family = AF_UNIX;
|
||||
if (addr == 0L) {
|
||||
/* Do explicit bind on Windows */
|
||||
*len = (int)(offsetof(struct sockaddr_un, sun_path));
|
||||
return 0;
|
||||
}
|
||||
int ret;
|
||||
jboolean isCopy;
|
||||
char *pname = (*env)->GetByteArrayElements(env, addr, &isCopy);
|
||||
if (pname == NULL) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Unix domain path not present");
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t name_len = (size_t)(*env)->GetArrayLength(env, addr);
|
||||
if (name_len > MAX_UNIX_DOMAIN_PATH_LEN) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Unix domain path too long");
|
||||
ret = -1;
|
||||
} else {
|
||||
strncpy(sa->sun_path, pname, name_len);
|
||||
*len = (int)(offsetof(struct sockaddr_un, sun_path) + name_len);
|
||||
ret = 0;
|
||||
}
|
||||
(*env)->ReleaseByteArrayElements(env, addr, pname, JNI_ABORT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_UnixDomainSockets_socketSupported(JNIEnv *env, jclass cl)
|
||||
{
|
||||
SOCKET s = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (s == INVALID_SOCKET) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
closesocket(s);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_UnixDomainSockets_socket0(JNIEnv *env, jclass cl)
|
||||
{
|
||||
SOCKET s = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (s == INVALID_SOCKET) {
|
||||
return handleSocketError(env, WSAGetLastError());
|
||||
}
|
||||
SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
|
||||
return (int)s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows does not support auto bind. So, the windows version of unixSocketAddressToSockaddr
|
||||
* looks out for a null 'uaddr' and handles it specially
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_UnixDomainSockets_bind0(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray addr)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int sa_len = 0;
|
||||
int rv = 0;
|
||||
|
||||
if (unixSocketAddressToSockaddr(env, addr, &sa, &sa_len) != 0)
|
||||
return;
|
||||
|
||||
rv = bind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len);
|
||||
if (rv == SOCKET_ERROR) {
|
||||
int err = WSAGetLastError();
|
||||
NET_ThrowNew(env, err, "bind");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_UnixDomainSockets_connect0(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray addr)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int sa_len = 0;
|
||||
int rv;
|
||||
|
||||
if (unixSocketAddressToSockaddr(env, addr, &sa, &sa_len) != 0) {
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
rv = connect(fdval(env, fdo), (const struct sockaddr *)&sa, sa_len);
|
||||
if (rv != 0) {
|
||||
int err = WSAGetLastError();
|
||||
if (err == WSAEINPROGRESS || err == WSAEWOULDBLOCK) {
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
NET_ThrowNew(env, err, "connect");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_UnixDomainSockets_accept0(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo,
|
||||
jobjectArray array)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
jint newfd;
|
||||
struct sockaddr_un sa;
|
||||
socklen_t sa_len = sizeof(sa);
|
||||
jbyteArray address;
|
||||
|
||||
memset((char *)&sa, 0, sizeof(sa));
|
||||
newfd = (jint) accept(fd, (struct sockaddr *)&sa, &sa_len);
|
||||
if (newfd == INVALID_SOCKET) {
|
||||
int theErr = (jint)WSAGetLastError();
|
||||
if (theErr == WSAEWOULDBLOCK) {
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Accept failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
|
||||
setfdval(env, newfdo, newfd);
|
||||
|
||||
address = sockaddrToUnixAddressBytes(env, &sa, sa_len);
|
||||
CHECK_NULL_RETURN(address, IOS_THROWN);
|
||||
(*env)->SetObjectArrayElement(env, array, 0, address);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_sun_nio_ch_UnixDomainSockets_localAddress0(JNIEnv *env, jclass clazz, jobject fdo)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int sa_len = sizeof(sa);
|
||||
|
||||
if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) == SOCKET_ERROR) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "getsockname");
|
||||
return NULL;
|
||||
}
|
||||
return sockaddrToUnixAddressBytes(env, &sa, sa_len);
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -24,6 +24,8 @@
|
|||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <afunix.h>
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
|
@ -35,6 +37,9 @@
|
|||
*/
|
||||
#define MAX_BUFFER_SIZE ((128*1024)-1)
|
||||
|
||||
#define MAX_UNIX_DOMAIN_PATH_LEN \
|
||||
(int)(sizeof(((struct sockaddr_un *)0)->sun_path)-2)
|
||||
|
||||
jint fdval(JNIEnv *env, jobject fdo);
|
||||
void setfdval(JNIEnv *env, jobject fdo, jint val);
|
||||
jlong handleval(JNIEnv *env, jobject fdo);
|
||||
|
@ -74,3 +79,11 @@ struct iovec {
|
|||
/* POLLCONN must not equal any of the other constants (see winsock2.h). */
|
||||
#define POLLCONN 0x2000
|
||||
#endif
|
||||
|
||||
/* Defined in UnixDomainSockets.c */
|
||||
|
||||
jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, socklen_t len);
|
||||
|
||||
jint unixSocketAddressToSockaddr(JNIEnv *env, jbyteArray uaddr,
|
||||
struct sockaddr_un *sa, int *len);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue