450 lines
13 KiB
Diff
450 lines
13 KiB
Diff
From c9e2b0f565074474613c8fbee6dde86a9fcd2395 Mon Sep 17 00:00:00 2001
|
|
From: Mat Booth <mat.booth@redhat.com>
|
|
Date: Sat, 8 Dec 2018 10:39:47 +0000
|
|
Subject: [PATCH] Add enxio classes from jnr-unixsocket
|
|
|
|
These classes are removed from jnr-unixsocket and packaged here instead
|
|
to avoid split-package problems in OSGi systems.
|
|
---
|
|
.../AbstractNativeDatagramChannel.java | 79 ++++++++++
|
|
.../channels/AbstractNativeSocketChannel.java | 101 +++++++++++++
|
|
src/main/java/jnr/enxio/channels/Common.java | 136 ++++++++++++++++++
|
|
.../enxio/channels/NativeSocketChannel.java | 46 ++----
|
|
4 files changed, 325 insertions(+), 37 deletions(-)
|
|
create mode 100644 src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java
|
|
create mode 100644 src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java
|
|
create mode 100644 src/main/java/jnr/enxio/channels/Common.java
|
|
|
|
diff --git a/src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java b/src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java
|
|
new file mode 100644
|
|
index 0000000..a48d6bc
|
|
--- /dev/null
|
|
+++ b/src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java
|
|
@@ -0,0 +1,79 @@
|
|
+/*
|
|
+ * Copyright (C) 2016 Fritz Elfert
|
|
+ *
|
|
+ * This file is part of the JNR project.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+package jnr.enxio.channels;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.nio.ByteBuffer;
|
|
+import java.nio.channels.ByteChannel;
|
|
+import java.nio.channels.DatagramChannel;
|
|
+import java.nio.channels.spi.SelectorProvider;
|
|
+
|
|
+public abstract class AbstractNativeDatagramChannel extends DatagramChannel
|
|
+ implements ByteChannel, NativeSelectableChannel {
|
|
+
|
|
+ private final Common common;
|
|
+
|
|
+ public AbstractNativeDatagramChannel(int fd) {
|
|
+ this(NativeSelectorProvider.getInstance(), fd);
|
|
+ }
|
|
+
|
|
+ AbstractNativeDatagramChannel(SelectorProvider provider, int fd) {
|
|
+ super(provider);
|
|
+ common = new Common(fd);
|
|
+ }
|
|
+
|
|
+ public void setFD(int fd) {
|
|
+ common.setFD(fd);
|
|
+ }
|
|
+
|
|
+ public final int getFD() {
|
|
+ return common.getFD();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void implCloseSelectableChannel() throws IOException {
|
|
+ Native.close(common.getFD());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void implConfigureBlocking(boolean block) throws IOException {
|
|
+ Native.setBlocking(common.getFD(), block);
|
|
+ }
|
|
+
|
|
+ public int read(ByteBuffer dst) throws IOException {
|
|
+ return common.read(dst);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long read(ByteBuffer[] dsts, int offset,
|
|
+ int length) throws IOException {
|
|
+ return common.read(dsts, offset, length);
|
|
+ }
|
|
+
|
|
+ public int write(ByteBuffer src) throws IOException {
|
|
+ return common.write(src);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long write(ByteBuffer[] srcs, int offset,
|
|
+ int length) throws IOException {
|
|
+ return common.write(srcs, offset, length);
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java b/src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java
|
|
new file mode 100644
|
|
index 0000000..65ead06
|
|
--- /dev/null
|
|
+++ b/src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java
|
|
@@ -0,0 +1,101 @@
|
|
+/*
|
|
+ * Copyright (C) 2016 Marcus Linke
|
|
+ *
|
|
+ * This file is part of the JNR project.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+package jnr.enxio.channels;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.nio.ByteBuffer;
|
|
+import java.nio.channels.ByteChannel;
|
|
+import java.nio.channels.SocketChannel;
|
|
+import java.nio.channels.spi.SelectorProvider;
|
|
+
|
|
+import jnr.constants.platform.Shutdown;
|
|
+
|
|
+public abstract class AbstractNativeSocketChannel extends SocketChannel
|
|
+ implements ByteChannel, NativeSelectableChannel {
|
|
+
|
|
+ private final Common common;
|
|
+
|
|
+ public AbstractNativeSocketChannel(int fd) {
|
|
+ this(NativeSelectorProvider.getInstance(), fd);
|
|
+ }
|
|
+
|
|
+ AbstractNativeSocketChannel(SelectorProvider provider, int fd) {
|
|
+ super(provider);
|
|
+ common = new Common(fd);
|
|
+ }
|
|
+
|
|
+ public void setFD(int fd) {
|
|
+ common.setFD(fd);
|
|
+ }
|
|
+
|
|
+ public final int getFD() {
|
|
+ return common.getFD();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void implCloseSelectableChannel() throws IOException {
|
|
+ Native.close(common.getFD());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void implConfigureBlocking(boolean block) throws IOException {
|
|
+ Native.setBlocking(common.getFD(), block);
|
|
+ }
|
|
+
|
|
+ public int read(ByteBuffer dst) throws IOException {
|
|
+ return common.read(dst);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long read(ByteBuffer[] dsts, int offset,
|
|
+ int length) throws IOException {
|
|
+ return common.read(dsts, offset, length);
|
|
+ }
|
|
+
|
|
+ public int write(ByteBuffer src) throws IOException {
|
|
+ return common.write(src);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long write(ByteBuffer[] srcs, int offset,
|
|
+ int length) throws IOException {
|
|
+ return common.write(srcs, offset, length);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public SocketChannel shutdownInput() throws IOException {
|
|
+ int n = Native.shutdown(common.getFD(), SHUT_RD);
|
|
+ if (n < 0) {
|
|
+ throw new IOException(Native.getLastErrorString());
|
|
+ }
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public SocketChannel shutdownOutput() throws IOException {
|
|
+ int n = Native.shutdown(common.getFD(), SHUT_WR);
|
|
+ if (n < 0) {
|
|
+ throw new IOException(Native.getLastErrorString());
|
|
+ }
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ private static final int SHUT_RD = Shutdown.SHUT_RD.intValue();
|
|
+ private static final int SHUT_WR = Shutdown.SHUT_WR.intValue();
|
|
+}
|
|
diff --git a/src/main/java/jnr/enxio/channels/Common.java b/src/main/java/jnr/enxio/channels/Common.java
|
|
new file mode 100644
|
|
index 0000000..66ac609
|
|
--- /dev/null
|
|
+++ b/src/main/java/jnr/enxio/channels/Common.java
|
|
@@ -0,0 +1,136 @@
|
|
+/*
|
|
+ * Copyright (C) 2016 Fritz Elfert
|
|
+ *
|
|
+ * This file is part of the JNR project.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+package jnr.enxio.channels;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.nio.ByteBuffer;
|
|
+
|
|
+import jnr.constants.platform.Errno;
|
|
+
|
|
+/**
|
|
+ * Helper class, providing common methods.
|
|
+ */
|
|
+final class Common {
|
|
+
|
|
+ private int _fd = -1;
|
|
+
|
|
+ Common(int fd) {
|
|
+ _fd = fd;
|
|
+ }
|
|
+
|
|
+ void setFD(int fd) {
|
|
+ _fd = fd;
|
|
+ }
|
|
+
|
|
+ int getFD() {
|
|
+ return _fd;
|
|
+ }
|
|
+
|
|
+ int read(ByteBuffer dst) throws IOException {
|
|
+
|
|
+ ByteBuffer buffer = ByteBuffer.allocate(dst.remaining());
|
|
+
|
|
+ int n = Native.read(_fd, buffer);
|
|
+
|
|
+ buffer.flip();
|
|
+
|
|
+ dst.put(buffer);
|
|
+
|
|
+ switch (n) {
|
|
+ case 0:
|
|
+ return -1;
|
|
+
|
|
+ case -1:
|
|
+ Errno lastError = Native.getLastError();
|
|
+ switch (lastError) {
|
|
+ case EAGAIN:
|
|
+ case EWOULDBLOCK:
|
|
+ return 0;
|
|
+
|
|
+ default:
|
|
+ throw new IOException(Native.getLastErrorString());
|
|
+ }
|
|
+
|
|
+ default: {
|
|
+
|
|
+ return n;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ long read(ByteBuffer[] dsts, int offset, int length)
|
|
+ throws IOException {
|
|
+ long total = 0;
|
|
+
|
|
+ for (int i = 0; i < length; i++) {
|
|
+ ByteBuffer dst = dsts[offset + i];
|
|
+ long read = read(dst);
|
|
+ if (read == -1) {
|
|
+ return read;
|
|
+ }
|
|
+ total += read;
|
|
+ }
|
|
+
|
|
+ return total;
|
|
+ }
|
|
+
|
|
+ int write(ByteBuffer src) throws IOException {
|
|
+
|
|
+ int r = src.remaining();
|
|
+
|
|
+ ByteBuffer buffer = ByteBuffer.allocate(r);
|
|
+
|
|
+ buffer.put(src);
|
|
+
|
|
+ buffer.position(0);
|
|
+
|
|
+ int n = Native.write(_fd, buffer);
|
|
+
|
|
+ if (n >=0 ) {
|
|
+ if (n < r) {
|
|
+ src.position(src.position()-(r-n));
|
|
+ }
|
|
+ } else {
|
|
+ switch (Native.getLastError()) {
|
|
+ case EAGAIN:
|
|
+ case EWOULDBLOCK:
|
|
+ src.position(src.position()-r);
|
|
+ return 0;
|
|
+ default:
|
|
+ throw new IOException(Native.getLastErrorString());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return n;
|
|
+ }
|
|
+
|
|
+ long write(ByteBuffer[] srcs, int offset, int length)
|
|
+ throws IOException {
|
|
+
|
|
+ long result = 0;
|
|
+ int index = 0;
|
|
+
|
|
+ for (index = offset; index < length; index++) {
|
|
+ result += write(srcs[index]);
|
|
+ }
|
|
+
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/jnr/enxio/channels/NativeSocketChannel.java b/src/main/java/jnr/enxio/channels/NativeSocketChannel.java
|
|
index 445ba1a..082ead1 100644
|
|
--- a/src/main/java/jnr/enxio/channels/NativeSocketChannel.java
|
|
+++ b/src/main/java/jnr/enxio/channels/NativeSocketChannel.java
|
|
@@ -29,7 +29,7 @@ import java.nio.channels.spi.SelectorProvider;
|
|
public class NativeSocketChannel extends AbstractSelectableChannel
|
|
implements ByteChannel, NativeSelectableChannel {
|
|
|
|
- private final int fd;
|
|
+ private final Common common;
|
|
private final int validOps;
|
|
|
|
public NativeSocketChannel(int fd) {
|
|
@@ -42,18 +42,18 @@ public class NativeSocketChannel extends AbstractSelectableChannel
|
|
|
|
NativeSocketChannel(SelectorProvider provider, int fd, int ops) {
|
|
super(provider);
|
|
- this.fd = fd;
|
|
+ common = new Common(fd);
|
|
this.validOps = ops;
|
|
}
|
|
|
|
@Override
|
|
protected void implCloseSelectableChannel() throws IOException {
|
|
- Native.close(fd);
|
|
+ Native.close(common.getFD());
|
|
}
|
|
|
|
@Override
|
|
protected void implConfigureBlocking(boolean block) throws IOException {
|
|
- Native.setBlocking(fd, block);
|
|
+ Native.setBlocking(common.getFD(), block);
|
|
}
|
|
|
|
@Override
|
|
@@ -61,54 +61,26 @@ public class NativeSocketChannel extends AbstractSelectableChannel
|
|
return validOps;
|
|
}
|
|
public final int getFD() {
|
|
- return fd;
|
|
+ return common.getFD();
|
|
}
|
|
|
|
public int read(ByteBuffer dst) throws IOException {
|
|
- int n = Native.read(fd, dst);
|
|
- switch (n) {
|
|
- case 0:
|
|
- return -1;
|
|
-
|
|
- case -1:
|
|
- switch (Native.getLastError()) {
|
|
- case EAGAIN:
|
|
- case EWOULDBLOCK:
|
|
- return 0;
|
|
-
|
|
- default:
|
|
- throw new IOException(Native.getLastErrorString());
|
|
- }
|
|
-
|
|
- default:
|
|
- return n;
|
|
- }
|
|
+ return common.read(dst);
|
|
}
|
|
|
|
public int write(ByteBuffer src) throws IOException {
|
|
- int n = Native.write(fd, src);
|
|
- if (n < 0) {
|
|
- switch (Native.getLastError()) {
|
|
- case EAGAIN:
|
|
- case EWOULDBLOCK:
|
|
- return 0;
|
|
- default:
|
|
- throw new IOException(Native.getLastErrorString());
|
|
- }
|
|
- }
|
|
-
|
|
- return n;
|
|
+ return common.write(src);
|
|
}
|
|
|
|
public void shutdownInput() throws IOException {
|
|
- int n = Native.shutdown(fd, SHUT_RD);
|
|
+ int n = Native.shutdown(common.getFD(), SHUT_RD);
|
|
if (n < 0) {
|
|
throw new IOException(Native.getLastErrorString());
|
|
}
|
|
}
|
|
|
|
public void shutdownOutput() throws IOException {
|
|
- int n = Native.shutdown(fd, SHUT_WR);
|
|
+ int n = Native.shutdown(common.getFD(), SHUT_WR);
|
|
if (n < 0) {
|
|
throw new IOException(Native.getLastErrorString());
|
|
}
|
|
--
|
|
2.19.1
|
|
|