Skip to content

Commit

Permalink
[Truffle] Initial implementation of File.symlink?
Browse files Browse the repository at this point in the history
nirvdrum committed Jan 3, 2015
1 parent 9d8cf7f commit b6a6cba
Showing 2 changed files with 35 additions and 1 deletion.
35 changes: 35 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/core/FileNodes.java
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import jnr.posix.FileStat;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.core.RubyArray;
@@ -442,6 +443,40 @@ public Object read(RubyString file) {

}

@CoreMethod(names = "symlink?", onSingleton = true, required = 1)
public abstract static class SymlinkQueryNode extends CoreMethodNode {

public SymlinkQueryNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public SymlinkQueryNode(SymlinkQueryNode prev) {
super(prev);
}

@Specialization
public boolean symlinkQuery(RubyString fileName) {
notDesignedForCompilation();

try {
// Note: We can't use file.exists() to check whether the symlink
// exists or not, because that method returns false for existing
// but broken symlink. So, we try without the existence check,
// but in the try-catch block.
// MRI behavior: symlink? on broken symlink should return true.
FileStat stat = getContext().getRuntime().getPosix().allocateStat();

if (getContext().getRuntime().getPosix().lstat(fileName.toString(), stat) < 0) {
stat = null;
}

return (stat != null && stat.isSymlink());
} catch (SecurityException re) {
return false;
}
}
}

@CoreMethod(names = "write", required = 1)
public abstract static class WriteNode extends CoreMethodNode {

1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/symlink_tags.txt
Original file line number Diff line number Diff line change
@@ -6,4 +6,3 @@ fails:File.symlink raises an ArgumentError if not called with two arguments
fails:File.symlink raises a TypeError if not called with String types
fails:File.symlink? returns true if the file is a link
fails:File.symlink? accepts an object that has a #to_path method
fails:File.symlink? returns false if the file does not exist

0 comments on commit b6a6cba

Please sign in to comment.