diff options
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.java | 80 |
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; } |