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

Petri Hintukainen phintuka at users.sourceforge.net
Tue Jan 17 10:06:20 CET 2017


Ping

Can I apply this patch with following changes:
- BD_DEBUG removed from child process
- exit() changed to _exit() (do we need this ?)

We  need this patch to git. The second patch was already committed, 
and the code doesn't compile without _java_home_macos().

pe, 2016-12-09 kello 15:26 +0200, Petri Hintukainen kirjoitti:
> to, 2016-12-08 kello 03:47 +0100, Marvin Scholz kirjoitti:
> > 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.
> > 	---
> > It turned out the previous patchset actually still did work fine in
> > all cases, so this one does not use popen/pclose at all anymore,
> > which hopefully works in all cases.
> > 
> > Additionally the check if JLI was loaded properly was done the
> > other
> > way around, so it would log that it was not able to load JLI when
> > it
> > actually was, which is fixed in this version of the second patch.
> > 
> >  src/libbluray/bdj/bdj.c | 89
> > +++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 89 insertions(+)
> > 
> > diff --git a/src/libbluray/bdj/bdj.c b/src/libbluray/bdj/bdj.c
> > index d3d4c43..1a03be6 100644
> > --- a/src/libbluray/bdj/bdj.c
> > +++ b/src/libbluray/bdj/bdj.c
> > @@ -39,6 +39,13 @@
> >  #include <stdlib.h>
> >  #include <string.h>
> >  
> > +#ifdef __APPLE__
> > +#include <sys/types.h>
> > +#include <sys/wait.h>
> > +#include <limits.h>
> > +#include <unistd.h>
> > +#endif
> > +
> >  #ifdef _WIN32
> >  #include <windows.h>
> >  #include <winreg.h>
> > @@ -174,6 +181,75 @@ static inline char *_utf8_to_cp(const char
> > *utf8)
> >  }
> >  #endif
> >  
> > +#if defined(__APPLE__) && !defined(HAVE_BDJ_J2ME)
> > +
> > +#define MACOS_JAVA_HOME "/usr/libexec/java_home"
> > +static char *_java_home_macos()
> > +{
> > +    static char result[PATH_MAX] = "";
> > +
> > +    if (result[0])
> > +        return result;
> > +
> > +    pid_t java_home_pid;
> > +    int fd[2], exitcode;
> > +
> > +    if (pipe(fd)) {
> > +        BD_DEBUG(DBG_BDJ | DBG_CRIT, "unable to set up pipes\n");
> > +        return NULL;
> > +    }
> > +
> > +    switch (java_home_pid = vfork())
> 
> I must say I don't like the idea of forking in library. But if there
> are no other ways around the problem ... I don't like running Java VM
> in library either :).
> 
> > +    {
> > +        case -1:
> > +            BD_DEBUG(DBG_BDJ | DBG_CRIT, "vfork failed\n");
> > +            return NULL;
> > +
> > +        case 0:
> > +            if (dup2(fd[1], STDOUT_FILENO) == -1) {
> > +                BD_DEBUG(DBG_BDJ | DBG_CRIT, "unable to dup2
> > fd[1]\n");
> 
> You can't log anything here. It may deadlock or clobber parent
> process
> state. If you want to log child process errors you need to signal the
> error with _exit() and log the message in the parent process.
> 
> > +                exit(-1);
> 
> Should this be _exit() ?
> 
> man vfork:
> "(From POSIX.1) The vfork() function has the same effect as fork(2),
> except that the behavior is undefined if the process created by
> vfork()
> either modifies any data other than a variable of type pid_t used to
> store the return value from vfork(), or returns from the function in
> which vfork() was called, or calls any other function before
> successfully calling _exit(2) or one of the exec(3) family of
> functions."
> 
> > +            }
> > +
> > +            close(fd[1]);
> > +            close(fd[0]);
> > +
> > +            execl(MACOS_JAVA_HOME, MACOS_JAVA_HOME);
> > +
> > +            BD_DEBUG(DBG_BDJ | DBG_CRIT,
> > +                     "unable to execute " MACOS_JAVA_HOME "\n");
> > +
> > +            exit(-1);
> > +
> > +        default:
> > +            close(fd[1]);
> > +
> > +            for (int len = 0; ;) {
> > +                int n = read(fd[0], result + len, sizeof result -
> > len);
> > +                if (n <= 0)
> > +                    break;
> > +
> > +                len += n;
> > +                result[len-1] = '\0';
> > +            }
> > +
> > +            waitpid(java_home_pid, &exitcode, 0);
> > +    }
> > +
> > +    if (result[0] == '\0' || exitcode) {
> > +        BD_DEBUG(DBG_BDJ | DBG_CRIT,
> > +                 "Unable to read path from " MACOS_JAVA_HOME
> > "\n");
> > +        result[0] = '\0';
> > +        return NULL;
> > +    }
> > +
> > +    BD_DEBUG(DBG_BDJ, "macos java home: '%s'\n", result );
> > +    return result;
> > +}
> > +#undef MACOS_JAVA_HOME
> > +
> > +#endif
> > +
> >  static void *_jvm_dlopen(const char *java_home, const char
> > *jvm_dir,
> > const char *jvm_lib)
> >  {
> >      if (java_home) {
> > @@ -210,6 +286,10 @@ 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";
> > +#  else
> >      static const char *jvm_path[] = {NULL, JDK_HOME,
> >                                       "/usr/lib/jvm/default-java",
> >                                       "/usr/lib/jvm/default",
> > @@ -220,6 +300,7 @@ static void *_load_jvm(const char
> > **p_java_home)
> >                                       "/usr/lib/jvm/java-6-
> > openjdk",
> >      };
> >      static const char  jvm_dir[]  = "jre/lib/" JAVA_ARCH
> > "/server";
> > +#  endif
> >      static const char  jvm_lib[]  = "libjvm";
> >  # endif
> >  #endif
> > @@ -241,6 +322,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 */


More information about the libbluray-devel mailing list