From: nobu@... Date: 2017-05-22T08:17:30+00:00 Subject: [ruby-core:81329] [Ruby trunk Feature#13568] File#path for O_TMPFILE fds are unmeaning Issue #13568 has been updated by nobu (Nobuyoshi Nakada). ```sh $ ./x86_64-linux/bin/ruby -e 'f = open(File.expand_path("/tmp"), File::RDWR|File::TMPFILE); p open(f).read' Traceback (most recent call last): 2: from -e:1:in `
' 1: from -e:1:in `open' -e:1:in `to_path': unnamed temporary file at /tmp (IOError) ``` ```diff diff --git a/file.c b/file.c index b234910d5d..261997ecb2 100644 --- a/file.c +++ b/file.c @@ -367,7 +367,6 @@ apply2files(void (*func)(const char *, VALUE, void *), int argc, VALUE *argv, vo /* * call-seq: * file.path -> filename - * file.to_path -> filename * * Returns the pathname used to create file as a string. Does * not normalize the name. @@ -391,6 +390,38 @@ rb_file_path(VALUE obj) return rb_obj_taint(rb_str_dup(fptr->pathv)); } +#ifdef O_TMPFILE +/* + * call-seq: + * file.to_path -> filename + * + * Returns the pathname to open the file as a string. + * + * The pathname may not point the file corresponding to file. + * e.g. file has been moved, deleted, or created with File::TMPFILE option. + */ + +static VALUE +rb_file_to_path(VALUE obj) +{ + rb_io_t *fptr; + int flags; + + fptr = RFILE(rb_io_taint_check(obj))->fptr; + rb_io_check_initialized(fptr); + flags = fcntl(fptr->fd, F_GETFL); + if (flags == -1) rb_sys_fail_path(fptr->pathv); + if ((flags & O_TMPFILE) == O_TMPFILE) { + rb_raise(rb_eIOError, "unnamed temporary file at %"PRIsVALUE, + fptr->pathv); + } + if (NIL_P(fptr->pathv)) return Qnil; + return rb_obj_taint(rb_str_dup(fptr->pathv)); +} +#else +# define rb_file_to_path rb_file_path +#endif + static size_t stat_memsize(const void *p) { @@ -6140,7 +6171,7 @@ Init_File(void) rb_define_const(rb_mFConst, "NULL", rb_fstring_cstr(null_device)); rb_define_method(rb_cFile, "path", rb_file_path, 0); - rb_define_method(rb_cFile, "to_path", rb_file_path, 0); + rb_define_method(rb_cFile, "to_path", rb_file_to_path, 0); rb_define_global_function("test", rb_f_test, -1); rb_cStat = rb_define_class_under(rb_cFile, "Stat", rb_cObject); ``` ---------------------------------------- Feature #13568: File#path for O_TMPFILE fds are unmeaning https://bugs.ruby-lang.org/issues/13568#change-65019 * Author: sorah (Sorah Fukumori) * Status: Assigned * Priority: Normal * Assignee: sorah (Sorah Fukumori) * Target version: ---------------------------------------- By using File::TMPFILE (O_TMPFILE) allows us to create a file without directory entries. While open(2) with O_TMPFILE don't create a file without directory entries, it still requires a directory name to determine a file system to create a file. Current Ruby implementation holds such directory names in fptr->pathv and retrievable via File#path. But such paths are useless and may raise errors. For example, some code [1] checks File#path availability then when available, it attempts to use the path to open a file in different fd, finally raises Errno::EISDIR. This patch changes File#path (fptr->pathv) not to return String if a fd is opened with O_TMPFILE. [1]: https://github.com/aws/aws-sdk-ruby/blob/v2.9.17/aws-sdk-core/lib/aws-sdk-core/checksums.rb#L15 ---Files-------------------------------- tmpfile-path.patch (1.96 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: