From 83ead3c4a7dc2670bad06745eaccbdd0a9397f46 Mon Sep 17 00:00:00 2001 From: akr Date: Thu, 29 May 2014 22:28:47 +0000 Subject: * ext/-test-/dir: Dir#fileno implemented. * test/lib/minitest/unit.rb (find_fds): Don't return the fd used to scan /proc/$$/fd. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46240 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++ ext/-test-/dir/extconf.rb | 9 ++++ ext/-test-/dir/fileno.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++ ext/-test-/dir/init.c | 11 +++++ test/lib/minitest/unit.rb | 13 +++++- 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 ext/-test-/dir/extconf.rb create mode 100644 ext/-test-/dir/fileno.c create mode 100644 ext/-test-/dir/init.c diff --git a/ChangeLog b/ChangeLog index 33f86a0e35..591c1aa484 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri May 30 07:25:46 2014 Tanaka Akira + + * ext/-test-/dir: Dir#fileno implemented. + + * test/lib/minitest/unit.rb (find_fds): Don't return the fd used to + scan /proc/$$/fd. + Fri May 30 04:48:00 2014 Eric Wong * parse.y (rb_gc_mark_parser): remove, empty since r8758 diff --git a/ext/-test-/dir/extconf.rb b/ext/-test-/dir/extconf.rb new file mode 100644 index 0000000000..ce4aad142a --- /dev/null +++ b/ext/-test-/dir/extconf.rb @@ -0,0 +1,9 @@ +have_func("dirfd") + +$INCFLAGS << " -I$(topdir) -I$(top_srcdir)" +$srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")] +inits = $srcs.map {|s| File.basename(s, ".*")} +inits.delete("init") +inits.map! {|s|"X(#{s})"} +$defs << "-DTEST_INIT_FUNCS(X)=\"#{inits.join(' ')}\"" +create_makefile("-test-/dir") diff --git a/ext/-test-/dir/fileno.c b/ext/-test-/dir/fileno.c new file mode 100644 index 0000000000..7a451bc1a7 --- /dev/null +++ b/ext/-test-/dir/fileno.c @@ -0,0 +1,107 @@ +#include "ruby.h" +#include "ruby/encoding.h" +#include "internal.h" + +#if defined HAVE_DIRENT_H && !defined _WIN32 +# include +#elif defined HAVE_DIRECT_H && !defined _WIN32 +# include +#else +# define dirent direct +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# ifdef _WIN32 +# include "win32/dir.h" +# endif +#endif +#if defined(__native_client__) && defined(NACL_NEWLIB) +# include "nacl/dirent.h" +# include "nacl/stat.h" +#endif + +struct dir_data { + DIR *dir; + VALUE path; + rb_encoding *enc; +}; + +static void * +rb_check_typeddata0(VALUE obj /*, const rb_data_type_t *data_type */) +{ + const char *etype; + /* static const char mesg[] = "wrong argument type %s (expected %s)"; */ + + if (!RB_TYPE_P(obj, T_DATA)) { + etype = rb_builtin_class_name(obj); + /* rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); */ + rb_raise(rb_eTypeError, "wrong argument type %s", etype); + } +/* + if (!RTYPEDDATA_P(obj)) { + etype = rb_obj_classname(obj); + rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); + } + else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) { + etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name; + rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); + } +*/ + return DATA_PTR(obj); +} + +static void +dir_closed(void) +{ + rb_raise(rb_eIOError, "closed directory"); +} + +static struct dir_data * +dir_check(VALUE dir) +{ + struct dir_data *dirp; + rb_check_frozen(dir); + dirp = rb_check_typeddata0(dir /*, &dir_data_type*/); + if (!dirp->dir) dir_closed(); + return dirp; +} + +#define GetDIR(obj, dirp) ((dirp) = dir_check(obj)) + +#ifdef HAVE_DIRFD +/* + * call-seq: + * dir.fileno -> integer + * + * Returns the file descriptor used in dir. + * + * d = Dir.new("..") + * d.fileno #=> 8 + */ +static VALUE +dir_fileno(VALUE dir) +{ + struct dir_data *dirp; + int fd; + + GetDIR(dir, dirp); + fd = dirfd(dirp->dir); + if (fd == -1) + rb_sys_fail("dirfd"); + return INT2NUM(fd); +} +#else +#define dir_fileno rb_f_notimplement +#endif + +void +Init_fileno(VALUE klass) +{ + rb_define_method(rb_cDir,"fileno", dir_fileno, 0); +} diff --git a/ext/-test-/dir/init.c b/ext/-test-/dir/init.c new file mode 100644 index 0000000000..2ca1508468 --- /dev/null +++ b/ext/-test-/dir/init.c @@ -0,0 +1,11 @@ +#include "ruby.h" + +#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);} + +void +Init_dir(void) +{ + VALUE mBug = rb_define_module("Bug"); + VALUE klass = rb_define_class_under(mBug, "Dir", rb_cObject); + TEST_INIT_FUNCS(init); +} diff --git a/test/lib/minitest/unit.rb b/test/lib/minitest/unit.rb index e880d3654b..2f31d6d2e9 100644 --- a/test/lib/minitest/unit.rb +++ b/test/lib/minitest/unit.rb @@ -2,6 +2,7 @@ require "optparse" require "rbconfig" +require "-test-/dir" ## # Minimal (mostly drop-in) replacement for test-unit. @@ -992,7 +993,17 @@ module MiniTest def find_fds fd_dir = "/proc/#{$$}/fd" if File.directory?(fd_dir) - Dir.entries(fd_dir).grep(/\A\d+\z/).map(&:to_i).sort + fds = Dir.open(fd_dir) {|d| + a = [] + while fn = d.read + a << fn + end + if d.respond_to? :fileno + a -= [d.fileno.to_s] + end + a + } + fds.grep(/\A\d+\z/).map(&:to_i).sort else [] end -- cgit v1.2.3