Skip to content

Instantly share code, notes, and snippets.

@denismakogon
Created August 30, 2022 18:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save denismakogon/2ab0e294cb27be21c06ed19f62aa7efe to your computer and use it in GitHub Desktop.
Save denismakogon/2ab0e294cb27be21c06ed19f62aa7efe to your computer and use it in GitHub Desktop.
package com.panama.examples;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Arrays;
import static java.lang.foreign.ValueLayout.ADDRESS;
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
public class Handler {
private static final MethodHandle callback$mh;
private static MemorySession ms;
static {
System.load(System.getProperty("lib.path"));
try {
callback$mh = MethodHandles
.lookup()
.findStatic(Handler.class,
"callback",
MethodType.methodType(void.class, Addressable.class));
} catch (IllegalAccessException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
static final Linker linker = Linker.nativeLinker();
private static final SymbolLookup linkerLookup = linker.defaultLookup();
private static final SymbolLookup systemLookup = SymbolLookup.loaderLookup();
private static final SymbolLookup symbolLookup = name ->
systemLookup.lookup(name).or(() -> linkerLookup.lookup(name));
static final MethodHandle nativeFunctionWithCallback = symbolLookup.lookup("start")
.map(add -> linker.downcallHandle(add, FunctionDescriptor.ofVoid(ADDRESS))
).orElseThrow();
static void callback(Addressable ma) {
var memorySegment = MemorySegment.ofAddress(
(MemoryAddress) ma, 8192, ms);
var arr = memorySegment.toArray(JAVA_BYTE);
System.out.printf("Data received! Raw content: %s\n", Arrays.toString(arr));
}
public static void main(String[] args) throws Throwable {
ms = MemorySession.openConfined();
MemorySession asFinal = ms;
try(asFinal) {
MemorySegment callbackNativeSymbol = linker.upcallStub(
callback$mh, FunctionDescriptor.ofVoid(ADDRESS), ms);
nativeFunctionWithCallback.invokeExact((Addressable) callbackNativeSymbol);
}
}
}
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#define SERVER_SOCK_FILE "fn.sock"
void handle_function(char* data) {
printf ("recvfrom: %s\n", data);
}
int start(void (*handler)(char*) ) {
int fd;
struct sockaddr_un addr;
int ret;
char buff[8192];
struct sockaddr_un from;
int ok = 1;
int len;
socklen_t fromlen = sizeof(from);
if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) {
perror("socket");
ok = 0;
}
if (ok) {
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, SERVER_SOCK_FILE);
unlink(SERVER_SOCK_FILE);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
ok = 0;
}
}
while ((len = recvfrom(fd, buff, 8192, 0, (struct sockaddr *)&from, &fromlen)) > 0) {
handler(buff);
strcpy (buff, "transmit good!");
ret = sendto(fd, buff, strlen(buff)+1, 0, (struct sockaddr *)&from, fromlen);
if (ret < 0) {
perror("sendto");
break;
}
}
if (fd >= 0) {
close(fd);
}
return 0;
}
int main() {
return start(handle_function);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment