Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java80
1 files changed, 48 insertions, 32 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java
index 2588daf932..05b645444f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java
@@ -16,6 +16,8 @@ package org.eclipse.swt.internal;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
import java.util.function.*;
import java.util.jar.*;
@@ -136,45 +138,59 @@ public static int SWT_VERSION (int major, int minor) {
return major * 1000 + minor;
}
+private static boolean extractResource(String resourceName, File outFile) {
+ try (InputStream inputStream = Library.class.getResourceAsStream (resourceName)) {
+ if (inputStream == null) return false;
+ Files.copy(inputStream, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ } catch (Throwable e) {
+ return false;
+ }
+
+ return true;
+}
+
/**
- * Extract file with 'mappedName' into path 'extractToFilePath'. Cleanup leftovers if extract failed.
+ * Extract file with 'mappedName' into path 'extractToFilePath'.
+ * Does not overwrite existing file.
+ * Does not leave trash on error.
* @param extractToFilePath full path of where the file is to be extacted to, inc name of file,
* e.g /home/USER/.swt/lib/linux/x86_64/libswt-MYLIB-gtk-4826.so
* @param mappedName file to be searched in jar.
* @return true upon success, failure if something went wrong.
*/
-static boolean extract (String extractToFilePath, String mappedName, StringBuilder message) {
- FileOutputStream os = null;
- InputStream is = null;
+static boolean extract (String extractToFilePath, String mappedName) {
File file = new File(extractToFilePath);
- boolean extracted = false;
+ if (file.exists ()) return true;
+
+ // Write to temp file first, so that other processes don't see
+ // partially written library on disk
+ File tempFile;
try {
- if (!file.exists ()) {
- is = Library.class.getResourceAsStream ("/" + mappedName); //$NON-NLS-1$
- if (is != null) {
- extracted = true;
- int read;
- byte [] buffer = new byte [4096];
- os = new FileOutputStream (extractToFilePath);
- while ((read = is.read (buffer)) != -1) {
- os.write(buffer, 0, read);
- }
- os.close ();
- is.close ();
- chmod ("755", extractToFilePath);
- return true;
- }
- }
+ tempFile = File.createTempFile (file.getName(), ".tmp", file.getParentFile()); //$NON-NLS-1$
} catch (Throwable e) {
- try {
- if (os != null) os.close ();
- } catch (IOException e1) {}
- try {
- if (is != null) is.close ();
- } catch (IOException e1) {}
- if (extracted && file.exists ()) file.delete ();
+ return false;
}
- return false;
+
+ // Extract resource
+ String resourceName = "/" + mappedName; //$NON-NLS-1$
+ if (!extractResource (resourceName, tempFile)) {
+ tempFile.delete();
+ return false;
+ }
+
+ // Make it executable
+ chmod ("755", tempFile.getPath()); //$NON-NLS-1$
+
+ // "Publish" file now that it's ready to use.
+ // If there is a file already, then someone published while we were
+ // extracting, just delete our file and consider it a success.
+ try {
+ Files.move (tempFile.toPath(), file.toPath());
+ } catch (Throwable e) {
+ tempFile.delete();
+ }
+
+ return true;
}
static boolean isLoadable () {
@@ -315,11 +331,11 @@ public static void loadLibrary (String name, boolean mapName) {
/* Try extracting and loading library from jar. */
if (path != null) {
- if (extract (path + SEPARATOR + fileName1, mappedName1, message)) {
+ if (extract (path + SEPARATOR + fileName1, mappedName1)) {
load(path + SEPARATOR + fileName1, message);
return;
}
- if (mapName && extract (path + SEPARATOR + fileName2, mappedName2, message)) {
+ if (mapName && extract (path + SEPARATOR + fileName2, mappedName2)) {
load(path + SEPARATOR + fileName2, message);
return;
}
@@ -448,7 +464,7 @@ public static File findResource(String subDir, String resourceName, boolean mapR
}
StringBuilder message = new StringBuilder("");
- if (extract(file.getPath(), maybeSubDirPath + finalResourceName, message)) {
+ if (extract(file.getPath(), maybeSubDirPath + finalResourceName)) {
if (file.exists()) {
return file;
}

Back to the top