diff --git a/api/src/org/labkey/api/reports/ExternalScriptEngine.java b/api/src/org/labkey/api/reports/ExternalScriptEngine.java index ebbcda4c263..452070b797c 100644 --- a/api/src/org/labkey/api/reports/ExternalScriptEngine.java +++ b/api/src/org/labkey/api/reports/ExternalScriptEngine.java @@ -444,6 +444,7 @@ protected File writeScriptFile(String script, ScriptContext context, List replacem for (File src : param.getFiles()) { File dst = new File(cacheDir, src.getName()); - if (src.exists() && dst.createNewFile()) + if (src.exists() && FileUtil.createTempFile(dst)) { FileUtil.copyFile(src, dst); diff --git a/api/src/org/labkey/api/reports/report/ScriptReport.java b/api/src/org/labkey/api/reports/report/ScriptReport.java index 6fcbdf733f6..08cefb86590 100644 --- a/api/src/org/labkey/api/reports/report/ScriptReport.java +++ b/api/src/org/labkey/api/reports/report/ScriptReport.java @@ -189,6 +189,7 @@ public File _createInputDataFile(@NotNull ViewContext context, ResultsFactory fa try (TSVGridWriter tsv = new TSVGridWriter(srf, dataColumns)) { tsv.setColumnHeaderType(ColumnHeaderType.Name); // CONSIDER: Use FieldKey instead + FileUtil.createTempFile(resultFile); tsv.write(resultFile); } } diff --git a/api/src/org/labkey/api/reports/report/python/IpynbReport.java b/api/src/org/labkey/api/reports/report/python/IpynbReport.java index 336efb12bb8..7fed670292b 100644 --- a/api/src/org/labkey/api/reports/report/python/IpynbReport.java +++ b/api/src/org/labkey/api/reports/report/python/IpynbReport.java @@ -193,6 +193,7 @@ public HttpView renderReport(ViewContext context) throws Exception var descriptor = getDescriptor(); String script = descriptor.getProperty(ScriptReportDescriptor.Prop.script); File scriptFile = new File(workingDirectory, FileUtil.makeLegalName(descriptor.getReportName()) + ".ipynb"); + FileUtil.createTempFile(scriptFile); IOUtil.copyCompletely(new StringReader(script), new FileWriter(scriptFile, StringUtilsLabKey.DEFAULT_CHARSET)); Set beforeExecute = new HashSet<>(FileUtils.listFiles(workingDirectory, null, true)); @@ -304,6 +305,7 @@ private static void extractTar(InputStream in, File targetDirectory) throws IOEx } else { + FileUtil.createTempFile(path); try (FileOutputStream os = new FileOutputStream(path)) { IOUtils.copy(tar, os); diff --git a/api/src/org/labkey/api/reports/report/r/RserveScriptEngine.java b/api/src/org/labkey/api/reports/report/r/RserveScriptEngine.java index fcd4a03f04c..1b3da3936df 100644 --- a/api/src/org/labkey/api/reports/report/r/RserveScriptEngine.java +++ b/api/src/org/labkey/api/reports/report/r/RserveScriptEngine.java @@ -253,16 +253,17 @@ protected void copyWorkingDirectoryFromRemote(RConnection rconn) throws IOExcept File wd = getWorkingDir(getContext()); try { - String[] names = rconn.eval("dir("+ toR(defaultIfBlank(rserveWorkingDirectory, ".")) +", all.files = TRUE, full.names = TRUE, recursive = TRUE, include.dirs = FALSE, no.. = FALSE)").asStrings(); - for (var name : names) + String[] paths = rconn.eval("dir("+ toR(defaultIfBlank(rserveWorkingDirectory, ".")) +", all.files = TRUE, full.names = TRUE, recursive = TRUE, include.dirs = FALSE, no.. = FALSE)").asStrings(); + for (var remotePath : paths) { - if ("input_data.tsv".equalsIgnoreCase(name)) + if ("input_data.tsv".equalsIgnoreCase(remotePath)) continue; - if ("script.R".equalsIgnoreCase(name)) + if ("script.R".equalsIgnoreCase(remotePath)) continue; - new File(wd,name).getParentFile().mkdirs(); - try (InputStream is = rconn.openFile(name); - FileOutputStream fos = new FileOutputStream(new File(wd,name))) + File file = new File(wd,remotePath); + FileUtil.createTempFile(file); + try (InputStream is = rconn.openFile(remotePath); + FileOutputStream fos = new FileOutputStream(file)) { IOUtil.copyCompletely(is, fos); } diff --git a/api/src/org/labkey/api/util/FileUtil.java b/api/src/org/labkey/api/util/FileUtil.java index f9fc3455428..0fab6967c3a 100644 --- a/api/src/org/labkey/api/util/FileUtil.java +++ b/api/src/org/labkey/api/util/FileUtil.java @@ -53,11 +53,15 @@ import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; +import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -66,6 +70,7 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -1220,6 +1225,24 @@ public static File createTempFile(@Nullable String prefix, @Nullable String suff return path.toFile(); } + + private static final boolean isPosix = + FileSystems.getDefault().supportedFileAttributeViews().contains("posix"); + final static private FileAttribute[] tempFileAttributes = new FileAttribute[] { PosixFilePermissions.asFileAttribute(Set.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)) }; + + public static boolean createTempFile(File file) throws IOException + { + if (file.exists()) + return false; + file.getParentFile().mkdirs(); + if (isPosix) + Files.createFile(file.toPath(), tempFileAttributes); + else + Files.createFile(file.toPath()); + return true; + } + + public static void deleteTempFile(File f) { if (null != f && f.isFile())