зеркало из https://github.com/github/ruby.git
* configure.in (dirfd): Check function.
* dir.c (dir_fileno): New method. [ruby-dev:48265] [Feature #9880] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47387 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
f20d51b0ad
Коммит
d03315d84a
|
@ -1,3 +1,10 @@
|
||||||
|
Fri Sep 5 00:29:08 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* configure.in (dirfd): Check function.
|
||||||
|
|
||||||
|
* dir.c (dir_fileno): New method.
|
||||||
|
[ruby-dev:48265] [Feature #9880]
|
||||||
|
|
||||||
Thu Sep 4 23:39:52 2014 Tanaka Akira <akr@fsij.org>
|
Thu Sep 4 23:39:52 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* process.c (has_privilege): New function.
|
* process.c (has_privilege): New function.
|
||||||
|
|
4
NEWS
4
NEWS
|
@ -20,6 +20,10 @@ with all sufficient information, see the ChangeLog file.
|
||||||
* Binding#local_variables
|
* Binding#local_variables
|
||||||
* Binding#receiver
|
* Binding#receiver
|
||||||
|
|
||||||
|
* Dir
|
||||||
|
* New methods:
|
||||||
|
* Dir#fileno
|
||||||
|
|
||||||
* Enumerable
|
* Enumerable
|
||||||
* New methods:
|
* New methods:
|
||||||
* Enumerable#slice_after
|
* Enumerable#slice_after
|
||||||
|
|
|
@ -1974,6 +1974,7 @@ AC_CHECK_FUNCS(chsize)
|
||||||
AC_CHECK_FUNCS(clock_gettime)
|
AC_CHECK_FUNCS(clock_gettime)
|
||||||
AC_CHECK_FUNCS(cosh)
|
AC_CHECK_FUNCS(cosh)
|
||||||
AC_CHECK_FUNCS(daemon)
|
AC_CHECK_FUNCS(daemon)
|
||||||
|
AC_CHECK_FUNCS(dirfd)
|
||||||
AC_CHECK_FUNCS(dl_iterate_phdr)
|
AC_CHECK_FUNCS(dl_iterate_phdr)
|
||||||
AC_CHECK_FUNCS(dlopen)
|
AC_CHECK_FUNCS(dlopen)
|
||||||
AC_CHECK_FUNCS(dladdr)
|
AC_CHECK_FUNCS(dladdr)
|
||||||
|
|
32
dir.c
32
dir.c
|
@ -539,6 +539,37 @@ dir_inspect(VALUE dir)
|
||||||
return rb_funcall(dir, rb_intern("to_s"), 0, 0);
|
return rb_funcall(dir, rb_intern("to_s"), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DIRFD
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* dir.fileno -> integer
|
||||||
|
*
|
||||||
|
* Returns the file descriptor used in <em>dir</em>.
|
||||||
|
*
|
||||||
|
* d = Dir.new("..")
|
||||||
|
* d.fileno #=> 8
|
||||||
|
*
|
||||||
|
* This method uses dirfd() function defined by POSIX 2008.
|
||||||
|
* NotImplementedError is raised on other platforms, such as Windows,
|
||||||
|
* which doesn't provide the function.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* dir.path -> string or nil
|
* dir.path -> string or nil
|
||||||
|
@ -2259,6 +2290,7 @@ Init_Dir(void)
|
||||||
rb_define_singleton_method(rb_cDir, "entries", dir_entries, -1);
|
rb_define_singleton_method(rb_cDir, "entries", dir_entries, -1);
|
||||||
|
|
||||||
rb_define_method(rb_cDir,"initialize", dir_initialize, -1);
|
rb_define_method(rb_cDir,"initialize", dir_initialize, -1);
|
||||||
|
rb_define_method(rb_cDir,"fileno", dir_fileno, 0);
|
||||||
rb_define_method(rb_cDir,"path", dir_path, 0);
|
rb_define_method(rb_cDir,"path", dir_path, 0);
|
||||||
rb_define_method(rb_cDir,"to_path", dir_path, 0);
|
rb_define_method(rb_cDir,"to_path", dir_path, 0);
|
||||||
rb_define_method(rb_cDir,"inspect", dir_inspect, 0);
|
rb_define_method(rb_cDir,"inspect", dir_inspect, 0);
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
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")
|
|
|
@ -1,109 +0,0 @@
|
||||||
#include "ruby.h"
|
|
||||||
#include "ruby/encoding.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#if defined HAVE_DIRENT_H && !defined _WIN32
|
|
||||||
# include <dirent.h>
|
|
||||||
#elif defined HAVE_DIRECT_H && !defined _WIN32
|
|
||||||
# include <direct.h>
|
|
||||||
#else
|
|
||||||
# define dirent direct
|
|
||||||
# if HAVE_SYS_NDIR_H
|
|
||||||
# include <sys/ndir.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_SYS_DIR_H
|
|
||||||
# include <sys/dir.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_NDIR_H
|
|
||||||
# include <ndir.h>
|
|
||||||
# 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef HAVE_DIRFD
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GetDIR(obj, dirp) ((dirp) = dir_check(obj))
|
|
||||||
|
|
||||||
#ifdef HAVE_DIRFD
|
|
||||||
/*
|
|
||||||
* call-seq:
|
|
||||||
* dir.fileno -> integer
|
|
||||||
*
|
|
||||||
* Returns the file descriptor used in <em>dir</em>.
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
#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);
|
|
||||||
}
|
|
|
@ -15,7 +15,6 @@ class LeakChecker
|
||||||
def find_fds
|
def find_fds
|
||||||
fd_dir = "/proc/self/fd"
|
fd_dir = "/proc/self/fd"
|
||||||
if File.directory?(fd_dir)
|
if File.directory?(fd_dir)
|
||||||
require "-test-/dir"
|
|
||||||
fds = Dir.open(fd_dir) {|d|
|
fds = Dir.open(fd_dir) {|d|
|
||||||
a = d.grep(/\A\d+\z/, &:to_i)
|
a = d.grep(/\A\d+\z/, &:to_i)
|
||||||
if d.respond_to? :fileno
|
if d.respond_to? :fileno
|
||||||
|
|
|
@ -294,4 +294,14 @@ class TestDir < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_fileno
|
||||||
|
Dir.open(".") {|d|
|
||||||
|
if d.respond_to? :fileno
|
||||||
|
assert_kind_of(Integer, d.fileno)
|
||||||
|
else
|
||||||
|
assert_raise(NotImplementedError) { d.fileno }
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Загрузка…
Ссылка в новой задаче