Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions com/etsy/net/JUDS.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ public class JUDS {
/**
* A constant for the datagram socket type (connectionless).
*/
public static final int SOCK_DGRAM = 0;
public static final int SOCK_DGRAM;

/**
* A constant for the stream oriented stream socket type (connection-based)
*/
public static final int SOCK_STREAM = 1;
public static final int SOCK_STREAM;
public static final int SOCK_SEQPACKET;


public static final int SERVER = 0;
public static final int CLIENT = 1;

Expand Down Expand Up @@ -60,6 +60,11 @@ public class JUDS {
}
jarURL = prepared;
}

UnixDomainSocket.staticInit();
SOCK_DGRAM = UnixDomainSocket.nativeGetSocketType("SOCK_DGRAM");
SOCK_STREAM = UnixDomainSocket.nativeGetSocketType("SOCK_STREAM");
SOCK_SEQPACKET = UnixDomainSocket.nativeGetSocketType("SOCK_SEQPACKET");
}

private static ClassLoader judsCl = new URLClassLoader(
Expand Down
51 changes: 41 additions & 10 deletions com/etsy/net/UnixDomainSocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@
#define ASSERTNOERR(cond, msg) do { \
if (cond) { fprintf(stderr, "[%d] ", errno); perror(msg); return -1; }} while(0)

/* In the class UnixDomainSocket SOCK_DGRAM and SOCK_STREAM correspond to the
* constant values 0 and 1; SOCK_TYPE replaces them with the respective macro */
#define SOCK_TYPE(type) ((type) == 0 ? SOCK_DGRAM : SOCK_STREAM)


