diff options
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java | 3 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java | 38 |
2 files changed, 22 insertions, 19 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java index e6408dc3cc..1600190a11 100644 --- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java +++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java @@ -14,7 +14,6 @@ package com.google.devtools.build.lib.sandbox; -import com.google.common.io.Files; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -81,7 +80,7 @@ interface SandboxedSpawn { // have already been created, but the spawn outputs may be different from the overall action // outputs. This is the case for test actions. target.getParentDirectory().createDirectoryAndParents(); - Files.move(source.getPathFile(), target.getPathFile()); + FileSystemUtils.moveFile(source, target); } else if (source.isDirectory()) { try { source.renameTo(target); diff --git a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java b/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java index b7fd8d2a43..999c470c8b 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java @@ -409,26 +409,35 @@ public class FileSystemUtils { } /** - * Moves the file from location "from" to location "to", while overwriting a - * potentially existing "to". File's last modified time, executable and - * writable bits are also preserved. + * Moves the file from location "from" to location "to", while overwriting a potentially existing + * "to". If "from" is a regular file, its last modified time, executable and writable bits are + * also preserved. Symlinks are also supported but not directories or special files. * - * <p>If no error occurs, the method returns normally. If a parent directory does - * not exist, a FileNotFoundException is thrown. An IOException is thrown when - * other erroneous situations occur. (e.g. read errors) + * <p>If no error occurs, the method returns normally. If a parent directory does not exist, a + * FileNotFoundException is thrown. {@link IOException} is thrown when other erroneous situations + * occur. (e.g. read errors) */ - @ThreadSafe // but not atomic + @ThreadSafe // but not atomic public static void moveFile(Path from, Path to) throws IOException { - long mtime = from.getLastModifiedTime(); - boolean writable = from.isWritable(); - boolean executable = from.isExecutable(); - // We don't try-catch here for better performance. to.delete(); try { from.renameTo(to); } catch (IOException e) { - asByteSource(from).copyTo(asByteSink(to)); + // Fallback to a copy. + FileStatus stat = from.stat(Symlinks.NOFOLLOW); + if (stat.isFile()) { + asByteSource(from).copyTo(asByteSink(to)); + to.setLastModifiedTime(stat.getLastModifiedTime()); // Preserve mtime. + if (!from.isWritable()) { + to.setWritable(false); // Make file read-only if original was read-only. + } + to.setExecutable(from.isExecutable()); // Copy executable bit. + } else if (stat.isSymbolicLink()) { + to.createSymbolicLink(from.readSymbolicLink()); + } else { + throw new IOException("Don't know how to copy " + from); + } if (!from.delete()) { if (!to.delete()) { throw new IOException("Unable to delete " + to); @@ -436,11 +445,6 @@ public class FileSystemUtils { throw new IOException("Unable to delete " + from); } } - to.setLastModifiedTime(mtime); // Preserve mtime. - if (!writable) { - to.setWritable(false); // Make file read-only if original was read-only. - } - to.setExecutable(executable); // Copy executable bit. } /** |