[libbluray-devel] [PATCH 1/2] [RFC] Get the correct java home on macOS

Marvin Scholz epirat07 at gmail.com
Mon Dec 5 08:23:16 CET 2016


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)



More information about the libbluray-devel mailing list