From 7eea7c0fc3ee544e0d5d7e2274894025b9c3acb9 Mon Sep 17 00:00:00 2001 From: crschnick Date: Tue, 11 Jul 2023 16:56:06 +0000 Subject: [PATCH] Rework temporary directory handling [stage] --- .../io/xpipe/core/process/ShellDialect.java | 2 +- .../core/store/ConnectionFileSystem.java | 4 +- .../core/util/XPipeExecTempDirectory.java | 89 ++++++++++++------- 3 files changed, 61 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/io/xpipe/core/process/ShellDialect.java b/core/src/main/java/io/xpipe/core/process/ShellDialect.java index 77d7e0e3..10b0a62e 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellDialect.java +++ b/core/src/main/java/io/xpipe/core/process/ShellDialect.java @@ -153,7 +153,7 @@ public interface ShellDialect { CommandControl createScriptTextFileWriteCommand(ShellControl parent, String content, String file); - String getFileDeleteCommand(String file); + CommandControl deleteFile(ShellControl sc, String file); CommandControl createFileExistsCommand(ShellControl sc, String file); diff --git a/core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java b/core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java index c1c6f478..b61cafec 100644 --- a/core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java +++ b/core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java @@ -92,9 +92,7 @@ public class ConnectionFileSystem implements FileSystem { @Override public void delete(String file) throws Exception { - try (var pc = shellControl - .command(proc -> proc.getShellDialect().getFileDeleteCommand(file)) - .complex() + try (var pc = shellControl.getShellDialect().deleteFile(shellControl, file) .start()) { pc.discardOrThrow(); } diff --git a/core/src/main/java/io/xpipe/core/util/XPipeExecTempDirectory.java b/core/src/main/java/io/xpipe/core/util/XPipeExecTempDirectory.java index 7611de05..49ef6787 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeExecTempDirectory.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeExecTempDirectory.java @@ -4,6 +4,7 @@ import io.xpipe.core.impl.FileNames; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellControl; +import java.io.IOException; import java.util.Arrays; import java.util.Set; import java.util.UUID; @@ -19,32 +20,62 @@ public class XPipeExecTempDirectory { } public static synchronized String initXPipeTempDirectory(ShellControl proc) throws Exception { - var base = proc.getOsType().getTempDirectory(proc); - var arr = Stream.of(base, "xpipe", "exec").toArray(String[]::new); - var dir = FileNames.join(arr); + var d = proc.getShellDialect(); + var tempBase = proc.getOsType().getTempDirectory(proc); + var xpipeTemp = FileNames.join(tempBase, "xpipe"); + + // Check permissions for system temp directory + if (!checkDirectoryPermissions(proc, tempBase)) { + var home = proc.getOsType().getHomeDirectory(proc); + + // We assume that this exists now as the systemid should have been created in this + var xpipeHome = FileNames.join(home, ".xpipe"); + + if (!d.directoryExists(proc, xpipeHome).executeAndCheck() || !checkDirectoryPermissions(proc, xpipeHome)) { + throw new IOException("No permissions to create scripts in either %s or %s".formatted(tempBase, xpipeHome)); + } + + tempBase = xpipeHome; + xpipeTemp = FileNames.join(tempBase, "temp"); + } + + var execTemp = FileNames.join(xpipeTemp, "exec"); + + // Create and set all access permissions if not existent + if (!d.directoryExists(proc, xpipeTemp).executeAndCheck()) { + d.prepareTempDirectory(proc, xpipeTemp).execute(); + } + + // Check permissions for xpipe directory + // If they don't match, delete it. We can do this as we are guaranteed to have all permissions in the parent directory + else if (!checkDirectoryPermissions(proc, xpipeTemp)) { + d.deleteFile(proc, xpipeTemp).execute(); + d.prepareTempDirectory(proc, xpipeTemp).execute(); + } + + // Create and set all access permissions if not existent + if (!d.directoryExists(proc, execTemp).executeAndCheck()) { + d.prepareTempDirectory(proc, execTemp).execute(); + } + + // Clear directory if it exists and is definitely not in use or the permissions do not match + else if (!usedSystems.contains(proc.getSystemId()) || !checkDirectoryPermissions(proc, execTemp)) { + d.deleteFile(proc, execTemp).execute(); + d.prepareTempDirectory(proc, execTemp).execute(); + } + + usedSystems.add(proc.getSystemId()); + return execTemp; + } + + private static boolean checkDirectoryPermissions(ShellControl proc, String dir) throws Exception { + if (proc.getOsType().equals(OsType.WINDOWS)) { + return true; + } var d = proc.getShellDialect(); - if (proc.getOsType() == OsType.LINUX - && !proc.executeSimpleBooleanCommand("test -r %s && test -w %s && test -x %s" - .formatted(d.fileArgument(base), d.fileArgument(base), d.fileArgument(base)))) { - dir = FileNames.join(Stream.of(proc.getOsType().getHomeDirectory(proc), "xpipe", "exec") - .toArray(String[]::new)); - } - - // We don't want to modify the temp directory if it is possibly in use - if (usedSystems.contains(proc.getSystemId())) { - return dir; - } - - var existsCommand = d.directoryExists(proc, dir); - if (existsCommand.executeAndCheck() && !usedSystems.contains(proc.getSystemId())) { - proc.executeSimpleCommand(d.getFileDeleteCommand(dir)); - } - - d.prepareTempDirectory(proc, dir).execute(); - usedSystems.add(proc.getSystemId()); - - return dir; + return proc.executeSimpleBooleanCommand("test -r %s && test -w %s && test -x %s" + .formatted(d.fileArgument(dir), d.fileArgument(dir), d.fileArgument(dir))); } public static synchronized void occupyXPipeTempDirectory(ShellControl proc) { @@ -52,15 +83,13 @@ public class XPipeExecTempDirectory { } public static String getSubDirectory(ShellControl proc, String... sub) throws Exception { - var base = proc.getOsType().getTempDirectory(proc); - var arr = Stream.concat(Stream.of(base, "xpipe", "exec"), Arrays.stream(sub)) + var base = proc.getSubTemporaryDirectory(); + var arr = Stream.concat(Stream.of(base), Arrays.stream(sub)) .toArray(String[]::new); var dir = FileNames.join(arr); - var existsCommand = proc.getShellDialect().createFileExistsCommand(proc, dir); - if (!existsCommand.executeAndCheck()) { - proc.getShellDialect().prepareTempDirectory(proc, dir).execute(); - } + // We assume that this directory does not exist yet and therefore don't perform any checks + proc.getShellDialect().prepareTempDirectory(proc, dir).execute(); return dir; }