зеркало из https://github.com/github/ruby.git
console.c: IO.console arguments passing
* ext/io/console/console.c (console_dev): send the given arguments to the opened console. as a special case, do nothing if :close is given. * test/lib/leakchecker.rb (LeakChecker#check_fd_leak): close if console. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48993 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
f0806c4863
Коммит
945e4692ca
|
@ -1,3 +1,12 @@
|
|||
Thu Dec 25 16:14:10 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* ext/io/console/console.c (console_dev): send the given arguments
|
||||
to the opened console. as a special case, do nothing if :close
|
||||
is given.
|
||||
|
||||
* test/lib/leakchecker.rb (LeakChecker#check_fd_leak): close if
|
||||
console.
|
||||
|
||||
Thu Dec 25 16:01:19 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* file.c (rb_file_expand_path_internal): drop characters ignored
|
||||
|
|
|
@ -77,7 +77,7 @@ getattr(int fd, conmode *t)
|
|||
#define SET_LAST_ERROR (0)
|
||||
#endif
|
||||
|
||||
static ID id_getc, id_console;
|
||||
static ID id_getc, id_console, id_close;
|
||||
|
||||
typedef struct {
|
||||
int vmin;
|
||||
|
@ -629,27 +629,49 @@ console_ioflush(VALUE io)
|
|||
/*
|
||||
* call-seq:
|
||||
* IO.console -> #<File:/dev/tty>
|
||||
* IO.console(sym, *args)
|
||||
*
|
||||
* Returns an File instance opened console.
|
||||
*
|
||||
* If +sym+ is given, it will be sent to the opened console with
|
||||
* +args+ and the result will be returned instead of the console IO
|
||||
* itself.
|
||||
*
|
||||
* You must require 'io/console' to use this method.
|
||||
*/
|
||||
static VALUE
|
||||
console_dev(VALUE klass)
|
||||
console_dev(int argc, VALUE *argv, VALUE klass)
|
||||
{
|
||||
VALUE con = 0;
|
||||
rb_io_t *fptr;
|
||||
VALUE sym = 0;
|
||||
|
||||
rb_check_arity(argc, 0, 1);
|
||||
if (argc) {
|
||||
Check_Type(sym = argv[0], T_SYMBOL);
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
if (klass == rb_cIO) klass = rb_cFile;
|
||||
if (rb_const_defined(klass, id_console)) {
|
||||
con = rb_const_get(klass, id_console);
|
||||
if (RB_TYPE_P(con, T_FILE)) {
|
||||
if ((fptr = RFILE(con)->fptr) && GetReadFD(fptr) != -1)
|
||||
return con;
|
||||
if (!RB_TYPE_P(con, T_FILE) ||
|
||||
(!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) {
|
||||
rb_const_remove(klass, id_console);
|
||||
con = 0;
|
||||
}
|
||||
rb_const_remove(klass, id_console);
|
||||
}
|
||||
{
|
||||
if (sym) {
|
||||
if (sym == ID2SYM(id_close) && !argc) {
|
||||
if (con) {
|
||||
rb_io_close(con);
|
||||
rb_const_remove(klass, id_console);
|
||||
con = 0;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
if (!con) {
|
||||
VALUE args[2];
|
||||
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
|
||||
# define CONSOLE_DEVICE "/dev/tty"
|
||||
|
@ -697,6 +719,10 @@ console_dev(VALUE klass)
|
|||
fptr->mode |= FMODE_SYNC;
|
||||
rb_const_set(klass, id_console, con);
|
||||
}
|
||||
if (sym) {
|
||||
/* TODO: avoid inadvertent pindown */
|
||||
return rb_funcall(con, SYM2ID(sym), argc, argv);
|
||||
}
|
||||
return con;
|
||||
}
|
||||
|
||||
|
@ -720,6 +746,7 @@ Init_console(void)
|
|||
{
|
||||
id_getc = rb_intern("getc");
|
||||
id_console = rb_intern("console");
|
||||
id_close = rb_intern("close");
|
||||
InitVM(console);
|
||||
}
|
||||
|
||||
|
@ -739,7 +766,7 @@ InitVM_console(void)
|
|||
rb_define_method(rb_cIO, "iflush", console_iflush, 0);
|
||||
rb_define_method(rb_cIO, "oflush", console_oflush, 0);
|
||||
rb_define_method(rb_cIO, "ioflush", console_ioflush, 0);
|
||||
rb_define_singleton_method(rb_cIO, "console", console_dev, 0);
|
||||
rb_define_singleton_method(rb_cIO, "console", console_dev, -1);
|
||||
{
|
||||
VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
|
||||
rb_define_method(mReadable, "getch", io_getch, -1);
|
||||
|
|
|
@ -222,14 +222,22 @@ class TestIO_Console < Test::Unit::TestCase
|
|||
IO.console.close
|
||||
assert_kind_of(IO, IO.console)
|
||||
assert_nothing_raised(IOError) {IO.console.fileno}
|
||||
|
||||
IO.console(:close)
|
||||
assert(IO.console(:tty?))
|
||||
ensure
|
||||
IO.console(:close)
|
||||
end
|
||||
|
||||
def test_sync
|
||||
assert(IO.console.sync, "console should be unbuffered")
|
||||
ensure
|
||||
IO.console(:close)
|
||||
end
|
||||
else
|
||||
def test_close
|
||||
assert_equal(["true"], run_pty("IO.console.close; p IO.console.fileno >= 0"))
|
||||
assert_equal(["true"], run_pty("IO.console(:close); p IO.console(:tty?)"))
|
||||
end
|
||||
|
||||
def test_sync
|
||||
|
|
|
@ -31,6 +31,9 @@ class LeakChecker
|
|||
def check_fd_leak(test_name)
|
||||
leaked = false
|
||||
live1 = @fd_info
|
||||
if IO.respond_to?(:console)
|
||||
IO.console(:close)
|
||||
end
|
||||
live2 = find_fds
|
||||
fd_closed = live1 - live2
|
||||
if !fd_closed.empty?
|
||||
|
|
Загрузка…
Ссылка в новой задаче