diff options
author | Sven Gothel <[email protected]> | 2013-10-23 16:48:42 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-10-23 16:48:42 +0200 |
commit | fec9712b151ad31b053fe700cb0f809b9715407c (patch) | |
tree | 92201b96715373aa2ac7e13940226864fd65be0d /src/java/com/jogamp/common | |
parent | 55cc188f0f076a046d05a49c1c82bb90ba545117 (diff) |
Fix Bug 865: Safari >= 6.1 [OSX]: May employ xattr on 'com.apple.quarantine' on 'PluginProcess.app'
- IOUtil.getTempDir(..): Don't test executable caps on OSX for java_io_tmpdir
- JarUtil.extract(..): Issue native fixNativeLibAttribs(..) on OSX for native library files,
i.e. remove xattr 'com.apple.quarantine'
Diffstat (limited to 'src/java/com/jogamp/common')
-rw-r--r-- | src/java/com/jogamp/common/util/IOUtil.java | 97 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/JarUtil.java | 28 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/cache/TempFileCache.java | 2 |
3 files changed, 98 insertions, 29 deletions
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java index ef6a633..45cb6ec 100644 --- a/src/java/com/jogamp/common/util/IOUtil.java +++ b/src/java/com/jogamp/common/util/IOUtil.java @@ -1006,9 +1006,15 @@ public class IOUtil { throws SecurityException { if (!testFile(dir, true, true)) { + if(DEBUG) { + System.err.println("IOUtil.testDirExec: <"+dir.getAbsolutePath()+">: Not writeable dir"); + } return false; } if(!getOSHasNoexecFS()) { + if(DEBUG) { + System.err.println("IOUtil.testDirExec: <"+dir.getAbsolutePath()+">: Always executable"); + } return true; } @@ -1023,40 +1029,45 @@ public class IOUtil { } return false; } - int ok = -1; - if(exetst.setExecutable(true)) { + int res = -1; + if(exetst.setExecutable(true /* exec */, true /* ownerOnly */)) { try { Process pr = Runtime.getRuntime().exec(exetst.getCanonicalPath()); pr.waitFor() ; - ok = pr.exitValue(); + res = pr.exitValue(); } catch (SecurityException se) { throw se; // fwd Security exception } catch (Throwable t) { - ok = -2; + res = -2; if(DEBUG) { - System.err.println("IOUtil.testDirExec: <"+exetst.getAbsolutePath()+">: "+t.getMessage()); + System.err.println("IOUtil.testDirExec: <"+exetst.getAbsolutePath()+">: Catched "+t.getClass().getSimpleName()+": "+t.getMessage()); // t.printStackTrace(); } } } exetst.delete(); - return 0 == ok; + if(DEBUG) { + System.err.println("IOUtil.testDirExec(): <"+dir.getAbsolutePath()+">: res "+res); + } + return 0 == res; } - private static File testDirImpl(File dir, boolean create, boolean executable) + private static File testDirImpl(File dir, boolean create, boolean executable, String dbgMsg) throws SecurityException { + final File res; if (create && !dir.exists()) { dir.mkdirs(); } if( executable ) { - if(testDirExec(dir)) { - return dir; - } - } else if(testFile(dir, true, true)) { - return dir; + res = testDirExec(dir) ? dir : null; + } else { + res = testFile(dir, true, true) ? dir : null; } - return null; + if(DEBUG) { + System.err.println("IOUtil.testDirImpl("+dbgMsg+"): <"+dir.getAbsolutePath()+">, create "+create+", exec "+executable+": "+(null != res)); + } + return res; } /** @@ -1076,7 +1087,7 @@ public class IOUtil { public static File testDir(final File dir, final boolean create, final boolean executable) throws SecurityException { - return testDirImpl(dir, create, executable); + return testDirImpl(dir, create, executable, "testDir"); } private static boolean isStringSet(String s) { return null != s && 0 < s.length(); } @@ -1100,18 +1111,19 @@ public class IOUtil { * </p> * @param tmpRoot * @param executable + * @param dbgMsg TODO * @param tmpDirPrefix * @return a temporary directory, writable by this user * @throws SecurityException */ - private static File getSubTempDir(File tmpRoot, String tmpSubDirPrefix, boolean executable) + private static File getSubTempDir(File tmpRoot, String tmpSubDirPrefix, boolean executable, String dbgMsg) throws SecurityException { File tmpBaseDir = null; - if(null != testDirImpl(tmpRoot, true /* create */, executable)) { // check tmpRoot first + if(null != testDirImpl(tmpRoot, true /* create */, executable, dbgMsg)) { // check tmpRoot first for(int i = 0; null == tmpBaseDir && i<=9999; i++) { final String tmpDirSuffix = String.format("_%04d", i); // 4 digits for iteration - tmpBaseDir = testDirImpl(new File(tmpRoot, tmpSubDirPrefix+tmpDirSuffix), true /* create */, executable); + tmpBaseDir = testDirImpl(new File(tmpRoot, tmpSubDirPrefix+tmpDirSuffix), true /* create */, executable, dbgMsg); } } return tmpBaseDir; @@ -1153,13 +1165,25 @@ public class IOUtil { { final File ctxTempDir = AndroidUtils.getTempRoot(); // null if ( !Android || no android-ctx ) if(null != ctxTempDir) { - tempRootNoexec = getSubTempDir(ctxTempDir, tmpSubDir, false /* executable, see below */); + tempRootNoexec = getSubTempDir(ctxTempDir, tmpSubDir, false /* executable, see below */, "Android.ctxTemp"); tempRootExec = tempRootNoexec; // FIXME: Android temp root is always executable (?) return tempRootExec; } } final String java_io_tmpdir = PropertyAccess.getProperty(java_io_tmpdir_propkey, false); + final String user_temp; // only if diff than java_io_tmpdir + { + String _user_temp = System.getenv("TMPDIR"); + if( !isStringSet(_user_temp) ) { + _user_temp = System.getenv("TEMP"); + } + if( isStringSet(_user_temp) && !_user_temp.equals(java_io_tmpdir) ) { + user_temp = _user_temp; + } else { + user_temp = null; + } + } final String user_home = PropertyAccess.getProperty(user_home_propkey, false); final String xdg_cache_home; @@ -1178,41 +1202,58 @@ public class IOUtil { // 1) java.io.tmpdir/jogamp if( null == tempRootExec && isStringSet(java_io_tmpdir) ) { - tempRootExec = getSubTempDir(new File(java_io_tmpdir), tmpSubDir, true /* executable */); + if( Platform.OSType.MACOS == Platform.getOSType() ) { + // Bug 865: Safari >= 6.1 [OSX] May employ xattr on 'com.apple.quarantine' on 'PluginProcess.app' + // We attempt to fix this issue _after_ gluegen native lib is loaded, see JarUtil.fixNativeLibAttribs(File). + tempRootExec = getSubTempDir(new File(java_io_tmpdir), tmpSubDir, false /* executable */, "tempX1"); + } else { + tempRootExec = getSubTempDir(new File(java_io_tmpdir), tmpSubDir, true /* executable */, "tempX1"); + } } // 2) $XDG_CACHE_HOME/jogamp if(null == tempRootExec && isStringSet(xdg_cache_home)) { - tempRootExec = getSubTempDir(new File(xdg_cache_home), tmpSubDir, true /* executable */); + tempRootExec = getSubTempDir(new File(xdg_cache_home), tmpSubDir, true /* executable */, "tempX2"); } - // 3) $HOME/.jogamp - if(null == tempRootExec && isStringSet(user_home)) { - tempRootExec = getSubTempDir(new File(user_home), "." + tmpSubDir, true /* executable */); + // 3) $TMPDIR/jogamp + if(null == tempRootExec && isStringSet(user_temp)) { + tempRootExec = getSubTempDir(new File(user_temp), tmpSubDir, true /* executable */, "tempX3"); } + // 4) $HOME/.jogamp + if(null == tempRootExec && isStringSet(user_home)) { + tempRootExec = getSubTempDir(new File(user_home), "." + tmpSubDir, true /* executable */, "tempX4"); + } if(null != tempRootExec) { tempRootNoexec = tempRootExec; } else { // 1) java.io.tmpdir/jogamp if( null == tempRootNoexec && isStringSet(java_io_tmpdir) ) { - tempRootNoexec = getSubTempDir(new File(java_io_tmpdir), tmpSubDir, false /* executable */); + tempRootNoexec = getSubTempDir(new File(java_io_tmpdir), tmpSubDir, false /* executable */, "temp01"); } // 2) $XDG_CACHE_HOME/jogamp if(null == tempRootNoexec && isStringSet(xdg_cache_home)) { - tempRootNoexec = getSubTempDir(new File(xdg_cache_home), tmpSubDir, false /* executable */); + tempRootNoexec = getSubTempDir(new File(xdg_cache_home), tmpSubDir, false /* executable */, "temp02"); + } + + // 3) $TMPDIR/jogamp + if(null == tempRootNoexec && isStringSet(user_temp)) { + tempRootNoexec = getSubTempDir(new File(user_temp), tmpSubDir, false /* executable */, "temp03"); } - // 3) $HOME/.jogamp + // 4) $HOME/.jogamp if(null == tempRootNoexec && isStringSet(user_home)) { - tempRootNoexec = getSubTempDir(new File(user_home), "." + tmpSubDir, false /* executable */); + tempRootNoexec = getSubTempDir(new File(user_home), "." + tmpSubDir, false /* executable */, "temp04"); } } if(DEBUG) { - System.err.println("IOUtil.getTempRoot(): temp dirs: exec: "+tempRootExec.getAbsolutePath()+", noexec: "+tempRootNoexec.getAbsolutePath()); + final String tempRootExecAbsPath = null != tempRootExec ? tempRootExec.getAbsolutePath() : null; + final String tempRootNoexecAbsPath = null != tempRootNoexec ? tempRootNoexec.getAbsolutePath() : null; + System.err.println("IOUtil.getTempRoot(): temp dirs: exec: "+tempRootExecAbsPath+", noexec: "+tempRootNoexecAbsPath); } } } diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java index 5411d66..b5f8850 100644 --- a/src/java/com/jogamp/common/util/JarUtil.java +++ b/src/java/com/jogamp/common/util/JarUtil.java @@ -47,6 +47,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import com.jogamp.common.os.NativeLibrary; +import com.jogamp.common.os.Platform; import jogamp.common.Debug; @@ -632,6 +633,7 @@ public class JarUtil { if (isNativeLib && ( isRootEntry || !nativeLibMap.containsKey(libBaseName) ) ) { nativeLibMap.put(libBaseName, destFile.getAbsolutePath()); addedAsNativeLib = true; + fixNativeLibAttribs(destFile); } } if (DEBUG) { @@ -643,6 +645,32 @@ public class JarUtil { } /** + * Mitigate file permission issues of native library files, i.e.: + * <ul> + * <li>Bug 865: Safari >= 6.1 [OSX]: May employ xattr on 'com.apple.quarantine' on 'PluginProcess.app'</li> + * </ul> + */ + private final static void fixNativeLibAttribs(File file) { + // We tolerate UnsatisfiedLinkError (and derived) to solve the chicken and egg problem + // of loading gluegen's native library. + // On Safari(OSX), Bug 865, we simply hope the destination folder is executable. + if( Platform.OSType.MACOS == Platform.getOSType() ) { + final String fileAbsPath = file.getAbsolutePath(); + try { + fixNativeLibAttribs(fileAbsPath); + if( DEBUG ) { + System.err.println("JarUtil.fixNativeLibAttribs: "+fileAbsPath+" - OK"); + } + } catch (Throwable t) { + if( DEBUG ) { + System.err.println("JarUtil.fixNativeLibAttribs: "+fileAbsPath+" - "+t.getClass().getSimpleName()+": "+t.getMessage()); + } + } + } + } + private native static boolean fixNativeLibAttribs(String fname); + + /** * Validate the certificates for each native Lib in the jar file. * Throws an IOException if any certificate is not valid. * <pre> diff --git a/src/java/com/jogamp/common/util/cache/TempFileCache.java b/src/java/com/jogamp/common/util/cache/TempFileCache.java index cc7014a..3fd0a59 100644 --- a/src/java/com/jogamp/common/util/cache/TempFileCache.java +++ b/src/java/com/jogamp/common/util/cache/TempFileCache.java @@ -80,7 +80,7 @@ public class TempFileCache { _tmpBaseDir = new File(IOUtil.getTempDir(true /* executable */), tmpDirPrefix); _tmpBaseDir = IOUtil.testDir(_tmpBaseDir, true /* create */, false /* executable */); // executable already checked } catch (Exception ex) { - System.err.println("Warning: Catched Exception while retrieving temp base directory:"); + System.err.println("Warning: Catched Exception while retrieving executable temp base directory:"); ex.printStackTrace(); staticInitError = true; } |