On macOS apparently the only way to get the correct
path to the java home for the currently active SDK as
selected by the user is to use the /usr/libexec/java_home
tool.
---

While in theory this should work, I think, it does not as the
pclose always fails (returns -1) with errno 10 (ECHILD).
I do get the expected path back, but without the correct exit code,
that's not really helpful.

In an isolated example outside of the library it works fine though.
I have no idea what the problem is or how to fix it, but given that the
code is necessary to make libbluray work fine on macOS, I thought I would
still submit it as RFC and hopefully someone else has an idea why it is not
working as I expect it to.

 src/libbluray/bdj/bdj.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/src/libbluray/bdj/bdj.c b/src/libbluray/bdj/bdj.c
index d3d4c43..aebf3f0 100644
--- a/src/libbluray/bdj/bdj.c
+++ b/src/libbluray/bdj/bdj.c
@@ -38,6 +38,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
+#include <errno.h>
 
 #ifdef _WIN32
 #include <windows.h>
@@ -174,6 +176,45 @@ static inline char *_utf8_to_cp(const char *utf8)
 }
 #endif
 
+#if defined(__APPLE__) && !defined(HAVE_BDJ_J2ME)
+static char *_java_home_macos()
+{
+    FILE *fp;
+    int res = 0;
+    static char initialized = 0;
+    static char result[PATH_MAX];
+
+    if (initialized) {
+        return result;
+    }
+
+    fp = popen("/usr/libexec/java_home", "r");
+    if (fp == NULL) {
+        BD_DEBUG(DBG_BDJ | DBG_CRIT, "Failed to run 'java_home'\n");
+        return NULL;
+    }
+
+    if (fgets(result, PATH_MAX, fp) == NULL) {
+        BD_DEBUG(DBG_BDJ | DBG_CRIT, "Failed to read result from 
'java_home'\n");
+        return NULL;
+    }
+    res = pclose(fp);
+    if (res) {
+        int errsv = errno;
+        BD_DEBUG(DBG_BDJ | DBG_CRIT, "Executing 'java_home' not succesfull. 
(%i)\n", res);
+        if (res == -1)
+            BD_DEBUG(DBG_BDJ | DBG_CRIT, "pclose() failed: errno %i\n", errsv);
+        return NULL;
+    }
+    result[strcspn(result, "\n")] = '\0';
+
+    BD_DEBUG(DBG_BDJ, "Path returned from 'java_home': %s\n", result);
+
+    initialized = 1;
+    return result;
+}
+#endif
+
 static void *_jvm_dlopen(const char *java_home, const char *jvm_dir, const 
char *jvm_lib)
 {
     if (java_home) {
@@ -210,6 +251,11 @@ static void *_load_jvm(const char **p_java_home)
     static const char  jvm_dir[]  = "jre\\bin\\server";
     static const char  jvm_lib[]  = "jvm";
 # else
+#  ifdef __APPLE__
+    static const char *jvm_path[] = {NULL, JDK_HOME};
+    static const char  jvm_dir[]  = "jre/lib/server";
+    static const char  jvm_lib[]  = "libjvm";
+#  else
     static const char *jvm_path[] = {NULL, JDK_HOME,
                                      "/usr/lib/jvm/default-java",
                                      "/usr/lib/jvm/default",
@@ -221,6 +267,7 @@ static void *_load_jvm(const char **p_java_home)
     };
     static const char  jvm_dir[]  = "jre/lib/" JAVA_ARCH "/server";
     static const char  jvm_lib[]  = "libjvm";
+#  endif
 # endif
 #endif
     const char *java_home = NULL;
@@ -241,6 +288,14 @@ static void *_load_jvm(const char **p_java_home)
     }
 #endif
 
+#if defined(__APPLE__) && !defined(HAVE_BDJ_J2ME)
+    java_home = _java_home_macos();
+    if (java_home) {
+        *p_java_home = java_home;
+        return _jvm_dlopen(java_home, jvm_dir, jvm_lib);
+    }
+#endif
+
     BD_DEBUG(DBG_BDJ, "JAVA_HOME not set, trying default locations\n");
 
     /* try our pre-defined locations */
-- 
2.9.3 (Apple Git-75)

_______________________________________________
libbluray-devel mailing list
libbluray-devel@videolan.org
https://mailman.videolan.org/listinfo/libbluray-devel

Reply via email to