Try to use HOME directory as tmp directory if tmp is noexec

This commit is contained in:
Will Hedgecock 2022-01-10 10:23:04 -06:00
parent 1de0dc509f
commit 3c17081439
1 changed files with 90 additions and 67 deletions

View File

@ -59,15 +59,21 @@ public final class SerialPort
// Determine the temporary file directory for Java and remove any previous versions of this library // Determine the temporary file directory for Java and remove any previous versions of this library
String OS = System.getProperty("os.name").toLowerCase(), arch = System.getProperty("os.arch").toLowerCase(); String OS = System.getProperty("os.name").toLowerCase(), arch = System.getProperty("os.arch").toLowerCase();
String libraryPath = "", fileName = "", backupLibraryPath = ""; String libraryPath = "", fileName = "", backupLibraryPath = "";
String tempFileDirectory = System.getProperty("java.io.tmpdir"); String tempFileDirectory = System.getProperty("java.io.tmpdir"), userHomeDirectory = System.getProperty("user.home");
if (!tempFileDirectory.endsWith("\\") && !tempFileDirectory.endsWith("/")) if (!tempFileDirectory.endsWith("\\") && !tempFileDirectory.endsWith("/"))
tempFileDirectory += "/"; tempFileDirectory += "/";
if (!userHomeDirectory.endsWith("\\") && !userHomeDirectory.endsWith("/"))
userHomeDirectory += "/";
// Make sure to use appId to separate tmpdir directories if library is used by multiple modules so they don't erase each others' folders // Make sure to use appId to separate tmpdir directories if library is used by multiple modules so they don't erase each others' folders
tempFileDirectory += "jSerialComm/" + System.getProperty(tmpdirAppIdProperty, ""); tempFileDirectory += "jSerialComm/" + System.getProperty(tmpdirAppIdProperty, "");
userHomeDirectory += ".jSerialComm/" + System.getProperty(tmpdirAppIdProperty, "");
if (!tempFileDirectory.endsWith("\\") && !tempFileDirectory.endsWith("/")) if (!tempFileDirectory.endsWith("\\") && !tempFileDirectory.endsWith("/"))
tempFileDirectory += "/"; tempFileDirectory += "/";
if (!userHomeDirectory.endsWith("\\") && !userHomeDirectory.endsWith("/"))
userHomeDirectory += "/";
deleteDirectory(new File(tempFileDirectory)); deleteDirectory(new File(tempFileDirectory));
deleteDirectory(new File(userHomeDirectory));
// Determine Operating System and architecture // Determine Operating System and architecture
if (System.getProperty("java.vm.vendor").toLowerCase().contains("android")) if (System.getProperty("java.vm.vendor").toLowerCase().contains("android"))
@ -110,7 +116,10 @@ public final class SerialPort
backupLibraryPath = "Windows/x86"; backupLibraryPath = "Windows/x86";
} }
else else
{
libraryPath = "Windows/x86"; libraryPath = "Windows/x86";
backupLibraryPath = "Windows/x86_64";
}
isWindows = true; isWindows = true;
fileName = "jSerialComm.dll"; fileName = "jSerialComm.dll";
} }
@ -279,16 +288,23 @@ public final class SerialPort
// Copy platform-specific binary to a temporary location // Copy platform-specific binary to a temporary location
try try
{
boolean libraryLoaded = false;
for (int attempt = 0; !libraryLoaded && (attempt < 2); ++attempt)
{ {
// Get path of native library and copy file to working directory with open permissions // Get path of native library and copy file to working directory with open permissions
File tempNativeLibrary = new File(tempFileDirectory + (new Date()).getTime() + "-" + fileName); File tempNativeLibrary = new File(((attempt == 0) ? tempFileDirectory : userHomeDirectory) + (new Date()).getTime() + "-" + fileName);
File tempBackupNativeLibrary = new File(tempFileDirectory + (new Date()).getTime() + "-backup-" + fileName); File tempBackupNativeLibrary = new File(((attempt == 0) ? tempFileDirectory : userHomeDirectory) + (new Date()).getTime() + "-backup-" + fileName);
tempNativeLibrary.getParentFile().mkdirs(); if (tempNativeLibrary.getParentFile().mkdirs())
{
tempNativeLibrary.getParentFile().setReadable(true, false); tempNativeLibrary.getParentFile().setReadable(true, false);
tempNativeLibrary.getParentFile().setWritable(true, false); tempNativeLibrary.getParentFile().setWritable(true, false);
tempNativeLibrary.getParentFile().setExecutable(true, false); tempNativeLibrary.getParentFile().setExecutable(true, false);
tempBackupNativeLibrary.deleteOnExit(); tempBackupNativeLibrary.deleteOnExit();
tempNativeLibrary.deleteOnExit(); tempNativeLibrary.deleteOnExit();
}
else
continue;
// Load the native jSerialComm library // Load the native jSerialComm library
InputStream fileContents = SerialPort.class.getResourceAsStream("/" + libraryPath + "/" + fileName); InputStream fileContents = SerialPort.class.getResourceAsStream("/" + libraryPath + "/" + fileName);
@ -313,17 +329,17 @@ public final class SerialPort
destinationFileContents.write(transferBuffer, 0, numBytesRead); destinationFileContents.write(transferBuffer, 0, numBytesRead);
destinationFileContents.close(); destinationFileContents.close();
fileContents.close(); fileContents.close();
tempNativeLibrary.setReadable(true, false); tempNativeLibrary.setReadable(false, false);
tempNativeLibrary.setWritable(true, false); tempNativeLibrary.setWritable(false, false);
tempNativeLibrary.setExecutable(true, false); tempNativeLibrary.setExecutable(true, false);
// Load primary native library // Load primary native library
boolean libraryLoaded = true; libraryLoaded = true;
try { System.load(tempNativeLibrary.getAbsolutePath()); } try { System.load(tempNativeLibrary.getAbsolutePath()); }
catch (UnsatisfiedLinkError e) catch (UnsatisfiedLinkError e)
{ {
libraryLoaded = false; libraryLoaded = false;
if (backupFileContents == null) if ((backupFileContents == null) && (attempt > 0))
throw new UnsatisfiedLinkError("Cannot load native library " + tempNativeLibrary.getAbsolutePath() + " with expected architecture: " + libraryPath); throw new UnsatisfiedLinkError("Cannot load native library " + tempNativeLibrary.getAbsolutePath() + " with expected architecture: " + libraryPath);
} }
@ -338,13 +354,19 @@ public final class SerialPort
destinationFileContents.write(transferBuffer, 0, numBytesRead); destinationFileContents.write(transferBuffer, 0, numBytesRead);
destinationFileContents.close(); destinationFileContents.close();
backupFileContents.close(); backupFileContents.close();
tempBackupNativeLibrary.setReadable(true, false); tempBackupNativeLibrary.setReadable(false, false);
tempBackupNativeLibrary.setWritable(true, false); tempBackupNativeLibrary.setWritable(false, false);
tempBackupNativeLibrary.setExecutable(true, false); tempBackupNativeLibrary.setExecutable(true, false);
// Load backup native library // Load backup native library
libraryLoaded = true;
try { System.load(tempBackupNativeLibrary.getAbsolutePath()); } try { System.load(tempBackupNativeLibrary.getAbsolutePath()); }
catch (UnsatisfiedLinkError e) { throw new UnsatisfiedLinkError("Cannot load native libraries " + tempNativeLibrary.getAbsolutePath() + " or " + tempBackupNativeLibrary.getAbsolutePath() + " with expected architectures: " + libraryPath + " or " + backupLibraryPath); } catch (UnsatisfiedLinkError e)
{
libraryLoaded = false;
if (attempt > 0)
throw new UnsatisfiedLinkError("Cannot load native libraries " + tempNativeLibrary.getAbsolutePath() + " or " + tempBackupNativeLibrary.getAbsolutePath() + " with expected architectures: " + libraryPath + " or " + backupLibraryPath);
}
} }
else else
backupFileContents.close(); backupFileContents.close();
@ -355,6 +377,7 @@ public final class SerialPort
initializeLibrary(); initializeLibrary();
} }
} }
}
catch (Exception e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }
// Add a shutdown hook to ensure all ports get closed // Add a shutdown hook to ensure all ports get closed