mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8187443: Forest Consolidation: Move files to unified layout
Reviewed-by: darcy, ihse
This commit is contained in:
parent
270fe13182
commit
3789983e89
56923 changed files with 3 additions and 15727 deletions
233
src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c
Normal file
233
src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2017, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "net_util.h"
|
||||
#include "net_util_md.h"
|
||||
#include "nio.h"
|
||||
#include "nio_util.h"
|
||||
|
||||
#include "sun_nio_ch_DatagramChannelImpl.h"
|
||||
|
||||
static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */
|
||||
static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
|
||||
static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
|
||||
static jclass isa_class; /* java.net.InetSocketAddress */
|
||||
static jmethodID isa_ctorID; /* .InetSocketAddress(InetAddress, int) */
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
clazz = (*env)->FindClass(env, "java/net/InetSocketAddress");
|
||||
CHECK_NULL(clazz);
|
||||
isa_class = (*env)->NewGlobalRef(env, clazz);
|
||||
if (isa_class == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return;
|
||||
}
|
||||
isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
|
||||
"(Ljava/net/InetAddress;I)V");
|
||||
CHECK_NULL(isa_ctorID);
|
||||
|
||||
clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
|
||||
CHECK_NULL(clazz);
|
||||
dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
|
||||
"Ljava/net/SocketAddress;");
|
||||
CHECK_NULL(dci_senderID);
|
||||
dci_senderAddrID = (*env)->GetFieldID(env, clazz,
|
||||
"cachedSenderInetAddress",
|
||||
"Ljava/net/InetAddress;");
|
||||
CHECK_NULL(dci_senderAddrID);
|
||||
dci_senderPortID = (*env)->GetFieldID(env, clazz,
|
||||
"cachedSenderPort", "I");
|
||||
CHECK_NULL(dci_senderPortID);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_DatagramChannelImpl_disconnect0(JNIEnv *env, jobject this,
|
||||
jobject fdo, jboolean isIPv6)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
int rv;
|
||||
|
||||
#if defined(__solaris__)
|
||||
rv = connect(fd, 0, 0);
|
||||
#else
|
||||
SOCKETADDRESS sa;
|
||||
socklen_t len = isIPv6 ? sizeof(struct sockaddr_in6) :
|
||||
sizeof(struct sockaddr_in);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
#if defined(_ALLBSD_SOURCE)
|
||||
sa.sa.sa_family = isIPv6 ? AF_INET6 : AF_INET;
|
||||
#else
|
||||
sa.sa.sa_family = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
rv = connect(fd, &sa.sa, len);
|
||||
|
||||
#if defined(_ALLBSD_SOURCE)
|
||||
if (rv < 0 && errno == EADDRNOTAVAIL)
|
||||
rv = errno = 0;
|
||||
#elif defined(_AIX)
|
||||
/* See W. Richard Stevens, "UNIX Network Programming, Volume 1", p. 254:
|
||||
* 'Setting the address family to AF_UNSPEC might return EAFNOSUPPORT
|
||||
* but that is acceptable.
|
||||
*/
|
||||
if (rv < 0 && errno == EAFNOSUPPORT)
|
||||
rv = errno = 0;
|
||||
#endif // defined(_ALLBSD_SOURCE) || defined(_AIX)
|
||||
|
||||
#endif // defined(__solaris__)
|
||||
|
||||
if (rv < 0)
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
|
||||
jobject fdo, jlong address,
|
||||
jint len, jboolean connected)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
SOCKETADDRESS sa;
|
||||
socklen_t sa_len = sizeof(SOCKETADDRESS);
|
||||
jboolean retry = JNI_FALSE;
|
||||
jint n = 0;
|
||||
jobject senderAddr;
|
||||
|
||||
if (len > MAX_PACKET_LEN) {
|
||||
len = MAX_PACKET_LEN;
|
||||
}
|
||||
|
||||
do {
|
||||
retry = JNI_FALSE;
|
||||
n = recvfrom(fd, buf, len, 0, &sa.sa, &sa_len);
|
||||
if (n < 0) {
|
||||
if (errno == EWOULDBLOCK) {
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
if (errno == EINTR) {
|
||||
return IOS_INTERRUPTED;
|
||||
}
|
||||
if (errno == ECONNREFUSED) {
|
||||
if (connected == JNI_FALSE) {
|
||||
retry = JNI_TRUE;
|
||||
} else {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG
|
||||
"PortUnreachableException", 0);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
} else {
|
||||
return handleSocketError(env, errno);
|
||||
}
|
||||
}
|
||||
} while (retry == JNI_TRUE);
|
||||
|
||||
/*
|
||||
* If the source address and port match the cached address
|
||||
* and port in DatagramChannelImpl then we don't need to
|
||||
* create InetAddress and InetSocketAddress objects.
|
||||
*/
|
||||
senderAddr = (*env)->GetObjectField(env, this, dci_senderAddrID);
|
||||
if (senderAddr != NULL) {
|
||||
if (!NET_SockaddrEqualsInetAddress(env, &sa, senderAddr)) {
|
||||
senderAddr = NULL;
|
||||
} else {
|
||||
jint port = (*env)->GetIntField(env, this, dci_senderPortID);
|
||||
if (port != NET_GetPortFromSockaddr(&sa)) {
|
||||
senderAddr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (senderAddr == NULL) {
|
||||
jobject isa = NULL;
|
||||
int port = 0;
|
||||
jobject ia = NET_SockaddrToInetAddress(env, &sa, &port);
|
||||
if (ia != NULL) {
|
||||
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
|
||||
}
|
||||
CHECK_NULL_RETURN(isa, IOS_THROWN);
|
||||
|
||||
(*env)->SetObjectField(env, this, dci_senderAddrID, ia);
|
||||
(*env)->SetIntField(env, this, dci_senderPortID,
|
||||
NET_GetPortFromSockaddr(&sa));
|
||||
(*env)->SetObjectField(env, this, dci_senderID, isa);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
|
||||
jboolean preferIPv6, jobject fdo, jlong address,
|
||||
jint len, jobject destAddress, jint destPort)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
SOCKETADDRESS sa;
|
||||
int sa_len = 0;
|
||||
jint n = 0;
|
||||
|
||||
if (len > MAX_PACKET_LEN) {
|
||||
len = MAX_PACKET_LEN;
|
||||
}
|
||||
|
||||
if (NET_InetAddressToSockaddr(env, destAddress, destPort, &sa,
|
||||
&sa_len, preferIPv6) != 0) {
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
n = sendto(fd, buf, len, 0, &sa.sa, sa_len);
|
||||
if (n < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
if (errno == EINTR) {
|
||||
return IOS_INTERRUPTED;
|
||||
}
|
||||
if (errno == ECONNREFUSED) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
return handleSocketError(env, errno);
|
||||
}
|
||||
return n;
|
||||
}
|
119
src/java.base/unix/native/libnio/ch/DatagramDispatcher.c
Normal file
119
src/java.base/unix/native/libnio/ch/DatagramDispatcher.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2012, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_DatagramDispatcher.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nio_util.h"
|
||||
#include <limits.h>
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
int result = recv(fd, buf, len, 0);
|
||||
if (result < 0 && errno == ECONNREFUSED) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
|
||||
return -2;
|
||||
}
|
||||
return convertReturnVal(env, result, JNI_TRUE);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
ssize_t result = 0;
|
||||
struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
|
||||
struct msghdr m;
|
||||
if (len > IOV_MAX) {
|
||||
len = IOV_MAX;
|
||||
}
|
||||
|
||||
// initialize the message
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.msg_iov = iov;
|
||||
m.msg_iovlen = len;
|
||||
|
||||
result = recvmsg(fd, &m, 0);
|
||||
if (result < 0 && errno == ECONNREFUSED) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
|
||||
return -2;
|
||||
}
|
||||
return convertLongReturnVal(env, (jlong)result, JNI_TRUE);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_DatagramDispatcher_write0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
int result = send(fd, buf, len, 0);
|
||||
if (result < 0 && errno == ECONNREFUSED) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
|
||||
return -2;
|
||||
}
|
||||
return convertReturnVal(env, result, JNI_FALSE);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
|
||||
struct msghdr m;
|
||||
ssize_t result = 0;
|
||||
if (len > IOV_MAX) {
|
||||
len = IOV_MAX;
|
||||
}
|
||||
|
||||
// initialize the message
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.msg_iov = iov;
|
||||
m.msg_iovlen = len;
|
||||
|
||||
result = sendmsg(fd, &m, 0);
|
||||
if (result < 0 && errno == ECONNREFUSED) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
|
||||
return -2;
|
||||
}
|
||||
return convertLongReturnVal(env, (jlong)result, JNI_FALSE);
|
||||
}
|
266
src/java.base/unix/native/libnio/ch/FileChannelImpl.c
Normal file
266
src/java.base/unix/native/libnio/ch/FileChannelImpl.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2017, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jvm_md.h"
|
||||
#include "jlong.h"
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "sun_nio_ch_FileChannelImpl.h"
|
||||
#include "java_lang_Integer.h"
|
||||
#include "nio.h"
|
||||
#include "nio_util.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if defined(__linux__) || defined(__solaris__)
|
||||
#include <sys/sendfile.h>
|
||||
#elif defined(_AIX)
|
||||
#include <sys/socket.h>
|
||||
#elif defined(_ALLBSD_SOURCE)
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#define lseek64 lseek
|
||||
#define mmap64 mmap
|
||||
#endif
|
||||
|
||||
static jfieldID chan_fd; /* jobject 'fd' in sun.io.FileChannelImpl */
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
jlong pageSize = sysconf(_SC_PAGESIZE);
|
||||
chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
static jlong
|
||||
handle(JNIEnv *env, jlong rv, char *msg)
|
||||
{
|
||||
if (rv >= 0)
|
||||
return rv;
|
||||
if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
JNU_ThrowIOExceptionWithLastError(env, msg);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
|
||||
jint prot, jlong off, jlong len)
|
||||
{
|
||||
void *mapAddress = 0;
|
||||
jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
|
||||
jint fd = fdval(env, fdo);
|
||||
int protections = 0;
|
||||
int flags = 0;
|
||||
|
||||
if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
|
||||
protections = PROT_READ;
|
||||
flags = MAP_SHARED;
|
||||
} else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
|
||||
protections = PROT_WRITE | PROT_READ;
|
||||
flags = MAP_SHARED;
|
||||
} else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
|
||||
protections = PROT_WRITE | PROT_READ;
|
||||
flags = MAP_PRIVATE;
|
||||
}
|
||||
|
||||
mapAddress = mmap64(
|
||||
0, /* Let OS decide location */
|
||||
len, /* Number of bytes to map */
|
||||
protections, /* File permissions */
|
||||
flags, /* Changes are shared */
|
||||
fd, /* File descriptor of mapped file */
|
||||
off); /* Offset into file */
|
||||
|
||||
if (mapAddress == MAP_FAILED) {
|
||||
if (errno == ENOMEM) {
|
||||
JNU_ThrowOutOfMemoryError(env, "Map failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
return handle(env, -1, "Map failed");
|
||||
}
|
||||
|
||||
return ((jlong) (unsigned long) mapAddress);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
|
||||
jlong address, jlong len)
|
||||
{
|
||||
void *a = (void *)jlong_to_ptr(address);
|
||||
return handle(env,
|
||||
munmap(a, (size_t)len),
|
||||
"Unmap failed");
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
|
||||
jobject fdo, jlong offset)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
jlong result = 0;
|
||||
|
||||
if (offset < 0) {
|
||||
result = lseek64(fd, 0, SEEK_CUR);
|
||||
} else {
|
||||
result = lseek64(fd, offset, SEEK_SET);
|
||||
}
|
||||
return handle(env, result, "Position failed");
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
|
||||
jobject srcFDO,
|
||||
jlong position, jlong count,
|
||||
jobject dstFDO)
|
||||
{
|
||||
jint srcFD = fdval(env, srcFDO);
|
||||
jint dstFD = fdval(env, dstFDO);
|
||||
|
||||
#if defined(__linux__)
|
||||
off64_t offset = (off64_t)position;
|
||||
jlong n = sendfile64(dstFD, srcFD, &offset, (size_t)count);
|
||||
if (n < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return IOS_UNAVAILABLE;
|
||||
if ((errno == EINVAL) && ((ssize_t)count >= 0))
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
if (errno == EINTR) {
|
||||
return IOS_INTERRUPTED;
|
||||
}
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
return n;
|
||||
#elif defined (__solaris__)
|
||||
sendfilevec64_t sfv;
|
||||
size_t numBytes = 0;
|
||||
jlong result;
|
||||
|
||||
sfv.sfv_fd = srcFD;
|
||||
sfv.sfv_flag = 0;
|
||||
sfv.sfv_off = (off64_t)position;
|
||||
sfv.sfv_len = count;
|
||||
|
||||
result = sendfilev64(dstFD, &sfv, 1, &numBytes);
|
||||
|
||||
/* Solaris sendfilev() will return -1 even if some bytes have been
|
||||
* transferred, so we check numBytes first.
|
||||
*/
|
||||
if (numBytes > 0)
|
||||
return numBytes;
|
||||
if (result < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return IOS_UNAVAILABLE;
|
||||
if (errno == EOPNOTSUPP)
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
if ((errno == EINVAL) && ((ssize_t)count >= 0))
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
return result;
|
||||
#elif defined(__APPLE__)
|
||||
off_t numBytes;
|
||||
int result;
|
||||
|
||||
numBytes = count;
|
||||
|
||||
result = sendfile(srcFD, dstFD, position, &numBytes, NULL, 0);
|
||||
|
||||
if (numBytes > 0)
|
||||
return numBytes;
|
||||
|
||||
if (result == -1) {
|
||||
if (errno == EAGAIN)
|
||||
return IOS_UNAVAILABLE;
|
||||
if (errno == EOPNOTSUPP || errno == ENOTSOCK || errno == ENOTCONN)
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
if ((errno == EINVAL) && ((ssize_t)count >= 0))
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
#elif defined(_AIX)
|
||||
jlong max = (jlong)java_lang_Integer_MAX_VALUE;
|
||||
struct sf_parms sf_iobuf;
|
||||
jlong result;
|
||||
|
||||
if (position > max)
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
|
||||
if (count > max)
|
||||
count = max;
|
||||
|
||||
memset(&sf_iobuf, 0, sizeof(sf_iobuf));
|
||||
sf_iobuf.file_descriptor = srcFD;
|
||||
sf_iobuf.file_offset = (off_t)position;
|
||||
sf_iobuf.file_bytes = count;
|
||||
|
||||
result = send_file(&dstFD, &sf_iobuf, SF_SYNC_CACHE);
|
||||
|
||||
/* AIX send_file() will return 0 when this operation complete successfully,
|
||||
* return 1 when partial bytes transfered and return -1 when an error has
|
||||
* Occured.
|
||||
*/
|
||||
if (result == -1) {
|
||||
if (errno == EWOULDBLOCK)
|
||||
return IOS_UNAVAILABLE;
|
||||
if ((errno == EINVAL) && ((ssize_t)count >= 0))
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
if (errno == ENOTSOCK)
|
||||
return IOS_UNSUPPORTED;
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
if (sf_iobuf.bytes_sent > 0)
|
||||
return (jlong)sf_iobuf.bytes_sent;
|
||||
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
#else
|
||||
return IOS_UNSUPPORTED_CASE;
|
||||
#endif
|
||||
}
|
||||
|
325
src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c
Normal file
325
src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2017, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_FileDispatcherImpl.h"
|
||||
#include "java_lang_Long.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__linux__)
|
||||
#include <linux/fs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include "nio.h"
|
||||
#include "nio_util.h"
|
||||
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
#define stat64 stat
|
||||
#define flock64 flock
|
||||
#define off64_t off_t
|
||||
#define F_SETLKW64 F_SETLKW
|
||||
#define F_SETLK64 F_SETLK
|
||||
|
||||
#define pread64 pread
|
||||
#define pwrite64 pwrite
|
||||
#define ftruncate64 ftruncate
|
||||
#define fstat64 fstat
|
||||
|
||||
#define fdatasync fsync
|
||||
#endif
|
||||
|
||||
static int preCloseFD = -1; /* File descriptor to which we dup other fd's
|
||||
before closing them for real */
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_init(JNIEnv *env, jclass cl)
|
||||
{
|
||||
int sp[2];
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
|
||||
return;
|
||||
}
|
||||
preCloseFD = sp[0];
|
||||
close(sp[1]);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
|
||||
return convertReturnVal(env, read(fd, buf, len), JNI_TRUE);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,
|
||||
jlong address, jint len, jlong offset)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
|
||||
return convertReturnVal(env, pread64(fd, buf, len, offset), JNI_TRUE);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
|
||||
return convertLongReturnVal(env, readv(fd, iov, len), JNI_TRUE);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
|
||||
return convertReturnVal(env, write(fd, buf, len), JNI_FALSE);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
|
||||
jlong address, jint len, jlong offset)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
void *buf = (void *)jlong_to_ptr(address);
|
||||
|
||||
return convertReturnVal(env, pwrite64(fd, buf, len, offset), JNI_FALSE);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jlong address, jint len)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
|
||||
return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE);
|
||||
}
|
||||
|
||||
static jlong
|
||||
handle(JNIEnv *env, jlong rv, char *msg)
|
||||
{
|
||||
if (rv >= 0)
|
||||
return rv;
|
||||
if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
JNU_ThrowIOExceptionWithLastError(env, msg);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
|
||||
jobject fdo, jboolean md)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
int result = 0;
|
||||
|
||||
#ifdef MACOSX
|
||||
result = fcntl(fd, F_FULLFSYNC);
|
||||
if (result == -1 && errno == ENOTSUP) {
|
||||
/* Try fsync() in case F_FULLSYUNC is not implemented on the file system. */
|
||||
result = fsync(fd);
|
||||
}
|
||||
#else /* end MACOSX, begin not-MACOSX */
|
||||
if (md == JNI_FALSE) {
|
||||
result = fdatasync(fd);
|
||||
} else {
|
||||
#ifdef _AIX
|
||||
/* On AIX, calling fsync on a file descriptor that is opened only for
|
||||
* reading results in an error ("EBADF: The FileDescriptor parameter is
|
||||
* not a valid file descriptor open for writing.").
|
||||
* However, at this point it is not possibly anymore to read the
|
||||
* 'writable' attribute of the corresponding file channel so we have to
|
||||
* use 'fcntl'.
|
||||
*/
|
||||
int getfl = fcntl(fd, F_GETFL);
|
||||
if (getfl >= 0 && (getfl & O_ACCMODE) == O_RDONLY) {
|
||||
return 0;
|
||||
}
|
||||
#endif /* _AIX */
|
||||
result = fsync(fd);
|
||||
}
|
||||
#endif /* not-MACOSX */
|
||||
return handle(env, result, "Force failed");
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
|
||||
jobject fdo, jlong size)
|
||||
{
|
||||
return handle(env,
|
||||
ftruncate64(fdval(env, fdo), size),
|
||||
"Truncation failed");
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_allocate0(JNIEnv *env, jobject this,
|
||||
jobject fdo, jlong size)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
/*
|
||||
* On Linux, if the file size is being increased, then ftruncate64()
|
||||
* will modify the metadata value of the size without actually allocating
|
||||
* any blocks which can cause a SIGBUS error if the file is subsequently
|
||||
* memory-mapped.
|
||||
*/
|
||||
// Return on success or if errno is neither EOPNOTSUPP nor ENOSYS
|
||||
int result = fallocate64(fdval(env, fdo), 0, 0, size);
|
||||
if (result == 0) {
|
||||
return 0;
|
||||
} else if (errno != EOPNOTSUPP && errno != ENOSYS) {
|
||||
return handle(env, result, "Allocation failed");
|
||||
}
|
||||
#endif
|
||||
return handle(env,
|
||||
ftruncate64(fdval(env, fdo), size),
|
||||
"Truncation failed");
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
struct stat64 fbuf;
|
||||
|
||||
if (fstat64(fd, &fbuf) < 0)
|
||||
return handle(env, -1, "Size failed");
|
||||
|
||||
#ifdef BLKGETSIZE64
|
||||
if (S_ISBLK(fbuf.st_mode)) {
|
||||
uint64_t size;
|
||||
if (ioctl(fd, BLKGETSIZE64, &size) < 0)
|
||||
return handle(env, -1, "Size failed");
|
||||
return (jlong)size;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fbuf.st_size;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
|
||||
jboolean block, jlong pos, jlong size,
|
||||
jboolean shared)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
jint lockResult = 0;
|
||||
int cmd = 0;
|
||||
struct flock64 fl;
|
||||
|
||||
fl.l_whence = SEEK_SET;
|
||||
if (size == (jlong)java_lang_Long_MAX_VALUE) {
|
||||
fl.l_len = (off64_t)0;
|
||||
} else {
|
||||
fl.l_len = (off64_t)size;
|
||||
}
|
||||
fl.l_start = (off64_t)pos;
|
||||
if (shared == JNI_TRUE) {
|
||||
fl.l_type = F_RDLCK;
|
||||
} else {
|
||||
fl.l_type = F_WRLCK;
|
||||
}
|
||||
if (block == JNI_TRUE) {
|
||||
cmd = F_SETLKW64;
|
||||
} else {
|
||||
cmd = F_SETLK64;
|
||||
}
|
||||
lockResult = fcntl(fd, cmd, &fl);
|
||||
if (lockResult < 0) {
|
||||
if ((cmd == F_SETLK64) && (errno == EAGAIN || errno == EACCES))
|
||||
return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
|
||||
if (errno == EINTR)
|
||||
return sun_nio_ch_FileDispatcherImpl_INTERRUPTED;
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,
|
||||
jobject fdo, jlong pos, jlong size)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
jint lockResult = 0;
|
||||
struct flock64 fl;
|
||||
int cmd = F_SETLK64;
|
||||
|
||||
fl.l_whence = SEEK_SET;
|
||||
if (size == (jlong)java_lang_Long_MAX_VALUE) {
|
||||
fl.l_len = (off64_t)0;
|
||||
} else {
|
||||
fl.l_len = (off64_t)size;
|
||||
}
|
||||
fl.l_start = (off64_t)pos;
|
||||
fl.l_type = F_UNLCK;
|
||||
lockResult = fcntl(fd, cmd, &fl);
|
||||
if (lockResult < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Release failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void closeFileDescriptor(JNIEnv *env, int fd) {
|
||||
if (fd != -1) {
|
||||
int result = close(fd);
|
||||
if (result < 0)
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Close failed");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
closeFileDescriptor(env, fd);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_preClose0(JNIEnv *env, jclass clazz, jobject fdo)
|
||||
{
|
||||
jint fd = fdval(env, fdo);
|
||||
if (preCloseFD >= 0) {
|
||||
if (dup2(preCloseFD, fd) < 0)
|
||||
JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_FileDispatcherImpl_closeIntFD(JNIEnv *env, jclass clazz, jint fd)
|
||||
{
|
||||
closeFileDescriptor(env, fd);
|
||||
}
|
64
src/java.base/unix/native/libnio/ch/FileKey.c
Normal file
64
src/java.base/unix/native/libnio/ch/FileKey.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2012, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "nio.h"
|
||||
#include "nio_util.h"
|
||||
#include "sun_nio_ch_FileKey.h"
|
||||
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
#define stat64 stat
|
||||
|
||||
#define fstat64 fstat
|
||||
#endif
|
||||
|
||||
static jfieldID key_st_dev; /* id for FileKey.st_dev */
|
||||
static jfieldID key_st_ino; /* id for FileKey.st_ino */
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_FileKey_initIDs(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
CHECK_NULL(key_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J"));
|
||||
CHECK_NULL(key_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J"));
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_FileKey_init(JNIEnv *env, jobject this, jobject fdo)
|
||||
{
|
||||
struct stat64 fbuf;
|
||||
int res;
|
||||
|
||||
RESTARTABLE(fstat64(fdval(env, fdo), &fbuf), res);
|
||||
if (res < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "fstat64 failed");
|
||||
} else {
|
||||
(*env)->SetLongField(env, this, key_st_dev, (jlong)fbuf.st_dev);
|
||||
(*env)->SetLongField(env, this, key_st_ino, (jlong)fbuf.st_ino);
|
||||
}
|
||||
}
|
203
src/java.base/unix/native/libnio/ch/IOUtil.c
Normal file
203
src/java.base/unix/native/libnio/ch/IOUtil.c
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2015, 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 <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_IOUtil.h"
|
||||
#include "java_lang_Integer.h"
|
||||
#include "nio.h"
|
||||
#include "nio_util.h"
|
||||
|
||||
static jfieldID fd_fdID; /* for jint 'fd' in java.io.FileDescriptor */
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_IOUtil_initIDs(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
CHECK_NULL(clazz = (*env)->FindClass(env, "java/io/FileDescriptor"));
|
||||
CHECK_NULL(fd_fdID = (*env)->GetFieldID(env, clazz, "fd", "I"));
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_IOUtil_randomBytes(JNIEnv *env, jclass clazz,
|
||||
jbyteArray randArray)
|
||||
{
|
||||
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", NULL);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_IOUtil_fdVal(JNIEnv *env, jclass clazz, jobject fdo)
|
||||
{
|
||||
return (*env)->GetIntField(env, fdo, fd_fdID);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_IOUtil_setfdVal(JNIEnv *env, jclass clazz, jobject fdo, jint val)
|
||||
{
|
||||
(*env)->SetIntField(env, fdo, fd_fdID, val);
|
||||
}
|
||||
|
||||
static int
|
||||
configureBlocking(int fd, jboolean blocking)
|
||||
{
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
int newflags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
|
||||
|
||||
return (flags == newflags) ? 0 : fcntl(fd, F_SETFL, newflags);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_IOUtil_configureBlocking(JNIEnv *env, jclass clazz,
|
||||
jobject fdo, jboolean blocking)
|
||||
{
|
||||
if (configureBlocking(fdval(env, fdo), blocking) < 0)
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Configure blocking failed");
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_IOUtil_makePipe(JNIEnv *env, jobject this, jboolean blocking)
|
||||
{
|
||||
int fd[2];
|
||||
|
||||
if (pipe(fd) < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Pipe failed");
|
||||
return 0;
|
||||
}
|
||||
if (blocking == JNI_FALSE) {
|
||||
if ((configureBlocking(fd[0], JNI_FALSE) < 0)
|
||||
|| (configureBlocking(fd[1], JNI_FALSE) < 0)) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Configure blocking failed");
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return ((jlong) fd[0] << 32) | (jlong) fd[1];
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_IOUtil_drain(JNIEnv *env, jclass cl, jint fd)
|
||||
{
|
||||
char buf[128];
|
||||
int tn = 0;
|
||||
|
||||
for (;;) {
|
||||
int n = read(fd, buf, sizeof(buf));
|
||||
tn += n;
|
||||
if ((n < 0) && (errno != EAGAIN))
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Drain");
|
||||
if (n == (int)sizeof(buf))
|
||||
continue;
|
||||
return (tn > 0) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_IOUtil_fdLimit(JNIEnv *env, jclass this)
|
||||
{
|
||||
struct rlimit rlp;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "getrlimit failed");
|
||||
return -1;
|
||||
}
|
||||
if (rlp.rlim_max == RLIM_INFINITY ||
|
||||
rlp.rlim_max > (rlim_t)java_lang_Integer_MAX_VALUE) {
|
||||
return java_lang_Integer_MAX_VALUE;
|
||||
} else {
|
||||
return (jint)rlp.rlim_max;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_IOUtil_iovMax(JNIEnv *env, jclass this)
|
||||
{
|
||||
jlong iov_max = sysconf(_SC_IOV_MAX);
|
||||
if (iov_max == -1)
|
||||
iov_max = 16;
|
||||
return (jint)iov_max;
|
||||
}
|
||||
|
||||
/* Declared in nio_util.h for use elsewhere in NIO */
|
||||
|
||||
jint
|
||||
convertReturnVal(JNIEnv *env, jint n, jboolean reading)
|
||||
{
|
||||
if (n > 0) /* Number of bytes written */
|
||||
return n;
|
||||
else if (n == 0) {
|
||||
if (reading) {
|
||||
return IOS_EOF; /* EOF is -1 in javaland */
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (errno == EAGAIN)
|
||||
return IOS_UNAVAILABLE;
|
||||
else if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
else {
|
||||
const char *msg = reading ? "Read failed" : "Write failed";
|
||||
JNU_ThrowIOExceptionWithLastError(env, msg);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Declared in nio_util.h for use elsewhere in NIO */
|
||||
|
||||
jlong
|
||||
convertLongReturnVal(JNIEnv *env, jlong n, jboolean reading)
|
||||
{
|
||||
if (n > 0) /* Number of bytes written */
|
||||
return n;
|
||||
else if (n == 0) {
|
||||
if (reading) {
|
||||
return IOS_EOF; /* EOF is -1 in javaland */
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (errno == EAGAIN)
|
||||
return IOS_UNAVAILABLE;
|
||||
else if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
else {
|
||||
const char *msg = reading ? "Read failed" : "Write failed";
|
||||
JNU_ThrowIOExceptionWithLastError(env, msg);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
}
|
||||
|
||||
jint
|
||||
fdval(JNIEnv *env, jobject fdo)
|
||||
{
|
||||
return (*env)->GetIntField(env, fdo, fd_fdID);
|
||||
}
|
157
src/java.base/unix/native/libnio/ch/InheritedChannel.c
Normal file
157
src/java.base/unix/native/libnio/ch/InheritedChannel.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, 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 <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "net_util.h"
|
||||
|
||||
#include "sun_nio_ch_InheritedChannel.h"
|
||||
|
||||
static int matchFamily(SOCKETADDRESS *sa) {
|
||||
return (sa->sa.sa_family == (ipv6_available() ? AF_INET6 : AF_INET));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_initIDs(JNIEnv *env, jclass cla)
|
||||
{
|
||||
/* Initialize InetAddress IDs before later use of NET_XXX functions */
|
||||
initInetAddressIDs(env);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_peerAddress0(JNIEnv *env, jclass cla, jint fd)
|
||||
{
|
||||
SOCKETADDRESS sa;
|
||||
socklen_t len = sizeof(SOCKETADDRESS);
|
||||
jobject remote_ia = NULL;
|
||||
jint remote_port;
|
||||
|
||||
if (getpeername(fd, &sa.sa, &len) == 0) {
|
||||
if (matchFamily(&sa)) {
|
||||
remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
|
||||
}
|
||||
}
|
||||
|
||||
return remote_ia;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_peerPort0(JNIEnv *env, jclass cla, jint fd)
|
||||
{
|
||||
SOCKETADDRESS sa;
|
||||
socklen_t len = sizeof(SOCKETADDRESS);
|
||||
jint remote_port = -1;
|
||||
|
||||
if (getpeername(fd, &sa.sa, &len) == 0) {
|
||||
if (matchFamily(&sa)) {
|
||||
NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
|
||||
}
|
||||
}
|
||||
|
||||
return remote_port;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_soType0(JNIEnv *env, jclass cla, jint fd)
|
||||
{
|
||||
int sotype;
|
||||
socklen_t arglen = sizeof(sotype);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) == 0) {
|
||||
if (sotype == SOCK_STREAM)
|
||||
return sun_nio_ch_InheritedChannel_SOCK_STREAM;
|
||||
if (sotype == SOCK_DGRAM)
|
||||
return sun_nio_ch_InheritedChannel_SOCK_DGRAM;
|
||||
}
|
||||
return sun_nio_ch_InheritedChannel_UNKNOWN;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_dup(JNIEnv *env, jclass cla, jint fd)
|
||||
{
|
||||
int newfd = dup(fd);
|
||||
if (newfd < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "dup failed");
|
||||
}
|
||||
return (jint)newfd;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_dup2(JNIEnv *env, jclass cla, jint fd, jint fd2)
|
||||
{
|
||||
if (dup2(fd, fd2) < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_open0(JNIEnv *env, jclass cla, jstring path, jint oflag)
|
||||
{
|
||||
const char *str;
|
||||
int oflag_actual;
|
||||
|
||||
/* convert to OS specific value */
|
||||
switch (oflag) {
|
||||
case sun_nio_ch_InheritedChannel_O_RDWR :
|
||||
oflag_actual = O_RDWR;
|
||||
break;
|
||||
case sun_nio_ch_InheritedChannel_O_RDONLY :
|
||||
oflag_actual = O_RDONLY;
|
||||
break;
|
||||
case sun_nio_ch_InheritedChannel_O_WRONLY :
|
||||
oflag_actual = O_WRONLY;
|
||||
break;
|
||||
default :
|
||||
JNU_ThrowInternalError(env, "Unrecognized file mode");
|
||||
return -1;
|
||||
}
|
||||
|
||||
str = JNU_GetStringPlatformChars(env, path, NULL);
|
||||
if (str == NULL) {
|
||||
return (jint)-1;
|
||||
} else {
|
||||
int fd = open(str, oflag_actual);
|
||||
if (fd < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, str);
|
||||
}
|
||||
JNU_ReleaseStringPlatformChars(env, path, str);
|
||||
return (jint)fd;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_InheritedChannel_close0(JNIEnv *env, jclass cla, jint fd)
|
||||
{
|
||||
if (close(fd) < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "close failed");
|
||||
}
|
||||
}
|
104
src/java.base/unix/native/libnio/ch/NativeThread.c
Normal file
104
src/java.base/unix/native/libnio/ch/NativeThread.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2016, 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 <sys/types.h>
|
||||
#include <string.h>
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_NativeThread.h"
|
||||
#include "nio_util.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <pthread.h>
|
||||
/* Also defined in net/linux_close.c */
|
||||
#define INTERRUPT_SIGNAL (__SIGRTMAX - 2)
|
||||
#elif _AIX
|
||||
#include <pthread.h>
|
||||
/* Also defined in net/aix_close.c */
|
||||
#define INTERRUPT_SIGNAL (SIGRTMAX - 1)
|
||||
#elif __solaris__
|
||||
#include <thread.h>
|
||||
#define INTERRUPT_SIGNAL (SIGRTMAX - 2)
|
||||
#elif _ALLBSD_SOURCE
|
||||
#include <pthread.h>
|
||||
/* Also defined in net/bsd_close.c */
|
||||
#define INTERRUPT_SIGNAL SIGIO
|
||||
#else
|
||||
#error "missing platform-specific definition here"
|
||||
#endif
|
||||
|
||||
static void
|
||||
nullHandler(int sig)
|
||||
{
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_NativeThread_init(JNIEnv *env, jclass cl)
|
||||
{
|
||||
/* Install the null handler for INTERRUPT_SIGNAL. This might overwrite the
|
||||
* handler previously installed by <platform>_close.c, but that's okay
|
||||
* since neither handler actually does anything. We install our own
|
||||
* handler here simply out of paranoia; ultimately the two mechanisms
|
||||
* should somehow be unified, perhaps within the VM.
|
||||
*/
|
||||
|
||||
sigset_t ss;
|
||||
struct sigaction sa, osa;
|
||||
sa.sa_handler = nullHandler;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if (sigaction(INTERRUPT_SIGNAL, &sa, &osa) < 0)
|
||||
JNU_ThrowIOExceptionWithLastError(env, "sigaction");
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_NativeThread_current(JNIEnv *env, jclass cl)
|
||||
{
|
||||
#ifdef __solaris__
|
||||
return (jlong)thr_self();
|
||||
#else
|
||||
return (jlong)pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_NativeThread_signal(JNIEnv *env, jclass cl, jlong thread)
|
||||
{
|
||||
int ret;
|
||||
#ifdef __solaris__
|
||||
ret = thr_kill((thread_t)thread, INTERRUPT_SIGNAL);
|
||||
#else
|
||||
ret = pthread_kill((pthread_t)thread, INTERRUPT_SIGNAL);
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
if (ret != 0 && ret != ESRCH)
|
||||
#else
|
||||
if (ret != 0)
|
||||
#endif
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Thread signal failed");
|
||||
}
|
783
src/java.base/unix/native/libnio/ch/Net.c
Normal file
783
src/java.base/unix/native/libnio/ch/Net.c
Normal file
|
@ -0,0 +1,783 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2017, 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 <poll.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_Net.h"
|
||||
#include "net_util.h"
|
||||
#include "net_util_md.h"
|
||||
#include "nio_util.h"
|
||||
#include "nio.h"
|
||||
#include "sun_nio_ch_PollArrayWrapper.h"
|
||||
|
||||
#ifdef _AIX
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
|
||||
* build time.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
#ifndef IP_MULTICAST_ALL
|
||||
#define IP_MULTICAST_ALL 49
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP may not be defined on OSX and AIX
|
||||
*/
|
||||
#if defined(__APPLE__) || defined(_AIX)
|
||||
#ifndef IPV6_ADD_MEMBERSHIP
|
||||
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_AIX)
|
||||
#ifndef IP_BLOCK_SOURCE
|
||||
#define IP_BLOCK_SOURCE 58 /* Block data from a given source to a given group */
|
||||
#define IP_UNBLOCK_SOURCE 59 /* Unblock data from a given source to a given group */
|
||||
#define IP_ADD_SOURCE_MEMBERSHIP 60 /* Join a source-specific group */
|
||||
#define IP_DROP_SOURCE_MEMBERSHIP 61 /* Leave a source-specific group */
|
||||
#endif
|
||||
|
||||
#ifndef MCAST_BLOCK_SOURCE
|
||||
#define MCAST_BLOCK_SOURCE 64
|
||||
#define MCAST_UNBLOCK_SOURCE 65
|
||||
#define MCAST_JOIN_SOURCE_GROUP 66
|
||||
#define MCAST_LEAVE_SOURCE_GROUP 67
|
||||
|
||||
/* This means we're on AIX 5.3 and 'group_source_req' and 'ip_mreq_source' aren't defined as well */
|
||||
struct group_source_req {
|
||||
uint32_t gsr_interface;
|
||||
struct sockaddr_storage gsr_group;
|
||||
struct sockaddr_storage gsr_source;
|
||||
};
|
||||
struct ip_mreq_source {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_sourceaddr; /* IP address of source */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
};
|
||||
#endif
|
||||
#endif /* _AIX */
|
||||
|
||||
#define COPY_INET6_ADDRESS(env, source, target) \
|
||||
(*env)->GetByteArrayRegion(env, source, 0, 16, target)
|
||||
|
||||
/*
|
||||
* Copy IPv6 group, interface index, and IPv6 source address
|
||||
* into group_source_req structure.
|
||||
*/
|
||||
static void initGroupSourceReq(JNIEnv* env, jbyteArray group, jint index,
|
||||
jbyteArray source, struct group_source_req *req)
|
||||
{
|
||||
struct sockaddr_in6* sin6;
|
||||
|
||||
req->gsr_interface = (uint32_t)index;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&(req->gsr_group);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
COPY_INET6_ADDRESS(env, group, (jbyte *)&(sin6->sin6_addr));
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&(req->gsr_source);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
COPY_INET6_ADDRESS(env, source, (jbyte *)&(sin6->sin6_addr));
|
||||
}
|
||||
|
||||
#ifdef _AIX
|
||||
|
||||
/*
|
||||
* Checks whether or not "socket extensions for multicast source filters" is supported.
|
||||
* Returns JNI_TRUE if it is supported, JNI_FALSE otherwise
|
||||
*/
|
||||
static jboolean isSourceFilterSupported(){
|
||||
static jboolean alreadyChecked = JNI_FALSE;
|
||||
static jboolean result = JNI_TRUE;
|
||||
if (alreadyChecked != JNI_TRUE){
|
||||
struct utsname uts;
|
||||
memset(&uts, 0, sizeof(uts));
|
||||
strcpy(uts.sysname, "?");
|
||||
const int utsRes = uname(&uts);
|
||||
int major = -1;
|
||||
int minor = -1;
|
||||
major = atoi(uts.version);
|
||||
minor = atoi(uts.release);
|
||||
if (strcmp(uts.sysname, "AIX") == 0) {
|
||||
if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
|
||||
result = JNI_FALSE;
|
||||
}
|
||||
}
|
||||
alreadyChecked = JNI_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* _AIX */
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
initInetAddressIDs(env);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)
|
||||
{
|
||||
return (ipv6_available()) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||
{
|
||||
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
|
||||
{
|
||||
#if defined(__APPLE__) || defined(_AIX)
|
||||
/* for now IPv6 sockets cannot join IPv4 multicast groups */
|
||||
return JNI_FALSE;
|
||||
#else
|
||||
return JNI_TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
|
||||
{
|
||||
#ifdef __solaris__
|
||||
return JNI_TRUE;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
|
||||
jboolean stream, jboolean reuse, jboolean ignored)
|
||||
{
|
||||
int fd;
|
||||
int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
|
||||
int domain = (ipv6_available() && preferIPv6) ? AF_INET6 : AF_INET;
|
||||
|
||||
fd = socket(domain, type, 0);
|
||||
if (fd < 0) {
|
||||
return handleSocketError(env, errno);
|
||||
}
|
||||
|
||||
/* Disable IPV6_V6ONLY to ensure dual-socket support */
|
||||
if (domain == AF_INET6) {
|
||||
int arg = 0;
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
|
||||
sizeof(int)) < 0) {
|
||||
JNU_ThrowByNameWithLastError(env,
|
||||
JNU_JAVANETPKG "SocketException",
|
||||
"Unable to set IPV6_V6ONLY");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (reuse) {
|
||||
int arg = 1;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
|
||||
sizeof(arg)) < 0) {
|
||||
JNU_ThrowByNameWithLastError(env,
|
||||
JNU_JAVANETPKG "SocketException",
|
||||
"Unable to set SO_REUSEADDR");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
if (type == SOCK_DGRAM) {
|
||||
int arg = 0;
|
||||
int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP;
|
||||
if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) &&
|
||||
(errno != ENOPROTOOPT)) {
|
||||
JNU_ThrowByNameWithLastError(env,
|
||||
JNU_JAVANETPKG "SocketException",
|
||||
"Unable to set IP_MULTICAST_ALL");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* By default, Linux uses the route default */
|
||||
if (domain == AF_INET6 && type == SOCK_DGRAM) {
|
||||
int arg = 1;
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &arg,
|
||||
sizeof(arg)) < 0) {
|
||||
JNU_ThrowByNameWithLastError(env,
|
||||
JNU_JAVANETPKG "SocketException",
|
||||
"Unable to set IPV6_MULTICAST_HOPS");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_bind0(JNIEnv *env, jclass clazz, jobject fdo, jboolean preferIPv6,
|
||||
jboolean useExclBind, jobject iao, int port)
|
||||
{
|
||||
SOCKETADDRESS sa;
|
||||
int sa_len = 0;
|
||||
int rv = 0;
|
||||
|
||||
if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
|
||||
preferIPv6) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
rv = NET_Bind(fdval(env, fdo), &sa, sa_len);
|
||||
if (rv != 0) {
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_listen(JNIEnv *env, jclass cl, jobject fdo, jint backlog)
|
||||
{
|
||||
if (listen(fdval(env, fdo), backlog) < 0)
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_connect0(JNIEnv *env, jclass clazz, jboolean preferIPv6,
|
||||
jobject fdo, jobject iao, jint port)
|
||||
{
|
||||
SOCKETADDRESS sa;
|
||||
int sa_len = 0;
|
||||
int rv;
|
||||
|
||||
if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
|
||||
preferIPv6) != 0) {
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
rv = connect(fdval(env, fdo), &sa.sa, sa_len);
|
||||
if (rv != 0) {
|
||||
if (errno == EINPROGRESS) {
|
||||
return IOS_UNAVAILABLE;
|
||||
} else if (errno == EINTR) {
|
||||
return IOS_INTERRUPTED;
|
||||
}
|
||||
return handleSocketError(env, errno);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo)
|
||||
{
|
||||
SOCKETADDRESS sa;
|
||||
socklen_t sa_len = sizeof(SOCKETADDRESS);
|
||||
if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
/*
|
||||
* XXXBSD:
|
||||
* ECONNRESET is specific to the BSDs. We can not return an error,
|
||||
* as the calling Java code with raise a java.lang.Error given the expectation
|
||||
* that getsockname() will never fail. According to the Single UNIX Specification,
|
||||
* it shouldn't fail. As such, we just fill in generic Linux-compatible values.
|
||||
*/
|
||||
if (errno == ECONNRESET) {
|
||||
bzero(&sa.sa4, sizeof(sa));
|
||||
sa.sa4.sin_len = sizeof(struct sockaddr_in);
|
||||
sa.sa4.sin_family = AF_INET;
|
||||
sa.sa4.sin_port = htonl(0);
|
||||
sa.sa4.sin_addr.s_addr = INADDR_ANY;
|
||||
} else {
|
||||
handleSocketError(env, errno);
|
||||
return -1;
|
||||
}
|
||||
#else /* _ALLBSD_SOURCE */
|
||||
handleSocketError(env, errno);
|
||||
return -1;
|
||||
#endif /* _ALLBSD_SOURCE */
|
||||
}
|
||||
return NET_GetPortFromSockaddr(&sa);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_sun_nio_ch_Net_localInetAddress(JNIEnv *env, jclass clazz, jobject fdo)
|
||||
{
|
||||
SOCKETADDRESS sa;
|
||||
socklen_t sa_len = sizeof(SOCKETADDRESS);
|
||||
int port;
|
||||
if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
/*
|
||||
* XXXBSD:
|
||||
* ECONNRESET is specific to the BSDs. We can not return an error,
|
||||
* as the calling Java code with raise a java.lang.Error with the expectation
|
||||
* that getsockname() will never fail. According to the Single UNIX Specification,
|
||||
* it shouldn't fail. As such, we just fill in generic Linux-compatible values.
|
||||
*/
|
||||
if (errno == ECONNRESET) {
|
||||
bzero(&sa.sa4, sizeof(sa));
|
||||
sa.sa4.sin_len = sizeof(struct sockaddr_in);
|
||||
sa.sa4.sin_family = AF_INET;
|
||||
sa.sa4.sin_port = htonl(0);
|
||||
sa.sa4.sin_addr.s_addr = INADDR_ANY;
|
||||
} else {
|
||||
handleSocketError(env, errno);
|
||||
return NULL;
|
||||
}
|
||||
#else /* _ALLBSD_SOURCE */
|
||||
handleSocketError(env, errno);
|
||||
return NULL;
|
||||
#endif /* _ALLBSD_SOURCE */
|
||||
}
|
||||
return NET_SockaddrToInetAddress(env, &sa, &port);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz, jobject fdo,
|
||||
jboolean mayNeedConversion, jint level, jint opt)
|
||||
{
|
||||
int result;
|
||||
struct linger linger;
|
||||
u_char carg;
|
||||
void *arg;
|
||||
socklen_t arglen;
|
||||
int n;
|
||||
|
||||
/* Option value is an int except for a few specific cases */
|
||||
|
||||
arg = (void *)&result;
|
||||
arglen = sizeof(result);
|
||||
|
||||
if (level == IPPROTO_IP &&
|
||||
(opt == IP_MULTICAST_TTL || opt == IP_MULTICAST_LOOP)) {
|
||||
arg = (void*)&carg;
|
||||
arglen = sizeof(carg);
|
||||
}
|
||||
|
||||
if (level == SOL_SOCKET && opt == SO_LINGER) {
|
||||
arg = (void *)&linger;
|
||||
arglen = sizeof(linger);
|
||||
}
|
||||
|
||||
if (mayNeedConversion) {
|
||||
n = NET_GetSockOpt(fdval(env, fdo), level, opt, arg, (int*)&arglen);
|
||||
} else {
|
||||
n = getsockopt(fdval(env, fdo), level, opt, arg, &arglen);
|
||||
}
|
||||
if (n < 0) {
|
||||
JNU_ThrowByNameWithLastError(env,
|
||||
JNU_JAVANETPKG "SocketException",
|
||||
"sun.nio.ch.Net.getIntOption");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (level == IPPROTO_IP &&
|
||||
(opt == IP_MULTICAST_TTL || opt == IP_MULTICAST_LOOP))
|
||||
{
|
||||
return (jint)carg;
|
||||
}
|
||||
|
||||
if (level == SOL_SOCKET && opt == SO_LINGER)
|
||||
return linger.l_onoff ? (jint)linger.l_linger : (jint)-1;
|
||||
|
||||
return (jint)result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz, jobject fdo,
|
||||
jboolean mayNeedConversion, jint level,
|
||||
jint opt, jint arg, jboolean isIPv6)
|
||||
{
|
||||
int result;
|
||||
struct linger linger;
|
||||
u_char carg;
|
||||
void *parg;
|
||||
socklen_t arglen;
|
||||
int n;
|
||||
|
||||
/* Option value is an int except for a few specific cases */
|
||||
|
||||
parg = (void*)&arg;
|
||||
arglen = sizeof(arg);
|
||||
|
||||
if (level == IPPROTO_IP &&
|
||||
(opt == IP_MULTICAST_TTL || opt == IP_MULTICAST_LOOP)) {
|
||||
parg = (void*)&carg;
|
||||
arglen = sizeof(carg);
|
||||
carg = (u_char)arg;
|
||||
}
|
||||
|
||||
if (level == SOL_SOCKET && opt == SO_LINGER) {
|
||||
parg = (void *)&linger;
|
||||
arglen = sizeof(linger);
|
||||
if (arg >= 0) {
|
||||
linger.l_onoff = 1;
|
||||
linger.l_linger = arg;
|
||||
} else {
|
||||
linger.l_onoff = 0;
|
||||
linger.l_linger = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mayNeedConversion) {
|
||||
n = NET_SetSockOpt(fdval(env, fdo), level, opt, parg, arglen);
|
||||
} else {
|
||||
n = setsockopt(fdval(env, fdo), level, opt, parg, arglen);
|
||||
}
|
||||
if (n < 0) {
|
||||
JNU_ThrowByNameWithLastError(env,
|
||||
JNU_JAVANETPKG "SocketException",
|
||||
"sun.nio.ch.Net.setIntOption");
|
||||
}
|
||||
#ifdef __linux__
|
||||
if (level == IPPROTO_IPV6 && opt == IPV6_TCLASS && isIPv6) {
|
||||
// set the V4 option also
|
||||
setsockopt(fdval(env, fdo), IPPROTO_IP, IP_TOS, parg, arglen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_joinOrDrop4(JNIEnv *env, jobject this, jboolean join, jobject fdo,
|
||||
jint group, jint interf, jint source)
|
||||
{
|
||||
struct ip_mreq mreq;
|
||||
struct ip_mreq_source mreq_source;
|
||||
int opt, n, optlen;
|
||||
void* optval;
|
||||
|
||||
if (source == 0) {
|
||||
mreq.imr_multiaddr.s_addr = htonl(group);
|
||||
mreq.imr_interface.s_addr = htonl(interf);
|
||||
opt = (join) ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
|
||||
optval = (void*)&mreq;
|
||||
optlen = sizeof(mreq);
|
||||
} else {
|
||||
|
||||
#ifdef _AIX
|
||||
/* check AIX for support of source filtering */
|
||||
if (isSourceFilterSupported() != JNI_TRUE){
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mreq_source.imr_multiaddr.s_addr = htonl(group);
|
||||
mreq_source.imr_sourceaddr.s_addr = htonl(source);
|
||||
mreq_source.imr_interface.s_addr = htonl(interf);
|
||||
opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
|
||||
optval = (void*)&mreq_source;
|
||||
optlen = sizeof(mreq_source);
|
||||
}
|
||||
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
|
||||
if (n < 0) {
|
||||
if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_blockOrUnblock4(JNIEnv *env, jobject this, jboolean block, jobject fdo,
|
||||
jint group, jint interf, jint source)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
/* no IPv4 exclude-mode filtering for now */
|
||||
return IOS_UNAVAILABLE;
|
||||
#else
|
||||
struct ip_mreq_source mreq_source;
|
||||
int n;
|
||||
int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
|
||||
|
||||
#ifdef _AIX
|
||||
/* check AIX for support of source filtering */
|
||||
if (isSourceFilterSupported() != JNI_TRUE){
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mreq_source.imr_multiaddr.s_addr = htonl(group);
|
||||
mreq_source.imr_sourceaddr.s_addr = htonl(source);
|
||||
mreq_source.imr_interface.s_addr = htonl(interf);
|
||||
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
|
||||
(void*)&mreq_source, sizeof(mreq_source));
|
||||
if (n < 0) {
|
||||
if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobject fdo,
|
||||
jbyteArray group, jint index, jbyteArray source)
|
||||
{
|
||||
struct ipv6_mreq mreq6;
|
||||
struct group_source_req req;
|
||||
int opt, n, optlen;
|
||||
void* optval;
|
||||
|
||||
if (source == NULL) {
|
||||
COPY_INET6_ADDRESS(env, group, (jbyte*)&(mreq6.ipv6mr_multiaddr));
|
||||
mreq6.ipv6mr_interface = (int)index;
|
||||
opt = (join) ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP;
|
||||
optval = (void*)&mreq6;
|
||||
optlen = sizeof(mreq6);
|
||||
} else {
|
||||
#ifdef __APPLE__
|
||||
/* no IPv6 include-mode filtering for now */
|
||||
return IOS_UNAVAILABLE;
|
||||
#else
|
||||
initGroupSourceReq(env, group, index, source, &req);
|
||||
opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP;
|
||||
optval = (void*)&req;
|
||||
optlen = sizeof(req);
|
||||
#endif
|
||||
}
|
||||
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
|
||||
if (n < 0) {
|
||||
if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_blockOrUnblock6(JNIEnv *env, jobject this, jboolean block, jobject fdo,
|
||||
jbyteArray group, jint index, jbyteArray source)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
/* no IPv6 exclude-mode filtering for now */
|
||||
return IOS_UNAVAILABLE;
|
||||
#else
|
||||
struct group_source_req req;
|
||||
int n;
|
||||
int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
|
||||
|
||||
initGroupSourceReq(env, group, index, source, &req);
|
||||
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
|
||||
(void*)&req, sizeof(req));
|
||||
if (n < 0) {
|
||||
if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_setInterface4(JNIEnv* env, jobject this, jobject fdo, jint interf)
|
||||
{
|
||||
struct in_addr in;
|
||||
socklen_t arglen = sizeof(struct in_addr);
|
||||
int n;
|
||||
|
||||
in.s_addr = htonl(interf);
|
||||
|
||||
n = setsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(void*)&(in.s_addr), arglen);
|
||||
if (n < 0) {
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_getInterface4(JNIEnv* env, jobject this, jobject fdo)
|
||||
{
|
||||
struct in_addr in;
|
||||
socklen_t arglen = sizeof(struct in_addr);
|
||||
int n;
|
||||
|
||||
n = getsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF, (void*)&in, &arglen);
|
||||
if (n < 0) {
|
||||
handleSocketError(env, errno);
|
||||
return -1;
|
||||
}
|
||||
return ntohl(in.s_addr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_setInterface6(JNIEnv* env, jobject this, jobject fdo, jint index)
|
||||
{
|
||||
int value = (jint)index;
|
||||
socklen_t arglen = sizeof(value);
|
||||
int n;
|
||||
|
||||
n = setsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||
(void*)&(index), arglen);
|
||||
if (n < 0) {
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_getInterface6(JNIEnv* env, jobject this, jobject fdo)
|
||||
{
|
||||
int index;
|
||||
socklen_t arglen = sizeof(index);
|
||||
int n;
|
||||
|
||||
n = getsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF, (void*)&index, &arglen);
|
||||
if (n < 0) {
|
||||
handleSocketError(env, errno);
|
||||
return -1;
|
||||
}
|
||||
return (jint)index;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_shutdown(JNIEnv *env, jclass cl, jobject fdo, jint jhow)
|
||||
{
|
||||
int how = (jhow == sun_nio_ch_Net_SHUT_RD) ? SHUT_RD :
|
||||
(jhow == sun_nio_ch_Net_SHUT_WR) ? SHUT_WR : SHUT_RDWR;
|
||||
if ((shutdown(fdval(env, fdo), how) < 0) && (errno != ENOTCONN))
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_poll(JNIEnv* env, jclass this, jobject fdo, jint events, jlong timeout)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
int rv;
|
||||
pfd.fd = fdval(env, fdo);
|
||||
pfd.events = events;
|
||||
if (timeout < -1) {
|
||||
timeout = -1;
|
||||
} else if (timeout > INT_MAX) {
|
||||
timeout = INT_MAX;
|
||||
}
|
||||
rv = poll(&pfd, 1, (int)timeout);
|
||||
|
||||
if (rv >= 0) {
|
||||
return pfd.revents;
|
||||
} else if (errno == EINTR) {
|
||||
return IOS_INTERRUPTED;
|
||||
} else {
|
||||
handleSocketError(env, errno);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jshort JNICALL
|
||||
Java_sun_nio_ch_Net_pollinValue(JNIEnv *env, jclass this)
|
||||
{
|
||||
return (jshort)POLLIN;
|
||||
}
|
||||
|
||||
JNIEXPORT jshort JNICALL
|
||||
Java_sun_nio_ch_Net_polloutValue(JNIEnv *env, jclass this)
|
||||
{
|
||||
return (jshort)POLLOUT;
|
||||
}
|
||||
|
||||
JNIEXPORT jshort JNICALL
|
||||
Java_sun_nio_ch_Net_pollerrValue(JNIEnv *env, jclass this)
|
||||
{
|
||||
return (jshort)POLLERR;
|
||||
}
|
||||
|
||||
JNIEXPORT jshort JNICALL
|
||||
Java_sun_nio_ch_Net_pollhupValue(JNIEnv *env, jclass this)
|
||||
{
|
||||
return (jshort)POLLHUP;
|
||||
}
|
||||
|
||||
JNIEXPORT jshort JNICALL
|
||||
Java_sun_nio_ch_Net_pollnvalValue(JNIEnv *env, jclass this)
|
||||
{
|
||||
return (jshort)POLLNVAL;
|
||||
}
|
||||
|
||||
JNIEXPORT jshort JNICALL
|
||||
Java_sun_nio_ch_Net_pollconnValue(JNIEnv *env, jclass this)
|
||||
{
|
||||
return (jshort)POLLOUT;
|
||||
}
|
||||
|
||||
|
||||
/* Declared in nio_util.h */
|
||||
|
||||
jint
|
||||
handleSocketError(JNIEnv *env, jint errorValue)
|
||||
{
|
||||
char *xn;
|
||||
switch (errorValue) {
|
||||
case EINPROGRESS: /* Non-blocking connect */
|
||||
return 0;
|
||||
#ifdef EPROTO
|
||||
case EPROTO:
|
||||
xn = JNU_JAVANETPKG "ProtocolException";
|
||||
break;
|
||||
#endif
|
||||
case ECONNREFUSED:
|
||||
xn = JNU_JAVANETPKG "ConnectException";
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
xn = JNU_JAVANETPKG "ConnectException";
|
||||
break;
|
||||
case EHOSTUNREACH:
|
||||
xn = JNU_JAVANETPKG "NoRouteToHostException";
|
||||
break;
|
||||
case EADDRINUSE: /* Fall through */
|
||||
case EADDRNOTAVAIL:
|
||||
xn = JNU_JAVANETPKG "BindException";
|
||||
break;
|
||||
default:
|
||||
xn = JNU_JAVANETPKG "SocketException";
|
||||
break;
|
||||
}
|
||||
errno = errorValue;
|
||||
JNU_ThrowByNameWithLastError(env, xn, "NioSocketError");
|
||||
return IOS_THROWN;
|
||||
}
|
102
src/java.base/unix/native/libnio/ch/PollArrayWrapper.c
Normal file
102
src/java.base/unix/native/libnio/ch/PollArrayWrapper.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2005, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_PollArrayWrapper.h"
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define RESTARTABLE(_cmd, _result) do { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while(0)
|
||||
|
||||
static int
|
||||
ipoll(struct pollfd fds[], unsigned int nfds, int timeout)
|
||||
{
|
||||
jlong start, now;
|
||||
int remaining = timeout;
|
||||
struct timeval t;
|
||||
int diff;
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
start = t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
|
||||
for (;;) {
|
||||
int res = poll(fds, nfds, remaining);
|
||||
if (res < 0 && errno == EINTR) {
|
||||
if (remaining >= 0) {
|
||||
gettimeofday(&t, NULL);
|
||||
now = t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
diff = now - start;
|
||||
remaining -= diff;
|
||||
if (diff < 0 || remaining <= 0) {
|
||||
return 0;
|
||||
}
|
||||
start = now;
|
||||
}
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_PollArrayWrapper_poll0(JNIEnv *env, jobject this,
|
||||
jlong address, jint numfds,
|
||||
jlong timeout)
|
||||
{
|
||||
struct pollfd *a;
|
||||
int err = 0;
|
||||
|
||||
a = (struct pollfd *) jlong_to_ptr(address);
|
||||
|
||||
if (timeout <= 0) { /* Indefinite or no wait */
|
||||
RESTARTABLE (poll(a, numfds, timeout), err);
|
||||
} else { /* Bounded wait; bounded restarts */
|
||||
err = ipoll(a, numfds, timeout);
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Poll failed");
|
||||
}
|
||||
return (jint)err;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_PollArrayWrapper_interrupt(JNIEnv *env, jobject this, jint fd)
|
||||
{
|
||||
int fakebuf[1];
|
||||
fakebuf[0] = 1;
|
||||
if (write(fd, fakebuf, 1) < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env,
|
||||
"Write to interrupt fd failed");
|
||||
}
|
||||
}
|
121
src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c
Normal file
121
src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2016, 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 <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#if __linux__
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#if defined(__solaris__) && !defined(_SOCKLEN_T)
|
||||
typedef size_t socklen_t; /* New in SunOS 5.7, so need this for 5.6 */
|
||||
#endif
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "net_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_ServerSocketChannelImpl.h"
|
||||
#include "nio.h"
|
||||
#include "nio_util.h"
|
||||
|
||||
|
||||
static jfieldID fd_fdID; /* java.io.FileDescriptor.fd */
|
||||
static jclass isa_class; /* java.net.InetSocketAddress */
|
||||
static jmethodID isa_ctorID; /* .InetSocketAddress(InetAddress, int) */
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv *env, jclass c)
|
||||
{
|
||||
jclass cls;
|
||||
|
||||
cls = (*env)->FindClass(env, "java/io/FileDescriptor");
|
||||
CHECK_NULL(cls);
|
||||
fd_fdID = (*env)->GetFieldID(env, cls, "fd", "I");
|
||||
CHECK_NULL(fd_fdID);
|
||||
|
||||
cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
|
||||
CHECK_NULL(cls);
|
||||
isa_class = (*env)->NewGlobalRef(env, cls);
|
||||
if (isa_class == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return;
|
||||
}
|
||||
isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"(Ljava/net/InetAddress;I)V");
|
||||
CHECK_NULL(isa_ctorID);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv *env, jobject this,
|
||||
jobject ssfdo, jobject newfdo,
|
||||
jobjectArray isaa)
|
||||
{
|
||||
jint ssfd = (*env)->GetIntField(env, ssfdo, fd_fdID);
|
||||
jint newfd;
|
||||
SOCKETADDRESS sa;
|
||||
socklen_t sa_len = sizeof(SOCKETADDRESS);
|
||||
jobject remote_ia = 0;
|
||||
jobject isa;
|
||||
jint remote_port = 0;
|
||||
|
||||
/*
|
||||
* accept connection but ignore ECONNABORTED indicating that
|
||||
* a connection was eagerly accepted but was reset before
|
||||
* accept() was called.
|
||||
*/
|
||||
for (;;) {
|
||||
newfd = accept(ssfd, &sa.sa, &sa_len);
|
||||
if (newfd >= 0) {
|
||||
break;
|
||||
}
|
||||
if (errno != ECONNABORTED) {
|
||||
break;
|
||||
}
|
||||
/* ECONNABORTED => restart accept */
|
||||
}
|
||||
|
||||
if (newfd < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return IOS_UNAVAILABLE;
|
||||
if (errno == EINTR)
|
||||
return IOS_INTERRUPTED;
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Accept failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
(*env)->SetIntField(env, newfdo, fd_fdID, newfd);
|
||||
remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
|
||||
CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
|
||||
isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
|
||||
CHECK_NULL_RETURN(isa, IOS_THROWN);
|
||||
(*env)->SetObjectArrayElement(env, isaa, 0, isa);
|
||||
return 1;
|
||||
}
|
94
src/java.base/unix/native/libnio/ch/SocketChannelImpl.c
Normal file
94
src/java.base/unix/native/libnio/ch/SocketChannelImpl.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2010, 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 <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
|
||||
#if __linux__
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "net_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_SocketChannelImpl.h"
|
||||
#include "nio_util.h"
|
||||
#include "nio.h"
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
|
||||
jobject fdo, jboolean block,
|
||||
jboolean ready)
|
||||
{
|
||||
int error = 0;
|
||||
socklen_t n = sizeof(int);
|
||||
jint fd = fdval(env, fdo);
|
||||
int result = 0;
|
||||
struct pollfd poller;
|
||||
|
||||
poller.revents = 1;
|
||||
if (!ready) {
|
||||
poller.fd = fd;
|
||||
poller.events = POLLOUT;
|
||||
poller.revents = 0;
|
||||
result = poll(&poller, 1, block ? -1 : 0);
|
||||
if (result < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Poll failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
if (!block && (result == 0))
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (poller.revents) {
|
||||
errno = 0;
|
||||
result = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n);
|
||||
if (result < 0) {
|
||||
handleSocketError(env, errno);
|
||||
return JNI_FALSE;
|
||||
} else if (error) {
|
||||
handleSocketError(env, error);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_SocketChannelImpl_sendOutOfBandData(JNIEnv* env, jclass this,
|
||||
jobject fdo, jbyte b)
|
||||
{
|
||||
int n = send(fdval(env, fdo), (const void*)&b, 1, MSG_OOB);
|
||||
return convertReturnVal(env, n, JNI_FALSE);
|
||||
}
|
34
src/java.base/unix/native/libnio/ch/SocketDispatcher.c
Normal file
34
src/java.base/unix/native/libnio/ch/SocketDispatcher.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2009, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
|
||||
/* this is a fake c file to make the build happy since there is no
|
||||
real SocketDispatcher.c file on Solaris but there is on windows. */
|
||||
|
||||
static jfieldID fd_fdID; /* for jint 'fd' in java.io.FileDescriptor */
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2009, 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 "sun_nio_ch_UnixAsynchronousServerSocketChannelImpl.h"
|
||||
|
||||
extern void Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv* env,
|
||||
jclass c);
|
||||
|
||||
extern jint Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv* env,
|
||||
jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa);
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs(JNIEnv* env,
|
||||
jclass c)
|
||||
{
|
||||
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(env, c);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0(JNIEnv* env,
|
||||
jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa)
|
||||
{
|
||||
return Java_sun_nio_ch_ServerSocketChannelImpl_accept0(env, this,
|
||||
ssfdo, newfdo, isaa);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2010, 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 <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "net_util.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_nio_ch_UnixAsynchronousSocketChannelImpl.h"
|
||||
#include "nio_util.h"
|
||||
#include "nio.h"
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect(JNIEnv *env,
|
||||
jobject this, int fd)
|
||||
{
|
||||
int error = 0;
|
||||
socklen_t arglen = sizeof(error);
|
||||
int result;
|
||||
|
||||
result = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &arglen);
|
||||
if (result < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "getsockopt");
|
||||
} else {
|
||||
if (error)
|
||||
handleSocketError(env, error);
|
||||
}
|
||||
}
|
65
src/java.base/unix/native/libnio/ch/nio_util.h
Normal file
65
src/java.base/unix/native/libnio/ch/nio_util.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2016, 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define RESTARTABLE(_cmd, _result) do { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while(0)
|
||||
|
||||
/* Defines SO_REUSEPORT */
|
||||
#ifndef SO_REUSEPORT
|
||||
#ifdef __linux__
|
||||
#define SO_REUSEPORT 15
|
||||
#elif __solaris__
|
||||
#define SO_REUSEPORT 0x100e
|
||||
#elif defined(AIX) || defined(MACOSX)
|
||||
#define SO_REUSEPORT 0x0200
|
||||
#else
|
||||
#define SO_REUSEPORT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* NIO utility procedures */
|
||||
|
||||
|
||||
/* Defined in IOUtil.c */
|
||||
|
||||
jint fdval(JNIEnv *env, jobject fdo);
|
||||
|
||||
jint convertReturnVal(JNIEnv *env, jint n, jboolean reading);
|
||||
jlong convertLongReturnVal(JNIEnv *env, jlong n, jboolean reading);
|
||||
|
||||
|
||||
/* Defined in Net.c */
|
||||
|
||||
jint handleSocketError(JNIEnv *env, jint errorValue);
|
Loading…
Add table
Add a link
Reference in a new issue