ruby-changes:59061
From: Nobuyoshi <ko1@a...>
Date: Wed, 4 Dec 2019 10:13:11 +0900 (JST)
Subject: [ruby-changes:59061] 5a404efd29 (master): [ruby/io-console] Fixed `intr: false` mode on Windows
https://git.ruby-lang.org/ruby.git/commit/?id=5a404efd29 From 5a404efd29d255402e30f4f23a09d4e5398600b8 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Wed, 4 Dec 2019 10:06:54 +0900 Subject: [ruby/io-console] Fixed `intr: false` mode on Windows https://github.com/ruby/io-console/commit/4c172c01aa diff --git a/ext/io/console/console.c b/ext/io/console/console.c index 42b000f..e59284e 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -175,17 +175,21 @@ set_rawmode(conmode *t, void *arg) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L175 #elif defined _WIN32 *t = 0; #endif -#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H if (arg) { const rawmode_arg_t *r = arg; +#ifdef VMIN if (r->vmin >= 0) t->c_cc[VMIN] = r->vmin; +#endif +#ifdef VTIME if (r->vtime >= 0) t->c_cc[VTIME] = r->vtime; +#endif +#ifdef ISIG if (r->intr) { t->c_iflag |= BRKINT|IXON; t->c_lflag |= ISIG|IEXTEN; } - } #endif + } } static void @@ -449,6 +453,28 @@ getc_call(VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L453 { return rb_funcallv(io, id_getc, 0, 0); } +#else +static VALUE +nogvl_getch(void *p) +{ + int len = 0; + wint_t *buf = p, c = _getwch(); + + switch (c) { + case WEOF: + break; + return (VALUE)0; + case 0x00: + case 0xe0: + buf[len++] = c; + c = _getwch(); + /* fall through */ + default: + buf[len++] = c; + break; + } + return (VALUE)len; +} #endif /* @@ -473,6 +499,7 @@ console_getch(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L499 wint_t c; int w, len; char buf[8]; + wint_t wbuf[2]; struct timeval *to = NULL, tv; GetOpenFile(io, fptr); @@ -485,24 +512,26 @@ console_getch(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L512 if (optp->vmin != 1) { rb_warning("min option ignored"); } + if (optp->intr) { + w = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, to); + if (w < 0) rb_eof_error(); + if (!(w & RB_WAITFD_IN)) return Qnil; + } } - w = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, to); - if (w < 0) rb_eof_error(); - if (!(w & RB_WAITFD_IN)) return Qnil; - c = _getwch(); - switch (c) { - case WEOF: + len = (int)rb_thread_io_blocking_region(nogvl_getch, wbuf, fptr->fd); + switch (len) { + case 0: return Qnil; - case 0x00: - case 0xe0: - buf[0] = (char)c; - c = _getwch(); + case 2: + buf[0] = (char)wbuf[0]; + c = wbuf[1]; len = 1; do { buf[len++] = (unsigned char)c; } while ((c >>= CHAR_BIT) && len < (int)sizeof(buf)); return rb_str_new(buf, len); default: + c = wbuf[0]; len = rb_uv_to_utf8(buf, c); str = rb_utf8_str_new(buf, len); return rb_str_conv_enc(str, NULL, rb_default_external_encoding()); -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/