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

ruby-changes:47588

From: sorah <ko1@a...>
Date: Thu, 31 Aug 2017 20:14:42 +0900 (JST)
Subject: [ruby-changes:47588] sorah:r59704 (trunk): File#path: Raise IOError when a file is O_TMPFILE

sorah	2017-08-31 20:14:36 +0900 (Thu, 31 Aug 2017)

  New Revision: 59704

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

  Log:
    File#path: Raise IOError when a file is O_TMPFILE
    
    File#path for a file opened with O_TMPFILE has no meaning.
    
    A filepath returned by this method isn't guarranteed about its accuracy,
    but files opened with O_TMPFILE are known its recorded path has no
    meaning. So let them not to return any pathname.
    
    After a discussion in ruby-core, just returning Qnil makes guessing the
    root cause difficult. Instead, this patch makes the method to raise an
    error.
    
    Other consideration is calling fnctl(2) on rb_file_path, but it adds a
    overhead, and it's difficult to determine O_TMPFILE status  after fd has
    been closed.
    
    [Feature #13568]
    
    * io.c(rb_file_open_generic): Set Qnil to fptr->pathv when opening a
      file using O_TMPFILE
    
    * file.c(rb_file_path): Raise IOError when fptr->pathv is Qnil
    
    * file.c(rb_file_path): [DOC] Update for the new behavior

  Modified files:
    trunk/file.c
    trunk/io.c
    trunk/test/ruby/test_file.rb
Index: test/ruby/test_file.rb
===================================================================
--- test/ruby/test_file.rb	(revision 59703)
+++ test/ruby/test_file.rb	(revision 59704)
@@ -468,4 +468,16 @@ class TestFile < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_file.rb#L468
       assert_file.not_exist?(path)
     end
   end
+
+  def test_open_tempfile_path
+    Dir.mktmpdir(__method__.to_s) do |tmpdir|
+      File.open(tmpdir, File::RDWR | File::TMPFILE) do |io|
+        io.write "foo"
+        io.flush
+        assert_equal 3, io.size
+        assert_raise(IOError) { io.path }
+      end
+    end
+  end if File::Constants.const_defined?(:TMPFILE)
+
 end
Index: file.c
===================================================================
--- file.c	(revision 59703)
+++ file.c	(revision 59704)
@@ -379,7 +379,10 @@ apply2files(void (*func)(const char *, V https://github.com/ruby/ruby/blob/trunk/file.c#L379
  *  not normalize the name.
  *
  *  The pathname may not point the file corresponding to <i>file</i>.
- *  e.g. file has been moved, deleted, or created with <code>File::TMPFILE</code> option.
+ *  For instance, pathname becomes inaccurate when file has been moved or deleted.
+ *
+ *  This method raises <code>IOError</code> for a <i>file</i> created using
+ *  <code>File::Constants::TMPFILE</code> because they don't have a pathname.
  *
  *     File.new("testfile").path               #=> "testfile"
  *     File.new("/tmp/../tmp/xxx", "w").path   #=> "/tmp/../tmp/xxx"
@@ -393,7 +396,11 @@ rb_file_path(VALUE obj) https://github.com/ruby/ruby/blob/trunk/file.c#L396
 
     fptr = RFILE(rb_io_taint_check(obj))->fptr;
     rb_io_check_initialized(fptr);
-    if (NIL_P(fptr->pathv)) return Qnil;
+
+    if (NIL_P(fptr->pathv)) {
+        rb_raise(rb_eIOError, "File is unnamed (TMPFILE?)");
+    }
+
     return rb_obj_taint(rb_str_dup(fptr->pathv));
 }
 
Index: io.c
===================================================================
--- io.c	(revision 59703)
+++ io.c	(revision 59704)
@@ -5833,6 +5833,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L5833
 rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode,
 		     const convconfig_t *convconfig, mode_t perm)
 {
+    VALUE pathv;
     rb_io_t *fptr;
     convconfig_t cc;
     if (!convconfig) {
@@ -5848,8 +5849,15 @@ rb_file_open_generic(VALUE io, VALUE fil https://github.com/ruby/ruby/blob/trunk/io.c#L5849
     MakeOpenFile(io, fptr);
     fptr->mode = fmode;
     fptr->encs = *convconfig;
-    fptr->pathv = rb_str_new_frozen(filename);
-    fptr->fd = rb_sysopen(fptr->pathv, oflags, perm);
+    pathv = rb_str_new_frozen(filename);
+#ifdef O_TMPFILE
+    if (!(oflags & O_TMPFILE)) {
+        fptr->pathv = pathv;
+    }
+#else
+    fptr->pathv = pathv;
+#endif
+    fptr->fd = rb_sysopen(pathv, oflags, perm);
     io_check_tty(fptr);
     if (fmode & FMODE_SETENC_BY_BOM) io_set_encoding_by_bom(io);
 

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

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