summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-25 08:43:34 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-25 08:43:34 +0000
commit7393bf6a5cfff63683f36535e293caaa0d4c5be0 (patch)
tree753755854e63e4f3a904dc7d1db6df7358aef25b
parent74051762fe4072dc96d64f00ee53dd641c3fd687 (diff)
parentfe0ab0517a6cc71b06f0fe1b074f3f2e8e213862 (diff)
add tag v2_2_0v2_2_0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v2_2_0@49005 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog9
-rw-r--r--ext/io/console/console.c43
-rw-r--r--test/io/console/test_io_console.rb8
-rw-r--r--test/lib/leakchecker.rb3
4 files changed, 55 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 30908e72f2..6400e89691 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Thu Dec 25 17:42:01 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 17:37:47 2014 Naohisa Goto <ngotogenome@gmail.com>
* gc.c (wmap_final_func): fix memory size shortage when realloc wmap.
diff --git a/ext/io/console/console.c b/ext/io/console/console.c
index 0290a65a72..e846450007 100644
--- a/ext/io/console/console.c
+++ b/ext/io/console/console.c
@@ -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);
diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb
index 237a41a35f..3481a2b213 100644
--- a/test/io/console/test_io_console.rb
+++ b/test/io/console/test_io_console.rb
@@ -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
diff --git a/test/lib/leakchecker.rb b/test/lib/leakchecker.rb
index 5d05c1e456..37c87c9f72 100644
--- a/test/lib/leakchecker.rb
+++ b/test/lib/leakchecker.rb
@@ -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?