Skip to content

Commit

Permalink
add tag v2_2_0
Browse files Browse the repository at this point in the history
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v2_2_0@49005 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
nurse committed Dec 25, 2014
2 parents 7405176 + fe0ab05 commit 7393bf6
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
9 changes: 9 additions & 0 deletions 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.
Expand Down
43 changes: 35 additions & 8 deletions ext/io/console/console.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}

Expand All @@ -720,6 +746,7 @@ Init_console(void)
{
id_getc = rb_intern("getc");
id_console = rb_intern("console");
id_close = rb_intern("close");
InitVM(console);
}

Expand All @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions test/io/console/test_io_console.rb
Expand Up @@ -222,14 +222,22 @@ def test_close
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
Expand Down
3 changes: 3 additions & 0 deletions test/lib/leakchecker.rb
Expand Up @@ -31,6 +31,9 @@ def find_fds
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?
Expand Down

0 comments on commit 7393bf6

Please sign in to comment.