Skip to content

Commit 4c172c0

Browse files
committed
Fixed intr: false mode on Windows
1 parent a841dad commit 4c172c0

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

ext/io/console/console.c

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,21 @@ set_rawmode(conmode *t, void *arg)
175175
#elif defined _WIN32
176176
*t = 0;
177177
#endif
178-
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
179178
if (arg) {
180179
const rawmode_arg_t *r = arg;
180+
#ifdef VMIN
181181
if (r->vmin >= 0) t->c_cc[VMIN] = r->vmin;
182+
#endif
183+
#ifdef VTIME
182184
if (r->vtime >= 0) t->c_cc[VTIME] = r->vtime;
185+
#endif
186+
#ifdef ISIG
183187
if (r->intr) {
184188
t->c_iflag |= BRKINT|IXON;
185189
t->c_lflag |= ISIG|IEXTEN;
186190
}
187-
}
188191
#endif
192+
}
189193
}
190194

191195
static void
@@ -449,6 +453,28 @@ getc_call(VALUE io)
449453
{
450454
return rb_funcallv(io, id_getc, 0, 0);
451455
}
456+
#else
457+
static VALUE
458+
nogvl_getch(void *p)
459+
{
460+
int len = 0;
461+
wint_t *buf = p, c = _getwch();
462+
463+
switch (c) {
464+
case WEOF:
465+
break;
466+
return (VALUE)0;
467+
case 0x00:
468+
case 0xe0:
469+
buf[len++] = c;
470+
c = _getwch();
471+
/* fall through */
472+
default:
473+
buf[len++] = c;
474+
break;
475+
}
476+
return (VALUE)len;
477+
}
452478
#endif
453479

454480
/*
@@ -473,6 +499,7 @@ console_getch(int argc, VALUE *argv, VALUE io)
473499
wint_t c;
474500
int w, len;
475501
char buf[8];
502+
wint_t wbuf[2];
476503
struct timeval *to = NULL, tv;
477504

478505
GetOpenFile(io, fptr);
@@ -485,24 +512,26 @@ console_getch(int argc, VALUE *argv, VALUE io)
485512
if (optp->vmin != 1) {
486513
rb_warning("min option ignored");
487514
}
515+
if (optp->intr) {
516+
w = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, to);
517+
if (w < 0) rb_eof_error();
518+
if (!(w & RB_WAITFD_IN)) return Qnil;
519+
}
488520
}
489-
w = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, to);
490-
if (w < 0) rb_eof_error();
491-
if (!(w & RB_WAITFD_IN)) return Qnil;
492-
c = _getwch();
493-
switch (c) {
494-
case WEOF:
521+
len = (int)rb_thread_io_blocking_region(nogvl_getch, wbuf, fptr->fd);
522+
switch (len) {
523+
case 0:
495524
return Qnil;
496-
case 0x00:
497-
case 0xe0:
498-
buf[0] = (char)c;
499-
c = _getwch();
525+
case 2:
526+
buf[0] = (char)wbuf[0];
527+
c = wbuf[1];
500528
len = 1;
501529
do {
502530
buf[len++] = (unsigned char)c;
503531
} while ((c >>= CHAR_BIT) && len < (int)sizeof(buf));
504532
return rb_str_new(buf, len);
505533
default:
534+
c = wbuf[0];
506535
len = rb_uv_to_utf8(buf, c);
507536
str = rb_utf8_str_new(buf, len);
508537
return rb_str_conv_enc(str, NULL, rb_default_external_encoding());

0 commit comments

Comments
 (0)