aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java38
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.
}
/**