diff options
author | Hiroshi SHIBATA <[email protected]> | 2023-06-01 09:35:49 +0900 |
---|---|---|
committer | Hiroshi SHIBATA <[email protected]> | 2023-06-01 09:36:55 +0900 |
commit | 35da41b29bf0a1a8fd2cd7e1d7fcb036ca8c2c7c (patch) | |
tree | 0ade186d1f8ec1034e5062bee141863417b697b2 | |
parent | 85dcc4866d9ff29834596e9186cc97d622ee06f8 (diff) |
Revert https://github.com/ruby/io-console/pull/43
This reverts commit 1889133c04f337fec3969cb5040a544088249046 and
commit 764207e47ce38d1b73774a8e65114c87bc888298.
Followed up with https://github.com/ruby/ruby/commit/85dcc4866d9ff29834596e9186cc97d622ee06f8
-rw-r--r-- | ext/io/console/console.c | 356 | ||||
-rw-r--r-- | ext/io/console/extconf.rb | 6 |
2 files changed, 191 insertions, 171 deletions
diff --git a/ext/io/console/console.c b/ext/io/console/console.c index 6dadc8d0d6..21454a73fa 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -87,41 +87,7 @@ extern VALUE rb_scheduler_timeout(struct timeval *timeout); # define rb_fiber_scheduler_make_timeout rb_scheduler_timeout #endif -#ifndef HAVE_RB_IO_DESCRIPTOR -static int -io_descriptor_fallback(VALUE io) -{ - rb_io_t *fptr; - GetOpenFile(io, fptr); - return fptr->fd; -} -#define rb_io_descriptor io_descriptor_fallback -#endif - -#ifndef HAVE_RB_IO_PATH -static VALUE -io_path_fallback(VALUE io) -{ - rb_io_t *fptr; - GetOpenFile(io, fptr); - return fptr->pathv; -} -#define rb_io_path io_path_fallback -#endif - -#ifndef HAVE_RB_IO_GET_WRITE_IO -static VALUE -io_get_write_io_fallback(VALUE io) -{ - rb_io_t *fptr; - GetOpenFile(io, fptr); - VALUE wio = fptr->tied_io_for_writing; - return wio ? wio : io; -} -#define rb_io_get_write_io io_get_write_io_fallback -#endif - -#define sys_fail(io) rb_sys_fail_str(rb_io_path(io)) +#define sys_fail_fptr(fptr) rb_sys_fail_str((fptr)->pathv) #ifndef HAVE_RB_F_SEND #ifndef RB_PASS_CALLED_KEYWORDS @@ -327,21 +293,33 @@ set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg) return setattr(fd, &r); } -#define GetReadFD(io) rb_io_descriptor(io) -#define GetWriteFD(io) rb_io_descriptor(rb_io_get_write_io(io)) +#define GetReadFD(fptr) ((fptr)->fd) + +static inline int +get_write_fd(const rb_io_t *fptr) +{ + VALUE wio = fptr->tied_io_for_writing; + rb_io_t *ofptr; + if (!wio) return fptr->fd; + GetOpenFile(wio, ofptr); + return ofptr->fd; +} +#define GetWriteFD(fptr) get_write_fd(fptr) #define FD_PER_IO 2 static VALUE ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg) { + rb_io_t *fptr; int status = -1; int error = 0; int fd[FD_PER_IO]; conmode t[FD_PER_IO]; VALUE result = Qnil; - fd[0] = GetReadFD(io); + GetOpenFile(io, fptr); + fd[0] = GetReadFD(fptr); if (fd[0] != -1) { if (set_ttymode(fd[0], t+0, setter, arg)) { status = 0; @@ -351,7 +329,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo fd[0] = -1; } } - fd[1] = GetWriteFD(io); + fd[1] = GetWriteFD(fptr); if (fd[1] != -1 && fd[1] != fd[0]) { if (set_ttymode(fd[1], t+1, setter, arg)) { status = 0; @@ -364,13 +342,14 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo if (status == 0) { result = rb_protect(func, farg, &status); } - if (fd[0] != -1 && fd[0] == GetReadFD(io)) { + GetOpenFile(io, fptr); + if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) { if (!setattr(fd[0], t+0)) { error = errno; status = -1; } } - if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(io)) { + if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(fptr)) { if (!setattr(fd[1], t+1)) { error = errno; status = -1; @@ -456,11 +435,15 @@ static VALUE console_set_raw(int argc, VALUE *argv, VALUE io) { conmode t; + rb_io_t *fptr; + int fd; rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts); - int fd = GetReadFD(io); - if (!getattr(fd, &t)) sys_fail(io); + + GetOpenFile(io, fptr); + fd = GetReadFD(fptr); + if (!getattr(fd, &t)) sys_fail_fptr(fptr); set_rawmode(&t, optp); - if (!setattr(fd, &t)) sys_fail(io); + if (!setattr(fd, &t)) sys_fail_fptr(fptr); return io; } @@ -496,10 +479,14 @@ static VALUE console_set_cooked(VALUE io) { conmode t; - int fd = GetReadFD(io); - if (!getattr(fd, &t)) sys_fail(io); + rb_io_t *fptr; + int fd; + + GetOpenFile(io, fptr); + fd = GetReadFD(fptr); + if (!getattr(fd, &t)) sys_fail_fptr(fptr); set_cookedmode(&t, NULL); - if (!setattr(fd, &t)) sys_fail(io); + if (!setattr(fd, &t)) sys_fail_fptr(fptr); return io; } @@ -651,17 +638,17 @@ static VALUE console_set_echo(VALUE io, VALUE f) { conmode t; - int fd = GetReadFD(io); - - if (!getattr(fd, &t)) sys_fail(io); + rb_io_t *fptr; + int fd; + GetOpenFile(io, fptr); + fd = GetReadFD(fptr); + if (!getattr(fd, &t)) sys_fail_fptr(fptr); if (RTEST(f)) - set_echo(&t, NULL); + set_echo(&t, NULL); else - set_noecho(&t, NULL); - - if (!setattr(fd, &t)) sys_fail(io); - + set_noecho(&t, NULL); + if (!setattr(fd, &t)) sys_fail_fptr(fptr); return io; } @@ -677,9 +664,12 @@ static VALUE console_echo_p(VALUE io) { conmode t; - int fd = GetReadFD(io); + rb_io_t *fptr; + int fd; - if (!getattr(fd, &t)) sys_fail(io); + GetOpenFile(io, fptr); + fd = GetReadFD(fptr); + if (!getattr(fd, &t)) sys_fail_fptr(fptr); return echo_p(&t) ? Qtrue : Qfalse; } @@ -758,9 +748,12 @@ static VALUE console_conmode_get(VALUE io) { conmode t; - int fd = GetReadFD(io); + rb_io_t *fptr; + int fd; - if (!getattr(fd, &t)) sys_fail(io); + GetOpenFile(io, fptr); + fd = GetReadFD(fptr); + if (!getattr(fd, &t)) sys_fail_fptr(fptr); return conmode_new(cConmode, &t); } @@ -777,12 +770,14 @@ static VALUE console_conmode_set(VALUE io, VALUE mode) { conmode *t, r; - int fd = GetReadFD(io); + rb_io_t *fptr; + int fd; TypedData_Get_Struct(mode, conmode, &conmode_type, t); r = *t; - - if (!setattr(fd, &r)) sys_fail(io); + GetOpenFile(io, fptr); + fd = GetReadFD(fptr); + if (!setattr(fd, &r)) sys_fail_fptr(fptr); return mode; } @@ -818,9 +813,13 @@ typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t; static VALUE console_winsize(VALUE io) { + rb_io_t *fptr; + int fd; rb_console_size_t ws; - int fd = GetWriteFD(io); - if (!getwinsize(fd, &ws)) sys_fail(io); + + GetOpenFile(io, fptr); + fd = GetWriteFD(fptr); + if (!getwinsize(fd, &ws)) sys_fail_fptr(fptr); return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws))); } @@ -836,6 +835,7 @@ console_winsize(VALUE io) static VALUE console_set_winsize(VALUE io, VALUE size) { + rb_io_t *fptr; rb_console_size_t ws; #if defined _WIN32 HANDLE wh; @@ -844,17 +844,20 @@ console_set_winsize(VALUE io, VALUE size) #endif VALUE row, col, xpixel, ypixel; const VALUE *sz; - long sizelen; int fd; + long sizelen; + GetOpenFile(io, fptr); size = rb_Array(size); if ((sizelen = RARRAY_LEN(size)) != 2 && sizelen != 4) { - rb_raise(rb_eArgError, "wrong number of arguments (given %ld, expected 2 or 4)", sizelen); + rb_raise(rb_eArgError, + "wrong number of arguments (given %ld, expected 2 or 4)", + sizelen); } sz = RARRAY_CONST_PTR(size); row = sz[0], col = sz[1], xpixel = ypixel = Qnil; if (sizelen == 4) xpixel = sz[2], ypixel = sz[3]; - fd = GetWriteFD(io); + fd = GetWriteFD(fptr); #if defined TIOCSWINSZ ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0; #define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) @@ -863,7 +866,7 @@ console_set_winsize(VALUE io, VALUE size) SET(xpixel); SET(ypixel); #undef SET - if (!setwinsize(fd, &ws)) sys_fail(io); + if (!setwinsize(fd, &ws)) sys_fail_fptr(fptr); #elif defined _WIN32 wh = (HANDLE)rb_w32_get_osfhandle(fd); #define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) @@ -901,10 +904,12 @@ console_set_winsize(VALUE io, VALUE size) static VALUE console_check_winsize_changed(VALUE io) { + rb_io_t *fptr; HANDLE h; DWORD num; - h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(io)); + GetOpenFile(io, fptr); + h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr)); while (GetNumberOfConsoleInputEvents(h, &num) && num > 0) { INPUT_RECORD rec; if (ReadConsoleInput(h, &rec, 1, &num)) { @@ -930,11 +935,15 @@ console_check_winsize_changed(VALUE io) static VALUE console_iflush(VALUE io) { + rb_io_t *fptr; + int fd; + + GetOpenFile(io, fptr); + fd = GetReadFD(fptr); #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H - int fd = GetReadFD(io); - if (tcflush(fd, TCIFLUSH)) sys_fail(io); + if (tcflush(fd, TCIFLUSH)) sys_fail_fptr(fptr); #endif - + (void)fd; return io; } @@ -949,9 +958,13 @@ console_iflush(VALUE io) static VALUE console_oflush(VALUE io) { - int fd = GetWriteFD(io); + rb_io_t *fptr; + int fd; + + GetOpenFile(io, fptr); + fd = GetWriteFD(fptr); #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H - if (tcflush(fd, TCOFLUSH)) sys_fail(io); + if (tcflush(fd, TCOFLUSH)) sys_fail_fptr(fptr); #endif (void)fd; return io; @@ -968,30 +981,40 @@ console_oflush(VALUE io) static VALUE console_ioflush(VALUE io) { + rb_io_t *fptr; #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H - int fd1 = GetReadFD(io); - int fd2 = GetWriteFD(io); + int fd1, fd2; +#endif + GetOpenFile(io, fptr); +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + fd1 = GetReadFD(fptr); + fd2 = GetWriteFD(fptr); if (fd2 != -1 && fd1 != fd2) { - if (tcflush(fd1, TCIFLUSH)) sys_fail(io); - if (tcflush(fd2, TCOFLUSH)) sys_fail(io); + if (tcflush(fd1, TCIFLUSH)) sys_fail_fptr(fptr); + if (tcflush(fd2, TCOFLUSH)) sys_fail_fptr(fptr); } else { - if (tcflush(fd1, TCIOFLUSH)) sys_fail(io); + if (tcflush(fd1, TCIOFLUSH)) sys_fail_fptr(fptr); } #endif - return io; } static VALUE console_beep(VALUE io) { + rb_io_t *fptr; + int fd; + + GetOpenFile(io, fptr); + fd = GetWriteFD(fptr); #ifdef _WIN32 + (void)fd; MessageBeep(0); #else - int fd = GetWriteFD(io); - if (write(fd, "\a", 1) < 0) sys_fail(io); + if (write(fd, "\a", 1) < 0) + sys_fail_fptr(fptr); #endif return io; } @@ -1015,8 +1038,12 @@ mode_in_range(VALUE val, int high, const char *modename) static VALUE console_goto(VALUE io, VALUE y, VALUE x) { + rb_io_t *fptr; + int fd; COORD pos; - int fd = GetWriteFD(io); + + GetOpenFile(io, fptr); + fd = GetWriteFD(fptr); pos.X = NUM2UINT(x); pos.Y = NUM2UINT(y); if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) { @@ -1028,8 +1055,12 @@ console_goto(VALUE io, VALUE y, VALUE x) static VALUE console_cursor_pos(VALUE io) { + rb_io_t *fptr; + int fd; rb_console_size_t ws; - int fd = GetWriteFD(io); + + GetOpenFile(io, fptr); + fd = GetWriteFD(fptr); if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) { rb_syserr_fail(LAST_ERROR, 0); } @@ -1039,11 +1070,13 @@ console_cursor_pos(VALUE io) static VALUE console_move(VALUE io, int y, int x) { + rb_io_t *fptr; HANDLE h; rb_console_size_t ws; COORD *pos = &ws.dwCursorPosition; - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + GetOpenFile(io, fptr); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); if (!GetConsoleScreenBufferInfo(h, &ws)) { rb_syserr_fail(LAST_ERROR, 0); } @@ -1058,11 +1091,13 @@ console_move(VALUE io, int y, int x) static VALUE console_goto_column(VALUE io, VALUE val) { + rb_io_t *fptr; HANDLE h; rb_console_size_t ws; COORD *pos = &ws.dwCursorPosition; - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + GetOpenFile(io, fptr); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); if (!GetConsoleScreenBufferInfo(h, &ws)) { rb_syserr_fail(LAST_ERROR, 0); } @@ -1085,13 +1120,15 @@ constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos) static VALUE console_erase_line(VALUE io, VALUE val) { + rb_io_t *fptr; HANDLE h; rb_console_size_t ws; COORD *pos = &ws.dwCursorPosition; DWORD w; int mode = mode_in_range(val, 2, "line erase"); - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + GetOpenFile(io, fptr); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); if (!GetConsoleScreenBufferInfo(h, &ws)) { rb_syserr_fail(LAST_ERROR, 0); } @@ -1115,13 +1152,15 @@ console_erase_line(VALUE io, VALUE val) static VALUE console_erase_screen(VALUE io, VALUE val) { + rb_io_t *fptr; HANDLE h; rb_console_size_t ws; COORD *pos = &ws.dwCursorPosition; DWORD w; int mode = mode_in_range(val, 3, "screen erase"); - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + GetOpenFile(io, fptr); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); if (!GetConsoleScreenBufferInfo(h, &ws)) { rb_syserr_fail(LAST_ERROR, 0); } @@ -1153,10 +1192,12 @@ console_erase_screen(VALUE io, VALUE val) static VALUE console_scroll(VALUE io, int line) { + rb_io_t *fptr; HANDLE h; rb_console_size_t ws; - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + GetOpenFile(io, fptr); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); if (!GetConsoleScreenBufferInfo(h, &ws)) { rb_syserr_fail(LAST_ERROR, 0); } @@ -1215,11 +1256,23 @@ static int direct_query(VALUE io, const struct query_args *query) { if (RB_TYPE_P(io, T_FILE)) { - VALUE wio = rb_io_get_write_io(io); - VALUE s = rb_str_new_cstr(query->qstr); - rb_io_write(wio, s); - rb_io_flush(wio); - return 1; + rb_io_t *fptr; + VALUE wio; + GetOpenFile(io, fptr); + wio = fptr->tied_io_for_writing; + if (wio) { + VALUE s = rb_str_new_cstr(query->qstr); + rb_io_write(wio, s); + rb_io_flush(wio); + return 1; + } + if (write(fptr->fd, query->qstr, strlen(query->qstr)) != -1) { + return 1; + } + if (fptr->fd == 0 && + write(1, query->qstr, strlen(query->qstr)) != -1) { + return 1; + } } return 0; } @@ -1398,38 +1451,6 @@ console_clear_screen(VALUE io) return io; } -#ifndef HAVE_RB_IO_OPEN_DESCRIPTOR -static VALUE -io_open_descriptor_fallback(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, void *encoding) -{ - rb_update_max_fd(descriptor); - - VALUE arguments[2] = { - INT2NUM(descriptor), - INT2FIX(mode), - }; - - VALUE self = rb_class_new_instance(2, arguments, klass); - - rb_io_t *fptr; - GetOpenFile(self, fptr); - fptr->pathv = path; - fptr->mode |= mode; - - return self; -} -#define rb_io_open_descriptor io_open_descriptor_fallback -#endif - -#ifndef HAVE_RB_IO_CLOSED_P -static VALUE -rb_io_closed_p(VALUE io) -{ - rb_io_t *fptr = RFILE(io)->fptr; - return fptr->fd == -1 ? Qtrue : Qfalse; -} -#endif - /* * call-seq: * IO.console -> #<File:/dev/tty> @@ -1447,37 +1468,34 @@ static VALUE console_dev(int argc, VALUE *argv, VALUE klass) { VALUE con = 0; + rb_io_t *fptr; VALUE sym = 0; rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS); - if (argc) { - Check_Type(sym = argv[0], T_SYMBOL); + Check_Type(sym = argv[0], T_SYMBOL); } - - // Force the class to be File. 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) || RTEST(rb_io_closed_p(con))) { - rb_const_remove(klass, id_console); - con = 0; - } + con = rb_const_get(klass, id_console); + if (!RB_TYPE_P(con, T_FILE) || + (!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) { + rb_const_remove(klass, id_console); + con = 0; + } } - if (sym) { - if (sym == ID2SYM(id_close) && argc == 1) { - if (con) { - rb_io_close(con); - rb_const_remove(klass, id_console); - con = 0; - } - return Qnil; - } + if (sym == ID2SYM(id_close) && argc == 1) { + 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" #elif defined _WIN32 @@ -1489,36 +1507,44 @@ console_dev(int argc, VALUE *argv, VALUE klass) # define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE #endif #ifdef CONSOLE_DEVICE_FOR_WRITING - VALUE out; - rb_io_t *ofptr; + VALUE out; + rb_io_t *ofptr; #endif - int fd; - VALUE path = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE)); + int fd; #ifdef CONSOLE_DEVICE_FOR_WRITING - fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0); - if (fd < 0) return Qnil; - out = rb_io_open_descriptor(klass, fd, FMODE_WRITABLE | FMODE_SYNC, path, Qnil, NULL); + fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0); + if (fd < 0) return Qnil; + rb_update_max_fd(fd); + args[1] = INT2FIX(O_WRONLY); + args[0] = INT2NUM(fd); + out = rb_class_new_instance(2, args, klass); #endif - fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0); - if (fd < 0) { + fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0); + if (fd < 0) { #ifdef CONSOLE_DEVICE_FOR_WRITING - rb_io_close(out); + rb_io_close(out); #endif - return Qnil; - } - - con = rb_io_open_descriptor(klass, fd, FMODE_READWRITE | FMODE_SYNC, path, Qnil, NULL); + return Qnil; + } + rb_update_max_fd(fd); + args[1] = INT2FIX(O_RDWR); + args[0] = INT2NUM(fd); + con = rb_class_new_instance(2, args, klass); + GetOpenFile(con, fptr); + fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE)); #ifdef CONSOLE_DEVICE_FOR_WRITING - rb_io_set_write_io(con, out); + GetOpenFile(out, ofptr); + ofptr->pathv = fptr->pathv; + fptr->tied_io_for_writing = out; + ofptr->mode |= FMODE_SYNC; #endif - rb_const_set(klass, id_console, con); + fptr->mode |= FMODE_SYNC; + rb_const_set(klass, id_console, con); } - if (sym) { - return rb_f_send(argc, argv, con); + return rb_f_send(argc, argv, con); } - return con; } diff --git a/ext/io/console/extconf.rb b/ext/io/console/extconf.rb index 3cbe8954d4..e8c5923b18 100644 --- a/ext/io/console/extconf.rb +++ b/ext/io/console/extconf.rb @@ -1,12 +1,6 @@ # frozen_string_literal: false require 'mkmf' -have_func("rb_io_path") -have_func("rb_io_descriptor") -have_func("rb_io_get_write_io") -have_func("rb_io_closed_p") -have_func("rb_io_open_descriptor") - ok = true if RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby" hdr = nil case |