[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]