Introduce Path#readSymbolicLinkUnchecked, intended to only be used when the caller already knows the path is a symlink, and use this new method throughout the codebase.
--
MOS_MIGRATED_REVID=103229983
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java
index 0be5c31..140504e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java
@@ -88,7 +88,7 @@
} else if (statNoFollow.isDirectory()) {
return DIRECTORY_FILE_STATE_NODE;
} else if (statNoFollow.isSymbolicLink()) {
- return new SymlinkFileStateValue(path.readSymbolicLink());
+ return new SymlinkFileStateValue(path.readSymbolicLinkUnchecked());
}
throw new InconsistentFilesystemException("according to stat, existing path " + path + " is "
+ "neither a file nor directory nor symlink.");
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java
index fc5a9e8..bf74b96 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java
@@ -478,6 +478,17 @@
protected abstract PathFragment readSymbolicLink(Path path) throws IOException;
/**
+ * Returns the target of a symbolic link, under the assumption that the given path is indeed a
+ * symbolic link (this assumption permits efficient implementations). See
+ * {@link Path#readSymbolicLinkUnchecked} for specification.
+ *
+ * @throws IOException if the contents of the link could not be read for any reason.
+ */
+ protected PathFragment readSymbolicLinkUnchecked(Path path) throws IOException {
+ return readSymbolicLink(path);
+ }
+
+ /**
* Returns true iff {@code path} denotes an existing file of any kind. See
* {@link Path#exists(Symlinks)} for specification.
*/
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 840433a..7ce6a9a 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
@@ -608,7 +608,7 @@
copyTreesBelow(entry, subDir);
} else if (entry.isSymbolicLink()) {
Path newLink = to.getChild(entry.getBaseName());
- newLink.createSymbolicLink(entry.readSymbolicLink());
+ newLink.createSymbolicLink(entry.readSymbolicLinkUnchecked());
} else {
Path newEntry = to.getChild(entry.getBaseName());
copyFile(entry, newEntry);
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/Path.java b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
index 38a29ac..88e8d3b 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/Path.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
@@ -758,7 +758,7 @@
public void createSymbolicLink(PathFragment target) throws IOException {
fileSystem.createSymbolicLink(this, target);
}
-
+
/**
* Returns the target of the current path, which must be a symbolic link. The
* link contents are returned exactly, and may contain an absolute or relative
@@ -773,6 +773,18 @@
}
/**
+ * If the current path is a symbolic link, returns the target of this symbolic link. The
+ * semantics are intentionally left underspecified otherwise to permit efficient implementations.
+ *
+ * @return the content (i.e. target) of the symbolic link
+ * @throws IOException if the current path is not a symbolic link, or the
+ * contents of the link could not be read for any reason
+ */
+ public PathFragment readSymbolicLinkUnchecked() throws IOException {
+ return fileSystem.readSymbolicLinkUnchecked(this);
+ }
+
+ /**
* Returns the canonical path for this path, by repeatedly replacing symbolic
* links with their referents. Analogous to realpath(3).
*
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/UnixFileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/UnixFileSystem.java
index 2a86b22..74ae375 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/UnixFileSystem.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/UnixFileSystem.java
@@ -329,6 +329,8 @@
@Override
protected PathFragment readSymbolicLink(Path path) throws IOException {
+ // Note that the default implementation of readSymbolicLinkUnchecked calls this method and thus
+ // is optimal since we only make one system call in here.
String name = path.toString();
long startTime = Profiler.nanoTimeMaybe();
try {