aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2017-10-20 02:26:00 +0200
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2017-10-20 14:04:05 +0200
commit33700d64d665f1d708cedf0e6ca660d758392fb1 (patch)
treed61b36a4f84492c76dfe365fec9d29c61ab826f9 /src/main/java/com/google
parentd9a1a43d2a25245e53e2d2ea6a844f138b722272 (diff)
Make UnionFileSystem eagerly resolve symlinks.
This allows symlinks between multiple different file systems. InMemoryFileSystem uses this in some tests. This CL will allow deletion of ScopeEscapableFileSystem, one of two file systems that partially duplicate what UnionFileSystem does. PiperOrigin-RevId: 172823391
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/UnionFileSystem.java84
1 files changed, 72 insertions, 12 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/UnionFileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/UnionFileSystem.java
index 4a0148e90e..cab13a12b1 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/UnionFileSystem.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/UnionFileSystem.java
@@ -173,12 +173,18 @@ public class UnionFileSystem extends FileSystem {
@Override
public String getFileSystemType(Path path) {
+ try {
+ path = internalResolveSymlink(path);
+ } catch (IOException e) {
+ return "unknown";
+ }
FileSystem delegate = getDelegate(path);
return delegate.getFileSystemType(path);
}
@Override
protected byte[] getDigest(Path path, HashFunction hashFunction) throws IOException {
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
return delegate.getDigest(adjustPath(path, delegate), hashFunction);
}
@@ -199,6 +205,7 @@ public class UnionFileSystem extends FileSystem {
FileSystem delegate = getDelegate(path);
Path parent = path.getParentDirectory();
if (parent != null) {
+ parent = internalResolveSymlink(parent);
FileSystem parentDelegate = getDelegate(parent);
if (parentDelegate != delegate) {
// There's a possibility it already exists on the parent, so don't die
@@ -211,8 +218,9 @@ public class UnionFileSystem extends FileSystem {
@Override
protected long getFileSize(Path path, boolean followSymlinks) throws IOException {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
FileSystem delegate = getDelegate(path);
- return delegate.getFileSize(adjustPath(path, delegate), followSymlinks);
+ return delegate.getFileSize(adjustPath(path, delegate), false);
}
@Override
@@ -224,12 +232,14 @@ public class UnionFileSystem extends FileSystem {
@Override
protected long getLastModifiedTime(Path path, boolean followSymlinks) throws IOException {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
FileSystem delegate = getDelegate(path);
- return delegate.getLastModifiedTime(adjustPath(path, delegate), followSymlinks);
+ return delegate.getLastModifiedTime(adjustPath(path, delegate), false);
}
@Override
protected void setLastModifiedTime(Path path, long newTime) throws IOException {
+ path = internalResolveSymlink(path);
checkModifiable(path);
FileSystem delegate = getDelegate(path);
delegate.setLastModifiedTime(adjustPath(path, delegate), newTime);
@@ -244,20 +254,35 @@ public class UnionFileSystem extends FileSystem {
@Override
protected boolean isDirectory(Path path, boolean followSymlinks) {
+ try {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
+ } catch (IOException e) {
+ return false;
+ }
FileSystem delegate = getDelegate(path);
- return delegate.isDirectory(adjustPath(path, delegate), followSymlinks);
+ return delegate.isDirectory(adjustPath(path, delegate), false);
}
@Override
protected boolean isFile(Path path, boolean followSymlinks) {
+ try {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
+ } catch (IOException e) {
+ return false;
+ }
FileSystem delegate = getDelegate(path);
- return delegate.isFile(adjustPath(path, delegate), followSymlinks);
+ return delegate.isFile(adjustPath(path, delegate), false);
}
@Override
protected boolean isSpecialFile(Path path, boolean followSymlinks) {
+ try {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
+ } catch (IOException e) {
+ return false;
+ }
FileSystem delegate = getDelegate(path);
- return delegate.isSpecialFile(adjustPath(path, delegate), followSymlinks);
+ return delegate.isSpecialFile(adjustPath(path, delegate), false);
}
@Override
@@ -274,14 +299,20 @@ public class UnionFileSystem extends FileSystem {
@Override
protected boolean exists(Path path, boolean followSymlinks) {
+ try {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
+ } catch (IOException e) {
+ return false;
+ }
FileSystem delegate = getDelegate(path);
- return delegate.exists(adjustPath(path, delegate), followSymlinks);
+ return delegate.exists(adjustPath(path, delegate), false);
}
@Override
- protected FileStatus stat(final Path path, final boolean followSymlinks) throws IOException {
+ protected FileStatus stat(Path path, boolean followSymlinks) throws IOException {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
FileSystem delegate = getDelegate(path);
- return delegate.stat(adjustPath(path, delegate), followSymlinks);
+ return delegate.stat(adjustPath(path, delegate), false);
}
// Needs to be overridden for the delegation logic, because the
@@ -289,15 +320,21 @@ public class UnionFileSystem extends FileSystem {
// More generally, we wish to delegate all filesystem operations.
@Override
protected FileStatus statNullable(Path path, boolean followSymlinks) {
+ try {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
+ } catch (IOException e) {
+ return null;
+ }
FileSystem delegate = getDelegate(path);
- return delegate.statNullable(adjustPath(path, delegate), followSymlinks);
+ return delegate.statNullable(adjustPath(path, delegate), false);
}
@Override
@Nullable
protected FileStatus statIfFound(Path path, boolean followSymlinks) throws IOException {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
FileSystem delegate = getDelegate(path);
- return delegate.statIfFound(adjustPath(path, delegate), followSymlinks);
+ return delegate.statIfFound(adjustPath(path, delegate), false);
}
/**
@@ -308,12 +345,14 @@ public class UnionFileSystem extends FileSystem {
*/
@Override
protected Collection<Path> getDirectoryEntries(Path path) throws IOException {
+ Path origPath = path;
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
Path resolvedPath = adjustPath(path, delegate);
Collection<Path> entries = resolvedPath.getDirectoryEntries();
Collection<Path> result = Lists.newArrayListWithCapacity(entries.size());
for (Path entry : entries) {
- result.add(path.getChild(entry.getBaseName()));
+ result.add(origPath.getChild(entry.getBaseName()));
}
return result;
}
@@ -321,18 +360,21 @@ public class UnionFileSystem extends FileSystem {
// No need for the more complex logic of getDirectoryEntries; it calls it implicitly.
@Override
protected Collection<Dirent> readdir(Path path, boolean followSymlinks) throws IOException {
+ path = followSymlinks ? internalResolveSymlink(path) : path;
FileSystem delegate = getDelegate(path);
- return delegate.readdir(adjustPath(path, delegate), followSymlinks);
+ return delegate.readdir(adjustPath(path, delegate), false);
}
@Override
protected boolean isReadable(Path path) throws IOException {
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
return delegate.isReadable(adjustPath(path, delegate));
}
@Override
protected void setReadable(Path path, boolean readable) throws IOException {
+ path = internalResolveSymlink(path);
checkModifiable(path);
FileSystem delegate = getDelegate(path);
delegate.setReadable(adjustPath(path, delegate), readable);
@@ -343,6 +385,7 @@ public class UnionFileSystem extends FileSystem {
if (!supportsModifications(path)) {
return false;
}
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
return delegate.isWritable(adjustPath(path, delegate));
}
@@ -350,18 +393,21 @@ public class UnionFileSystem extends FileSystem {
@Override
protected void setWritable(Path path, boolean writable) throws IOException {
checkModifiable(path);
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
delegate.setWritable(adjustPath(path, delegate), writable);
}
@Override
protected boolean isExecutable(Path path) throws IOException {
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
return delegate.isExecutable(adjustPath(path, delegate));
}
@Override
protected void setExecutable(Path path, boolean executable) throws IOException {
+ path = internalResolveSymlink(path);
checkModifiable(path);
FileSystem delegate = getDelegate(path);
delegate.setExecutable(adjustPath(path, delegate), executable);
@@ -369,24 +415,28 @@ public class UnionFileSystem extends FileSystem {
@Override
protected byte[] getFastDigest(Path path, HashFunction hashFunction) throws IOException {
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
return delegate.getFastDigest(adjustPath(path, delegate), hashFunction);
}
@Override
protected byte[] getxattr(Path path, String name) throws IOException {
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
return delegate.getxattr(adjustPath(path, delegate), name);
}
@Override
protected InputStream getInputStream(Path path) throws IOException {
+ path = internalResolveSymlink(path);
FileSystem delegate = getDelegate(path);
return delegate.getInputStream(adjustPath(path, delegate));
}
@Override
protected OutputStream getOutputStream(Path path, boolean append) throws IOException {
+ path = internalResolveSymlink(path);
checkModifiable(path);
FileSystem delegate = getDelegate(path);
return delegate.getOutputStream(adjustPath(path, delegate), append);
@@ -394,6 +444,7 @@ public class UnionFileSystem extends FileSystem {
@Override
protected void renameTo(Path sourcePath, Path targetPath) throws IOException {
+ sourcePath = internalResolveSymlink(sourcePath);
FileSystem sourceDelegate = getDelegate(sourcePath);
if (!sourceDelegate.supportsModifications(sourcePath)) {
throw new UnsupportedOperationException(
@@ -428,6 +479,7 @@ public class UnionFileSystem extends FileSystem {
protected void createFSDependentHardLink(Path linkPath, Path originalPath) throws IOException {
checkModifiable(linkPath);
+ originalPath = internalResolveSymlink(originalPath);
FileSystem originalDelegate = getDelegate(originalPath);
FileSystem linkDelegate = getDelegate(linkPath);
@@ -439,4 +491,12 @@ public class UnionFileSystem extends FileSystem {
linkDelegate.createFSDependentHardLink(
adjustPath(linkPath, linkDelegate), adjustPath(originalPath, originalDelegate));
}
+
+ private Path internalResolveSymlink(Path path) throws IOException {
+ while (isSymbolicLink(path)) {
+ PathFragment pathFragment = resolveOneLink(path);
+ path = path.getRelative(pathFragment);
+ }
+ return path;
+ }
}