[前][次][番号順一覧][スレッド一覧]

ruby-changes:50498

From: naruse <ko1@a...>
Date: Fri, 2 Mar 2018 17:25:57 +0900 (JST)
Subject: [ruby-changes:50498] naruse:r62632 (ruby_2_5): merge revision(s) 62606, 62607: [Backport #14557]

naruse	2018-03-02 17:25:51 +0900 (Fri, 02 Mar 2018)

  New Revision: 62632

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62632

  Log:
    merge revision(s) 62606,62607: [Backport #14557]
    
    file.c: get rid of useless conversion
    
    * file.c (rb_file_s_stat): File.stat does not accept an IO
      object as trying conversion to path name string first.  skip
      conversion to IO and try stat(2) only.
    
    file.c: realpath on special symlink
    
    * file.c (realpath_rec): fallback to symlink path when it is
      accessible but the link target is not actual entry on file
      systems.  [ruby-dev:50487] [Bug #14557]

  Modified directories:
    branches/ruby_2_5/
  Modified files:
    branches/ruby_2_5/file.c
    branches/ruby_2_5/test/ruby/test_file.rb
    branches/ruby_2_5/version.h
Index: ruby_2_5/file.c
===================================================================
--- ruby_2_5/file.c	(revision 62631)
+++ ruby_2_5/file.c	(revision 62632)
@@ -1081,6 +1081,17 @@ no_gvl_fstat(void *data) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/file.c#L1081
     return (VALUE)fstat(arg->file.fd, arg->st);
 }
 
+static int
+fstat_without_gvl(int fd, struct stat *st)
+{
+    no_gvl_stat_data data;
+
+    data.file.fd = fd;
+    data.st = st;
+
+    return (int)(VALUE)rb_thread_io_blocking_region(no_gvl_fstat, &data, fd);
+}
+
 static void *
 no_gvl_stat(void * data)
 {
@@ -1089,27 +1100,38 @@ no_gvl_stat(void * data) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/file.c#L1100
 }
 
 static int
-rb_stat(VALUE file, struct stat *st)
+stat_without_gvl(const char *path, struct stat *st)
 {
-    VALUE tmp;
-    VALUE result;
     no_gvl_stat_data data;
 
+    data.file.path = path;
     data.st = st;
+
+    return (int)(VALUE)rb_thread_call_without_gvl(no_gvl_stat, &data,
+						  RUBY_UBF_IO, NULL);
+}
+
+static int
+rb_stat(VALUE file, struct stat *st)
+{
+    VALUE tmp;
+    int result;
+
     tmp = rb_check_convert_type_with_id(file, T_FILE, "IO", idTo_io);
     if (!NIL_P(tmp)) {
 	rb_io_t *fptr;
 
 	GetOpenFile(tmp, fptr);
-	data.file.fd = fptr->fd;
-	result = rb_thread_io_blocking_region(no_gvl_fstat, &data, fptr->fd);
-	return (int)result;
-    }
-    FilePathValue(file);
-    file = rb_str_encode_ospath(file);
-    data.file.path = StringValueCStr(file);
-    result = (VALUE)rb_thread_call_without_gvl(no_gvl_stat, &data, RUBY_UBF_IO, NULL);
-    return (int)result;
+	result = fstat_without_gvl(fptr->fd, st);
+	file = tmp;
+    }
+    else {
+	FilePathValue(file);
+	file = rb_str_encode_ospath(file);
+	result = stat_without_gvl(RSTRING_PTR(file), st);
+    }
+    RB_GC_GUARD(file);
+    return result;
 }
 
 /*
@@ -1129,7 +1151,8 @@ rb_file_s_stat(VALUE klass, VALUE fname) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/file.c#L1151
     struct stat st;
 
     FilePathValue(fname);
-    if (rb_stat(fname, &st) < 0) {
+    fname = rb_str_encode_ospath(fname);
+    if (stat_without_gvl(RSTRING_PTR(fname), &st) < 0) {
 	rb_sys_fail_path(fname);
     }
     return rb_stat_new(&st);
@@ -3919,7 +3942,7 @@ enum rb_realpath_mode { https://github.com/ruby/ruby/blob/trunk/ruby_2_5/file.c#L3942
 };
 
 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);
@@ -3977,6 +4000,12 @@ realpath_rec(long *prefixlenp, VALUE *re https://github.com/ruby/ruby/blob/trunk/ruby_2_5/file.c#L4000
                 ret = lstat_without_gvl(RSTRING_PTR(testpath), &sbuf);
                 if (ret == -1) {
 		    int e = errno;
+		    if (e == ENOENT && !NIL_P(fallback)) {
+			if (stat_without_gvl(RSTRING_PTR(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)
@@ -4008,7 +4037,7 @@ realpath_rec(long *prefixlenp, VALUE *re https://github.com/ruby/ruby/blob/trunk/ruby_2_5/file.c#L4037
 			*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);
@@ -4097,14 +4126,14 @@ rb_check_realpath_internal(VALUE basedir https://github.com/ruby/ruby/blob/trunk/ruby_2_5/file.c#L4126
 
     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 != rb_enc_get(resolved)) {
Index: ruby_2_5/version.h
===================================================================
--- ruby_2_5/version.h	(revision 62631)
+++ ruby_2_5/version.h	(revision 62632)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_5/version.h#L1
 #define RUBY_VERSION "2.5.0"
-#define RUBY_RELEASE_DATE "2018-02-28"
-#define RUBY_PATCHLEVEL 38
+#define RUBY_RELEASE_DATE "2018-03-02"
+#define RUBY_PATCHLEVEL 39
 
 #define RUBY_RELEASE_YEAR 2018
-#define RUBY_RELEASE_MONTH 2
-#define RUBY_RELEASE_DAY 28
+#define RUBY_RELEASE_MONTH 3
+#define RUBY_RELEASE_DAY 2
 
 #include "ruby/version.h"
 
Index: ruby_2_5/test/ruby/test_file.rb
===================================================================
--- ruby_2_5/test/ruby/test_file.rb	(revision 62631)
+++ ruby_2_5/test/ruby/test_file.rb	(revision 62632)
@@ -303,6 +303,14 @@ class TestFile < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_5/test/ruby/test_file.rb#L303
     }
   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)
Index: ruby_2_5
===================================================================
--- ruby_2_5	(revision 62631)
+++ ruby_2_5	(revision 62632)

Property changes on: ruby_2_5
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r62606-62607

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]