Skip to content

Commit

Permalink
Showing 3 changed files with 20 additions and 41 deletions.
20 changes: 13 additions & 7 deletions core/src/main/java/org/jruby/RubyFileTest.java
Original file line number Diff line number Diff line change
@@ -36,6 +36,10 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;

import jnr.posix.FileStat;
import org.jruby.anno.JRubyMethod;
@@ -278,21 +282,23 @@ public static IRubyObject sticky_p(IRubyObject recv, IRubyObject filename) {
@JRubyMethod(name = "symlink?", required = 1, module = true)
public static RubyBoolean symlink_p(IRubyObject recv, IRubyObject filename) {
Ruby runtime = recv.getRuntime();
IRubyObject oldExc = runtime.getGlobalVariables().get("$!"); // Save $!


Path p = new File(filename.toString()).toPath();

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 = fileResource(filename).lstat();
BasicFileAttributes attrs = Files.readAttributes(p, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);

return runtime.newBoolean(stat != null && stat.isSymlink());
} catch (SecurityException re) {
return runtime.newBoolean(attrs != null && attrs.isSymbolicLink());
} catch (SecurityException se) {
return runtime.getFalse();
} catch (IOException ie) {
return runtime.getFalse();
} catch (RaiseException re) {
runtime.getGlobalVariables().set("$!", oldExc); // Restore $!
} catch (UnsupportedOperationException uoe) {
return runtime.getFalse();
}
}
9 changes: 7 additions & 2 deletions core/src/main/java/org/jruby/RubyInstanceConfig.java
Original file line number Diff line number Diff line change
@@ -180,9 +180,14 @@ public void tryProcessArgumentsWithRubyopts() {
public void processArgumentsWithRubyopts() {
// environment defaults to System.getenv normally
Object rubyoptObj = environment.get("RUBYOPT");
String rubyopt = rubyoptObj == null ? null : rubyoptObj.toString();

if (rubyopt == null || rubyopt.length() == 0) return;
if (rubyoptObj == null) return;

// Our argument processor bails if an arg starts with space, so we trim the RUBYOPT line
// See #4849
String rubyopt = rubyoptObj.toString().trim();

if (rubyopt.length() == 0) return;

String[] rubyoptArgs = rubyopt.split("\\s+");
if (rubyoptArgs.length != 0) {
32 changes: 0 additions & 32 deletions core/src/main/ruby/jruby/kernel/file.rb
Original file line number Diff line number Diff line change
@@ -122,38 +122,6 @@ def self.symlink(target, link)
0 # Comply with spec
end

# Returns whether or not +file+ is a symlink.
#
def self.symlink?(file)
file = string_check(file)

return false if file =~ /^(classpath:|classloader:|uri:classloader|jar:)/ || !File.exist?(file)

file.slice!(5..-1) if file =~ /^file:/
wfile = file.wincode
attrib = GetFileAttributesW(wfile)

if attrib == INVALID_FILE_ATTRIBUTES
raise SystemCallError.new('GetFileAttributes', FFI.errno)
end

if attrib & FILE_ATTRIBUTE_REPARSE_POINT > 0
begin
find_data = WIN32_FIND_DATA.new
handle = FindFirstFileW(wfile, find_data)

if handle == INVALID_HANDLE_VALUE
raise SystemCallError.new('FindFirstFile', FFI.errno)
end

return true if find_data[:dwReserved0] == IO_REPARSE_TAG_SYMLINK
ensure
CloseHandle(handle)
end
end
false
end

private

# Simulate Ruby's string checking

0 comments on commit 0cd7cf9

Please sign in to comment.