JNIEXPORT jint JNICALL Java_com_etsy_net_UnixDomainSocket_nativeRead(JNIEnv * jEnv, jclass jClass, jint jSocketFileHandle, jbyteArray jbarr, jint off, jint len) { ssize_t count; jbyte *cbarr = (*jEnv)->GetByteArrayElements(jEnv, jbarr, NULL); ASSERTNOERR(cbarr == NULL, "nativeRead: GetByteArrayElements"); /* read up to len bytes from the socket into the buffer */ count = read(jSocketFileHandle, &cbarr[off], len); ASSERTNOERR(count == -1, "nativeRead: read"); (*jEnv)->ReleaseByteArrayElements(jEnv, jbarr, cbarr, 0); // end of stream ( 0 in 'C' API should be -1 in java.io.InputStream API ) if ( count == 0 ) { count = -1; } /* return the number of bytes read */ return count; }
JNIEXPORT jint JNICALL Java_com_etsy_net_UnixDomainSocket_nativeListen(JNIEnv * jEnv, jclass jClass, jstring jSocketFile, jint jSocketType, jint jBacklog) { int s; /* socket file handle */ struct sockaddr_un sa; const char *socketFile = (*jEnv)->GetStringUTFChars(jEnv, jSocketFile, NULL); socklen_t salen = sockaddr_init(socketFile, &sa); /* create the socket */ s = socket(PF_UNIX, SOCK_TYPE(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) { ASSERTNOERR(listen(s, jBacklog) == -1, "nativeListen: listen"); } (*jEnv)->ReleaseStringUTFChars(jEnv, jSocketFile, socketFile); /* return the listening socket file handle */ return s; }
JNIEXPORT jint JNICALL Java_com_etsy_net_UnixDomainSocket_nativeOpen(JNIEnv * jEnv, jclass jClass, jstring jSocketFile, jint jSocketType) { int s; /* socket file handle */ struct sockaddr_un sa; const char *socketFile = (*jEnv)->GetStringUTFChars(jEnv, jSocketFile, NULL); socklen_t salen = sockaddr_init(socketFile, &sa); s = socket(PF_UNIX, SOCK_TYPE(jSocketType), 0); ASSERTNOERR(s == -1, "nativeOpen: socket"); if (connect(s, (struct sockaddr *)&sa, salen) == -1) { perror("nativeOpen: connect"); int close_ = close(s); ASSERTNOERR(close_ == -1, "nativeOpen: close connect error socket"); return -1; } (*jEnv)->ReleaseStringUTFChars(jEnv, jSocketFile, socketFile); /* return the socket file handle */ return s; }
JNIEXPORT jint JNICALL Java_com_etsy_net_UnixDomainSocket_nativeAccept(JNIEnv * jEnv, jclass jClass, jint jSocketFileHandle, jint jSocketType) { int s = -1; /* socket file handle */ ASSERTNOERR(jSocketFileHandle == -1, "nativeAccept: socket"); if (SOCK_TYPE(jSocketType) == SOCK_STREAM) { s = accept(jSocketFileHandle, NULL, 0); ASSERTNOERR(s == -1, "nativeAccept: accept"); } /* return the socket file handle */ return s; }
__attribute__((unused)) static void fstest_task(void) { int chan; char path[PATH_MAX+1]; printf("path_max test\n"); memset(path, 'a', PATH_MAX); path[PATH_MAX] = 0; printf(" mkchan: %d\n", mkchan(ROOT_DIRFD, path)); printf(" open: %d\n", chan=open(ROOT_DIRFD, path)); printf(" rmchan: %d\n", rmchan(ROOT_DIRFD, path)); printf(" close: %d\n", close(chan)); for(int i=0; i<100; ++i) { sprintf(path, "/tmp/test%d", i); ASSERTNOERR(mkchan(ROOT_DIRFD, path)); ASSERTNOERR(chan=open(ROOT_DIRFD, path)); ASSERTNOERR(rmchan(ROOT_DIRFD, path)); ASSERTNOERR(close(chan)); } }
JNIEXPORT jint JNICALL Java_com_etsy_net_UnixDomainSocket_nativeWrite(JNIEnv * jEnv, jclass jClass, jint jSocketFileHandle, jbyteArray jbarr, jint off, jint len) { ssize_t count; jbyte *cbarr = (*jEnv)->GetByteArrayElements(jEnv, jbarr, NULL); ASSERTNOERR(cbarr == NULL, "nativeWrite: GetByteArrayElements"); /* try to write len bytes from the buffer to the socket */ count = write(jSocketFileHandle, &cbarr[off], len); ASSERTNOERR(count == -1, "nativeWrite: write"); (*jEnv)->ReleaseByteArrayElements(jEnv, jbarr, cbarr, JNI_ABORT); /* return the number of bytes written */ return count; }
JNIEXPORT jint JNICALL Java_com_etsy_net_UnixDomainSocket_nativeOpen(JNIEnv * jEnv, jclass jClass, jstring jSocketFile, jint jSocketType) { int s; /* socket file handle */ struct sockaddr_un sa; struct timeval timeout; const char *socketFile = (*jEnv)->GetStringUTFChars(jEnv, jSocketFile, NULL); socklen_t salen = sockaddr_init(socketFile, &sa); s = socket(PF_UNIX, SOCK_TYPE(jSocketType), 0); ASSERTNOERR(s == -1, "nativeOpen: socket"); if (connect(s, (struct sockaddr *)&sa, salen) == -1) { perror("nativeOpen: connect"); int close_ = close(s); ASSERTNOERR(close_ == -1, "nativeOpen: close connect error socket"); return -1; } timeout.tv_sec = 10; timeout.tv_usec = 0; if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) { perror("nativeOpen: setsockopt SO_RCVTIMEO failed"); } if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) { perror("nativeOpen: setsockopt SO_SNDTIMEO failed"); } (*jEnv)->ReleaseStringUTFChars(jEnv, jSocketFile, socketFile); /* return the socket file handle */ return s; }