Skip to content

Commit

Permalink
Add forFD functionality to UnixSocketChannel. Fixes #4.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Nov 24, 2015
1 parent 031e2e0 commit a268297
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/main/java/jnr/unixsocket/UnixSocketChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,27 @@ public static final UnixSocketChannel[] pair() throws IOException {
};
}

/**
* Create a UnixSocketChannel to wrap an existing file descriptor (presumably itself a UNIX socket).
*
* @param fd the file descriptor to wrap
* @return the new UnixSocketChannel instance
*/
public static final UnixSocketChannel fromFD(int fd) {
return fromFD(fd, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}

/**
* Create a UnixSocketChannel to wrap an existing file descriptor (presumably itself a UNIX socket).
*
* @param fd the file descriptor to wrap
* @param ops the SelectionKey operations the socket supports
* @return the new UnixSocketChannel instance
*/
public static final UnixSocketChannel fromFD(int fd, int ops) {
return new UnixSocketChannel(fd, ops);
}

private UnixSocketChannel() throws IOException {
super(Native.socket(ProtocolFamily.PF_UNIX, Sock.SOCK_STREAM, 0),
SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
Expand Down
80 changes: 80 additions & 0 deletions src/test/java/jnr/unixsocket/ForFDTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package jnr.unixsocket;

import jnr.constants.platform.ProtocolFamily;
import jnr.constants.platform.Sock;
import junit.framework.Assert;
import org.junit.Test;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;

/**
* Created by headius on 11/24/15.
*/
public class ForFDTest {
private static final File SOCKADDR = new File("/tmp/jnr-unixsocket-forfd" + System.currentTimeMillis() + ".sock");
static { SOCKADDR.deleteOnExit(); }
private static final UnixSocketAddress ADDRESS = new UnixSocketAddress(SOCKADDR);
private static final String FOOBAR = "foobar";

private volatile Exception serverException;

@Test
public void testForFD() throws Exception {
int fd = 0;
UnixSocketChannel channel = null;

try {
final UnixServerSocketChannel server = UnixServerSocketChannel.open();
server.socket().bind(ADDRESS);

new Thread("accept thread") {
public void run() {
UnixSocketChannel channel = null;

try {
channel = server.accept();
channel.write(ByteBuffer.wrap(FOOBAR.getBytes()));
} catch (Exception e) {
serverException = e;
} finally {
try {channel.close();} catch (Exception e) {}
}
}
}.start();

fd = Native.socket(ProtocolFamily.PF_UNIX, Sock.SOCK_STREAM, 0);

assertTrue("socket failed", fd > 0);

int ret = Native.connect(fd, ADDRESS.getStruct(), ADDRESS.getStruct().length());

assertTrue("connect failed", ret >= 0);

channel = UnixSocketChannel.fromFD(fd);

assertNotNull(channel);

ByteBuffer buf = ByteBuffer.allocate(1024);

channel.read(buf);

assertEquals(FOOBAR.length(), buf.position());

buf.flip();
String result = new String(buf.array(), buf.position(), buf.limit(), StandardCharsets.UTF_8);

assertEquals(FOOBAR, result);

if (serverException != null) throw serverException;
} finally {
channel.close();
}
}
}

0 comments on commit a268297

Please sign in to comment.