summaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-12-13 06:38:59 +0100
committerSven Gothel <[email protected]>2014-12-13 06:38:59 +0100
commit181dc8ae227cd5cbecf60ab8d973bb8eef7c45f0 (patch)
treed3ec0282c6c2a5196a9f148bf31f091951f09c46 /src/java
parentf26fcc971dc95ffb7033ac9e539a3c0ebb43025a (diff)
Bug 1108 - Fix difficulties to determine executable access permission on Windows via BATCH file execution
Batch file execution test via direct call, i.e.'a.bat', does not work on some Windows machine, not reproducible here! A workaround would be to call the batch file explicit via 'CMD /c a.bat': - works when using 'Software Restriction Policies' (Bug 1015 Comment 2) - does _not_ work when denying ACL "Traverse Folder / Execute File" permission (Bug 1015 Comment 3) Due to this bug, we need to use a native execution: - Performing executable test w/ native exe file instead of batch file on Windows x86 32bit and 64bit, - using [1] TinyPE XP-W8 Compatible - x86 32bit and 64bit - 268 bytes - Tested on: WinXP-32bit, Win7-64bit and Win8-64bit - Author/License: Ange Albertini, BSD Licence, 2010-2013 - On all other Windows machines (ARM, ..), we still use direct execution of 'a.bat' but may add native exe files for missing platforms. +++ This patch injects said binaries within the java jar file and copies it into the 'to be tested' temp folder for execution. [1] TinyPE XP-W8 Compatible - x86 32bit and 64bit - 268 bytes is included within 'src/native/tinype-corkami', build manually and imported as 'src/java/com/jogamp/common/util/bin/exe-windows-i586-268b.bin'. +++
Diffstat (limited to 'src/java')
-rw-r--r--src/java/com/jogamp/common/util/IOUtil.java100
-rw-r--r--src/java/com/jogamp/common/util/bin/exe-windows-i586-268b.binbin0 -> 268 bytes
2 files changed, 79 insertions, 21 deletions
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java
index ac011af..1fd7cbf 100644
--- a/src/java/com/jogamp/common/util/IOUtil.java
+++ b/src/java/com/jogamp/common/util/IOUtil.java
@@ -39,6 +39,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.net.URISyntaxException;
import java.net.URL;
@@ -652,15 +653,19 @@ public class IOUtil {
return null;
}
- private static String getShellSuffix() {
+ private static String getExeTestFileSuffix() {
switch(PlatformPropsImpl.OS_TYPE) {
case WINDOWS:
- return ".bat";
+ if( Platform.CPUFamily.X86 == PlatformPropsImpl.CPU_ARCH.family ) {
+ return ".exe";
+ } else {
+ return ".bat";
+ }
default:
return ".sh";
}
}
- private static String getShellCode() {
+ private static String getExeTestShellCode() {
switch(PlatformPropsImpl.OS_TYPE) {
case WINDOWS:
return "echo off"+PlatformPropsImpl.NEWLINE;
@@ -668,15 +673,71 @@ public class IOUtil {
return null;
}
}
- private static String[] getShellCommandArgs(final String scriptFile) {
+ private static String[] getExeTestCommandArgs(final String scriptFile) {
switch(PlatformPropsImpl.OS_TYPE) {
case WINDOWS:
- return new String[] { "cmd", "/c", scriptFile };
+ // return new String[] { "cmd", "/c", scriptFile };
default:
return new String[] { scriptFile };
}
}
-
+ private static final byte[] getBytesFromRelFile(final byte[] res, final String fname, final int size) throws IOException {
+ final URLConnection con = IOUtil.getResource(IOUtil.class, fname);
+ final InputStream in = con.getInputStream();
+ int numBytes = 0;
+ try {
+ while (true) {
+ final int remBytes = size - numBytes;
+ int count;
+ if ( 0 >= remBytes || (count = in.read(res, numBytes, remBytes)) == -1 ) {
+ break;
+ }
+ numBytes += count;
+ }
+ } finally {
+ in.close();
+ }
+ if( size != numBytes ) {
+ throw new IOException("Got "+numBytes+" bytes != expected "+size);
+ }
+ return res;
+ }
+ private static final Object exeTestBytesLock = new Object();
+ private static WeakReference<byte[]> exeTestBytesRef = null;
+
+ private static void fillExeTestFile(final File exefile) throws IOException {
+ if( Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE &&
+ Platform.CPUFamily.X86 == PlatformPropsImpl.CPU_ARCH.family
+ ) {
+ final int codeSize = 268;
+ final byte[] code;
+ synchronized ( exeTestBytesLock ) {
+ byte[] _code;
+ if( null == exeTestBytesRef || null == ( _code = exeTestBytesRef.get() ) ) {
+ code = getBytesFromRelFile(new byte[512], "bin/exe-windows-i586-268b.bin", codeSize);
+ exeTestBytesRef = new WeakReference<byte[]>(code);
+ } else {
+ code = _code;
+ }
+ }
+ final OutputStream out = new FileOutputStream(exefile);
+ try {
+ out.write(code, 0, codeSize);
+ } finally {
+ out.close();
+ }
+ } else {
+ final String shellCode = getExeTestShellCode();
+ if( isStringSet(shellCode) ) {
+ final FileWriter fout = new FileWriter(exefile);
+ try {
+ fout.write(shellCode);
+ } finally {
+ fout.close();
+ }
+ }
+ }
+ }
private static boolean getOSHasNoexecFS() {
switch(PlatformPropsImpl.OS_TYPE) {
case OPENKODE:
@@ -808,9 +869,9 @@ public class IOUtil {
}
final long t0 = DEBUG ? System.currentTimeMillis() : 0;
- File exetst;
+ final File exeTestFile;
try {
- exetst = File.createTempFile("jogamp_exe_tst", getShellSuffix(), dir);
+ exeTestFile = File.createTempFile("jogamp_exe_tst", getExeTestFileSuffix(), dir);
} catch (final SecurityException se) {
throw se; // fwd Security exception
} catch (final IOException e) {
@@ -821,17 +882,13 @@ public class IOUtil {
}
final long t1 = DEBUG ? System.currentTimeMillis() : 0;
int res = -1;
- if(exetst.setExecutable(true /* exec */, true /* ownerOnly */)) {
- final String shellCode = getShellCode();
+ if(exeTestFile.setExecutable(true /* exec */, true /* ownerOnly */)) {
try {
- if( isStringSet(shellCode) ) {
- final FileWriter fout = new FileWriter(exetst);
- fout.write(shellCode);
- fout.close();
- }
+ fillExeTestFile(exeTestFile);
+
// Using 'Process.exec(String[])' avoids StringTokenizer of 'Process.exec(String)'
// and hence splitting up command by spaces!
- final Process pr = Runtime.getRuntime().exec( getShellCommandArgs( exetst.getCanonicalPath() ) );
+ final Process pr = Runtime.getRuntime().exec( getExeTestCommandArgs( exeTestFile.getCanonicalPath() ) );
/**
* Disable StreamMonitor, which throttles exec-test performance a lot!
*
@@ -846,18 +903,19 @@ public class IOUtil {
} catch (final Throwable t) {
res = -2;
if(DEBUG) {
- System.err.println("IOUtil.testDirExec: <"+exetst.getAbsolutePath()+">: Caught "+t.getClass().getSimpleName()+": "+t.getMessage());
- // t.printStackTrace();
+ System.err.println("IOUtil.testDirExec: <"+exeTestFile.getAbsolutePath()+">: Caught "+t.getClass().getSimpleName()+": "+t.getMessage());
+ t.printStackTrace();
}
}
}
+ final boolean ok = 0 == res;
final long t2 = DEBUG ? System.currentTimeMillis() : 0;
- exetst.delete();
+ exeTestFile.delete();
if( DEBUG) {
- System.err.println("IOUtil.testDirExec(): <"+dir.getAbsolutePath()+">: res "+res);
+ System.err.println("IOUtil.testDirExec(): <"+dir.getAbsolutePath()+">: res "+res+" -> "+ok);
System.err.println("IOUtil.testDirExec(): total "+(t2-t0)+"ms, create "+(t1-t0)+"ms, execute "+(t2-t1)+"ms");
}
- return 0 == res;
+ return ok;
}
private static File testDirImpl(final File dir, final boolean create, final boolean executable, final String dbgMsg)
diff --git a/src/java/com/jogamp/common/util/bin/exe-windows-i586-268b.bin b/src/java/com/jogamp/common/util/bin/exe-windows-i586-268b.bin
new file mode 100644
index 0000000..b0d5f63
--- /dev/null
+++ b/src/java/com/jogamp/common/util/bin/exe-windows-i586-268b.bin
Binary files differ