summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--file.c16
-rw-r--r--test/ruby/test_file.rb8
-rw-r--r--version.h6
3 files changed, 22 insertions, 8 deletions
diff --git a/file.c b/file.c
index 0e67654da2..f321b57f08 100644
--- a/file.c
+++ b/file.c
@@ -3778,7 +3778,7 @@ enum rb_realpath_mode {
};
static int
-realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
+realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE fallback,
VALUE loopcheck, enum rb_realpath_mode mode, int last)
{
const char *pend = unresolved + strlen(unresolved);
@@ -3841,6 +3841,12 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
#endif
if (ret == -1) {
int e = errno;
+ if (e == ENOENT && !NIL_P(fallback)) {
+ if (rb_stat(fallback, &sbuf) == 0) {
+ rb_str_replace(*resolvedp, fallback);
+ return 0;
+ }
+ }
if (mode == RB_REALPATH_CHECK) return -1;
if (e == ENOENT) {
if (mode == RB_REALPATH_STRICT || !last || *unresolved_firstsep)
@@ -3872,7 +3878,7 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
*resolvedp = link;
*prefixlenp = link_prefixlen;
}
- if (realpath_rec(prefixlenp, resolvedp, link_names,
+ if (realpath_rec(prefixlenp, resolvedp, link_names, testpath,
loopcheck, mode, !*unresolved_firstsep))
return -1;
RB_GC_GUARD(link_orig);
@@ -3960,14 +3966,14 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
loopcheck = rb_hash_new();
if (curdir_names) {
- if (realpath_rec(&prefixlen, &resolved, curdir_names, loopcheck, mode, 0))
+ if (realpath_rec(&prefixlen, &resolved, curdir_names, Qnil, loopcheck, mode, 0))
return Qnil;
}
if (basedir_names) {
- if (realpath_rec(&prefixlen, &resolved, basedir_names, loopcheck, mode, 0))
+ if (realpath_rec(&prefixlen, &resolved, basedir_names, Qnil, loopcheck, mode, 0))
return Qnil;
}
- if (realpath_rec(&prefixlen, &resolved, path_names, loopcheck, mode, 1))
+ if (realpath_rec(&prefixlen, &resolved, path_names, Qnil, loopcheck, mode, 1))
return Qnil;
if (origenc != enc && rb_enc_str_asciionly_p(resolved))
diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb
index 58a4240391..d0d6a0ebe2 100644
--- a/test/ruby/test_file.rb
+++ b/test/ruby/test_file.rb
@@ -284,6 +284,14 @@ class TestFile < Test::Unit::TestCase
}
end
+ def test_realpath_special_symlink
+ IO.pipe do |r, w|
+ if File.pipe?(path = "/dev/fd/#{r.fileno}")
+ assert_file.identical?(File.realpath(path), path)
+ end
+ end
+ end
+
def test_realdirpath
Dir.mktmpdir('rubytest-realdirpath') {|tmpdir|
realdir = File.realpath(tmpdir)
diff --git a/version.h b/version.h
index 82cdb46aa8..1455401a54 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@
#define RUBY_VERSION "2.4.4"
-#define RUBY_RELEASE_DATE "2018-03-22"
-#define RUBY_PATCHLEVEL 282
+#define RUBY_RELEASE_DATE "2018-03-23"
+#define RUBY_PATCHLEVEL 283
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 22
+#define RUBY_RELEASE_DAY 23
#include "ruby/version.h"