aboutsummaryrefslogtreecommitdiffstats
path: root/src/jniwrap.c
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <[email protected]>2024-01-06 06:07:57 -0600
committerLibravatar bigfoot547 <[email protected]>2024-01-06 06:07:57 -0600
commit2d7d52542df9b925fb0d7786e828421cd731b82b (patch)
tree15c90c29ea5c0f9d1c5111d7a6a25201895c8cb1 /src/jniwrap.c
parentlaunch info all in one place (diff)
launches the game
Diffstat (limited to 'src/jniwrap.c')
-rw-r--r--src/jniwrap.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/jniwrap.c b/src/jniwrap.c
new file mode 100644
index 0000000..ac796b1
--- /dev/null
+++ b/src/jniwrap.c
@@ -0,0 +1,92 @@
+#define L2_JNI__NO_DEFINE_PROXIES
+
+#include "config.h"
+#include "jniwrap.h"
+#include "macros.h"
+#include "command.h"
+
+#include <stddef.h>
+#include <dlfcn.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* this isn't even a little bit thread safe but it is what it is */
+
+jint JNICALL l2_JNI__GetDefaultJavaVMInitArgs_load(void *args);
+jint JNICALL l2_JNI__CreateJavaVM_load(JavaVM **pvm, void **penv, void *args);
+
+l2_JNI__GetDefaultJavaVMInitArgs_t *l2_JNI__GetDefaultJavaVMInitArgs_call = &l2_JNI__GetDefaultJavaVMInitArgs_load;
+l2_JNI__CreateJavaVM_t *l2_JNI__CreateJavaVM_call = &l2_JNI__CreateJavaVM_load;
+
+void *volatile l2_JNI__jnimod = NULL;
+
+int l2_jni__try_load(const char *path)
+{
+ struct stat st;
+ if (stat(path, &st) < 0) {
+ CMD_ERROR("Could not stat %s: %s", path, strerror(errno));
+ return -1;
+ }
+
+ void *thelib = dlopen(path, RTLD_LAZY);
+ if (!thelib) {
+ CMD_ERROR("Failed to load JVM library %s: %s", path, dlerror());
+ return -1;
+ }
+
+ l2_JNI__jnimod = thelib;
+ return 0;
+}
+
+int l2_jni_init(const char *modpath)
+{
+ if (l2_JNI__jnimod) return 0;
+
+ if (l2_jni__try_load(modpath) < 0) {
+ CMD_ERROR0("Could not load JVM library.");
+ return -1;
+ }
+
+ return 0;
+}
+
+typedef void (l2_jni__fsym_unspec)(void);
+
+l2_jni__fsym_unspec *l2_jni__try_load_sym(const char *sym)
+{
+ void *themod = l2_JNI__jnimod;
+ if (!themod) {
+ CMD_MSG("bug", "JNI function %s called before l2_jni_init!", sym);
+ abort();
+ }
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+ l2_jni__fsym_unspec *thesym = dlsym(themod, sym);
+#pragma GCC diagnostic pop
+
+ if (!thesym) {
+ CMD_ERROR("Could not load JNI symbol %s: %s", sym, dlerror());
+ abort();
+ }
+
+ return thesym;
+}
+
+jint JNICALL l2_JNI__GetDefaultJavaVMInitArgs_load(void *args)
+{
+ l2_JNI__GetDefaultJavaVMInitArgs_t *thesym = (l2_JNI__GetDefaultJavaVMInitArgs_t *)l2_jni__try_load_sym("JNI_GetDefaultJavaVMInitArgs");
+ l2_JNI__GetDefaultJavaVMInitArgs_call = thesym;
+
+ return (*thesym)(args);
+}
+
+jint JNICALL l2_JNI__CreateJavaVM_load(JavaVM **pvm, void **penv, void *args)
+{
+ l2_JNI__CreateJavaVM_t *thesym = (l2_JNI__CreateJavaVM_t *)l2_jni__try_load_sym("JNI_CreateJavaVM");
+ l2_JNI__CreateJavaVM_call = thesym;
+
+ return (*thesym)(pvm, penv, args);
+}