#ifndef SUN_LEN
#define SUN_LEN(su) \
Expand Down Expand Up @@ -56,13 +52,13 @@ Java_com_etsy_net_UnixDomainSocket_nativeCreate(JNIEnv * jEnv,
socklen_t salen = sockaddr_init(socketFile, &sa);

/* create the socket */
s = socket(PF_UNIX, SOCK_TYPE(jSocketType), 0);
s = socket(PF_UNIX, jSocketType, 0);
ASSERTNOERR(s == -1, "nativeCreate: socket");

/* bind to the socket; here the socket file is created */
ASSERTNOERR(bind(s, (struct sockaddr *)&sa, salen) == -1,
"nativeCreate: bind");
if (SOCK_TYPE(jSocketType) == SOCK_STREAM) {
if (jSocketType == SOCK_STREAM || jSocketType == SOCK_SEQPACKET) {
ASSERTNOERR(listen(s, 0) == -1, "nativeCreate: listen");
s = accept(s, (struct sockaddr *)&sa, &salen);
ASSERTNOERR(s == -1, "nativeCreate: accept");
Expand All @@ -88,13 +84,13 @@ Java_com_etsy_net_UnixDomainSocket_nativeListen(JNIEnv * jEnv,
socklen_t salen = sockaddr_init(socketFile, &sa);

/* create the socket */
s = socket(PF_UNIX, SOCK_TYPE(jSocketType), 0);
s = socket(PF_UNIX, jSocketType, 0);
ASSERTNOERR(s == -1, "nativeListen: socket");

/* bind to the socket; here the socket file is created */
ASSERTNOERR(bind(s, (struct sockaddr *)&sa, salen) == -1,
"nativeListen: bind");
if (SOCK_TYPE(jSocketType) == SOCK_STREAM) {
if (jSocketType == SOCK_STREAM) {
ASSERTNOERR(listen(s, jBacklog) == -1, "nativeListen: listen");
}

Expand All @@ -113,7 +109,7 @@ Java_com_etsy_net_UnixDomainSocket_nativeAccept(JNIEnv * jEnv,
int s = -1; /* socket file handle */

ASSERTNOERR(jSocketFileHandle == -1, "nativeAccept: socket");
if (SOCK_TYPE(jSocketType) == SOCK_STREAM) {
if (jSocketType == SOCK_STREAM) {
s = accept(jSocketFileHandle, NULL, 0);
ASSERTNOERR(s == -1, "nativeAccept: accept");
}
Expand All @@ -135,7 +131,7 @@ Java_com_etsy_net_UnixDomainSocket_nativeOpen(JNIEnv * jEnv,
(*jEnv)->GetStringUTFChars(jEnv, jSocketFile, NULL);
socklen_t salen = sockaddr_init(socketFile, &sa);

s = socket(PF_UNIX, SOCK_TYPE(jSocketType), 0);
s = socket(PF_UNIX, jSocketType, 0);
ASSERTNOERR(s == -1, "nativeOpen: socket");
if (connect(s, (struct sockaddr *)&sa, salen) == -1) {
perror("nativeOpen: connect");
Expand Down Expand Up @@ -249,3 +245,38 @@ Java_com_etsy_net_UnixDomainSocket_nativeUnlink(JNIEnv * jEnv,

return ret;
}


#define CMP_ASN(ret,sock,sockStr) (-1!=(ret=(0==strcmp(#sock,sockStr))?sock:-1))

JNIEXPORT jint JNICALL Java_com_etsy_net_UnixDomainSocket_nativeGetSocketType
(JNIEnv * jEnv, jclass cls, jstring jSocketType){
int ret=-1;
const char *socketType=(*jEnv)->GetStringUTFChars(jEnv, jSocketType, NULL);
do{
#ifdef SOCK_STREAM
if(CMP_ASN(ret,SOCK_STREAM,socketType)) break;
#endif
#ifdef SOCK_DGRAM
if(CMP_ASN(ret,SOCK_DGRAM,socketType)) break;
#endif
#ifdef SOCK_RAW
if(CMP_ASN(ret,SOCK_RAW,socketType)) break;
#endif
#ifdef SOCK_RDM
if(CMP_ASN(ret,SOCK_RDM,socketType)) break;
#endif
#ifdef SOCK_SEQPACKET
if(CMP_ASN(ret,SOCK_SEQPACKET,socketType)) break;
#endif
#ifdef SOCK_DCCP
if(CMP_ASN(ret,SOCK_DCCP,socketType)) break;
#endif
#ifdef SOCK_PACKET
if(CMP_ASN(ret,SOCK_PACKET,socketType)) break;
#endif
}while(0);

(*jEnv)->ReleaseStringUTFChars(jEnv, jSocketType, socketType);
return ret;
}
6 changes: 6 additions & 0 deletions com/etsy/net/UnixDomainSocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public abstract class UnixDomainSocket {

private static File jarFile;
static {
staticInit();
}

static void staticInit(){
// Load the Unix domain socket C library
getJarPath();
try {
Expand Down Expand Up @@ -209,6 +213,8 @@ protected native static int nativeWrite(int nativeSocketFileHandle,

protected native static int nativeUnlink(String socketFile);

protected native static int nativeGetSocketType(String socketType);

protected UnixDomainSocket()
{
// default constructor
Expand Down
38 changes: 38 additions & 0 deletions test/TestUnixDomainSocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ public static void main(String[] args) throws IOException, InterruptedException
System.out.println("Text sent: \"" + text + "\"");
socket.close();

Thread.sleep(2000);

// Testcase 1.3: Test UnixDomainSocketClient with a SEQPACKET socket
socket = new UnixDomainSocketClient(socketFile,JUDS.SOCK_SEQPACKET);
System.out.println("Provoke and catch an "
+ "UnsupportedOperationException:");
try {
in = socket.getInputStream();
} catch (UnsupportedOperationException e) {
System.out.println("UnsupportedOperationException has been "
+ "thrown as expected.");
}
out = socket.getOutputStream();
text = "[3] Hello! I'm the client!";
out.write(text.getBytes());
System.out.println("Text sent: \"" + text + "\"");
socket.close();

Thread.sleep(10);

// Testcase 2.1: Test UnixDomainSocketServer with a stream socket
System.out.println("\nTest #2: Test UnixDomainSocketServer\nTestcase "
Expand Down Expand Up @@ -80,5 +99,24 @@ public static void main(String[] args) throws IOException, InterruptedException
System.out.println("Text received: \"" + new String(b) + "\"");
ssocket.close();
ssocket.unlink();

// Testcase 2.3: Test UnixDomainSocketServer with a datagram socket
System.out.println("Testcase 2.3: Test UnixDomainSocketServer with "
+ "a seqpacket socket...");
ssocket = new UnixDomainSocketServer(socketFile,
JUDS.SOCK_SEQPACKET);
System.out.println("Provoke and catch an "
+ "UnsupportedOperationException:");
in = ssocket.getInputStream();
try {
out = ssocket.getOutputStream();
} catch (UnsupportedOperationException e) {
System.out.println("UnsupportedOperationException has been "
+ "thrown as expected.");
}
in.read(b);
System.out.println("Text received: \"" + new String(b) + "\"");
ssocket.close();
ssocket.unlink();
}
}
26 changes: 26 additions & 0 deletions test/TestUnixDomainSocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ def main():
print ("usage: %s socketfilename" % sys.argv[0])
sys.exit(1)
socket_file = sys.argv[1]
try:
os.unlink(socket_file)
except OSError:
pass

# Testcase 1.1: Test UnixDomainSocketClient with a stream socket
print ("Test #1: Test UnixDomainSocketClient\n"
Expand Down Expand Up @@ -36,6 +40,18 @@ def main():

time.sleep(1) # wait for the server

# Testcase 1.3: Test UnixDomainSocketClient with a seqpacket socket
print ("Testcase 1.3: Test UnixDomainSocketClient with a seqpacket socket...")
s = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
s.bind(socket_file)
s.listen(0)
client, client_address = s.accept()
text = client.recv(BUFSIZE)
print ("Text received: \"%s\"" % text)
s.close()
os.unlink(socket_file)

time.sleep(1) # wait for the server
# Testcase 2.1: Test UnixDomainSocketServer with a stream socket
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(socket_file)
Expand All @@ -56,6 +72,16 @@ def main():
print ("Text sent: \"%s\"" % text)
s.close()

time.sleep(1) # wait for the server

# Testcase 2.3: Test UnixDomainSocketServer with a seqpacket socket
s = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
s.connect(socket_file)
text = "[6] Hello I'm the client!"
s.send(text)
print ("Text sent: \"%s\"" % text)
s.close()


if __name__ == "__main__":
main()