diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 8d1233ab04..b7b5b2d79d 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -77,13 +77,20 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.InvalidPathException; +import java.nio.file.Path; import java.nio.file.LinkOption; import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.EnumSet; import java.util.Enumeration; import java.util.List; import java.util.Map; @@ -113,6 +120,7 @@ import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.input.CountingInputStream; +import org.apache.commons.lang.StringUtils; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.FileSet; @@ -1403,17 +1411,35 @@ public final class FilePath implements Serializable { * @return * The new FilePath pointing to the temporary directory * @since 1.311 - * @see File#createTempFile(String, String) + * @see Files#createTempDirectory(Path, String, FileAttribute[]) */ public FilePath createTempDir(final String prefix, final String suffix) throws IOException, InterruptedException { try { + String[] s; + if (StringUtils.isBlank(suffix)) { + s = new String[]{prefix, "tmp"}; // see File.createTempFile - tmp is used if suffix is null + } else { + s = new String[]{prefix, suffix}; + } + String name = StringUtils.join(s, "."); return new FilePath(this,act(new SecureFileCallable() { private static final long serialVersionUID = 1L; public String invoke(File dir, VirtualChannel channel) throws IOException { - File f = File.createTempFile(prefix, suffix, dir); - f.delete(); - f.mkdir(); - return f.getName(); + + Path tempPath; + final boolean isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix"); + + if (isPosix) { + tempPath = Files.createTempDirectory(Util.fileToPath(dir), name, + PosixFilePermissions.asFileAttribute(EnumSet.allOf(PosixFilePermission.class))); + } else { + tempPath = Files.createTempDirectory(Util.fileToPath(dir), name, new FileAttribute[] {}); + } + + if (tempPath.toFile() == null) { + throw new IOException("Failed to obtain file from path " + dir + " on " + remote); + } + return tempPath.toFile().getName(); } })); } catch (IOException e) { diff --git a/core/src/test/java/hudson/FilePathTest.java b/core/src/test/java/hudson/FilePathTest.java index 846900424e..57815f6618 100644 --- a/core/src/test/java/hudson/FilePathTest.java +++ b/core/src/test/java/hudson/FilePathTest.java @@ -32,18 +32,15 @@ import hudson.util.StreamTaskListener; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.net.ConnectException; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; -import java.net.URLStreamHandlerFactory; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -62,10 +59,16 @@ import org.apache.commons.io.output.NullOutputStream; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Chmod; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.junit.Assume.assumeThat; import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeFalse; + import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -622,7 +625,7 @@ public class FilePathTest { when(con.getResponseCode()) .thenReturn(HttpURLConnection.HTTP_NOT_MODIFIED); - assertFalse(d.installIfNecessaryFrom(url, null, null)); + assertFalse(d.installIfNecessaryFrom(url, null, "")); verify(con).setIfModifiedSince(123000); } @@ -641,7 +644,7 @@ public class FilePathTest { when(con.getInputStream()) .thenReturn(someZippedContent()); - assertTrue(d.installIfNecessaryFrom(url, null, null)); + assertTrue(d.installIfNecessaryFrom(url, null, "")); } @Issue("JENKINS-26196") @@ -759,7 +762,7 @@ public class FilePathTest { // and now fail when flush is bad! tmpDirPath.child("../" + archive.getName()).untar(outDir, TarCompression.NONE); } - + @Test public void chmod() throws Exception { assumeFalse(Functions.isWindows()); @@ -790,7 +793,25 @@ public class FilePathTest { path.chmod(mode); return path.mode(); } - + + @Issue("JENKINS-48227") + @Test + public void testCreateTempDir() throws IOException, InterruptedException { + final File srcFolder = temp.newFolder("src"); + final FilePath filePath = new FilePath(srcFolder); + FilePath x = filePath.createTempDir("jdk", "dmg"); + FilePath y = filePath.createTempDir("jdk", "pkg"); + FilePath z = filePath.createTempDir("jdk", null); + + assertNotNull("FilePath x should not be null", x); + assertNotNull("FilePath y should not be null", y); + assertNotNull("FilePath z should not be null", z); + + assertTrue(x.getName().contains("jdk.dmg")); + assertTrue(y.getName().contains("jdk.pkg")); + assertTrue(z.getName().contains("jdk.tmp")); + } + @Test public void deleteRecursiveOnUnix() throws Exception { assumeFalse("Uses Unix-specific features", Functions.isWindows()); Path targetDir = temp.newFolder("target").toPath();