io-console 0.4.2 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f84c71a10c07466a96df3e243d33729d409b5983
4
- data.tar.gz: 82ffd31d1858ed4d574efad6ef0ed86fb65636a8
3
+ metadata.gz: b8b1a359f6f19ba1ff5ba0afb46398547b33b600
4
+ data.tar.gz: 7ab4864fa4909efabba6c472b6a04612316be845
5
5
  SHA512:
6
- metadata.gz: ec1125bd8d61efee82b4bfcdc2de73b5a4b075b622a19e911408e4262415b7e2707f9c643bf711f7ddc4b6e64c2861585f99b0a3cd21539f811197042d0de40a
7
- data.tar.gz: 1748231bba6d1a9adb725424878d63562a8fae3dc6fb066651c4d4c56a59d103a34812b7b66fbd6abec1a2fdc13121fb0423b02bb3cf5e781d12851813e1d6f8
6
+ metadata.gz: dcfe215f5ad7a1f0cbc2e9440ab5bae8f481b6eaa9f0658eff2b0d95fb0402d2619ce311b5978060a5f7f14e3252728b9b1170e2fd5f864c816e6f546d4fa372
7
+ data.tar.gz: e02e7f3e0f4db8e931a558e0e8cf46eb400886af7a96921448c321b3d49e94d1b629a78e7234cbc5e0bb7027985b5cd0a3989b1e9a4f0e112e238841aae8fe1b
@@ -0,0 +1,3 @@
1
+ yicq�݂��Nb{}}le���B��On}6���j��̐����L����K�i���Z�!�c�0,��b��8�A{���{f� �_G9y :v���qG$�q�*9�yb8G�?Q��2�D��$�=�$�+ÞX
2
+ bݏ�t��Xe�spPv� ��>dϙ�O��GU�W��+8a�y�e-ϙ��(>pL!;�a���Z�
3
+ H�G�_���,t���+��d���OSCC <�5ʤ�H�Ï�ـݸ�-���;q��"T~�^
Binary file
data/console.c CHANGED
@@ -3,17 +3,7 @@
3
3
  * console IO module
4
4
  */
5
5
  #include "ruby.h"
6
- #ifdef HAVE_RUBY_IO_H
7
6
  #include "ruby/io.h"
8
- #else
9
- #include "rubyio.h"
10
- /* assumes rb_io_t doesn't have pathv */
11
- #include "util.h" /* for ruby_strdup() */
12
- #endif
13
-
14
- #ifndef HAVE_RB_IO_T
15
- typedef OpenFile rb_io_t;
16
- #endif
17
7
 
18
8
  #ifdef HAVE_UNISTD_H
19
9
  #include <unistd.h>
@@ -25,10 +15,6 @@ typedef OpenFile rb_io_t;
25
15
  #include <sys/ioctl.h>
26
16
  #endif
27
17
 
28
- #ifndef RB_TYPE_P
29
- #define RB_TYPE_P(obj, type) (TYPE(obj) == type)
30
- #endif
31
-
32
18
  #if defined HAVE_TERMIOS_H
33
19
  # include <termios.h>
34
20
  typedef struct termios conmode;
@@ -64,11 +50,7 @@ typedef struct sgttyb conmode;
64
50
  #include <winioctl.h>
65
51
  typedef DWORD conmode;
66
52
 
67
- #ifdef HAVE_RB_W32_MAP_ERRNO
68
53
  #define LAST_ERROR rb_w32_map_errno(GetLastError())
69
- #else
70
- #define LAST_ERROR EBADF
71
- #endif
72
54
  #define SET_LAST_ERROR (errno = LAST_ERROR, 0)
73
55
 
74
56
  static int
@@ -91,11 +73,29 @@ getattr(int fd, conmode *t)
91
73
  #define SET_LAST_ERROR (0)
92
74
  #endif
93
75
 
94
- #ifndef InitVM
95
- #define InitVM(ext) {void InitVM_##ext(void);InitVM_##ext();}
76
+ static ID id_getc, id_console, id_close, id_min, id_time;
77
+ #if ENABLE_IO_GETPASS
78
+ static ID id_gets;
96
79
  #endif
97
80
 
98
- static ID id_getc, id_console;
81
+ #ifndef HAVE_RB_F_SEND
82
+ static ID id___send__;
83
+
84
+ static VALUE
85
+ rb_f_send(int argc, VALUE *argv, VALUE recv)
86
+ {
87
+ VALUE sym = argv[0];
88
+ ID vid = rb_check_id(&sym);
89
+ if (vid) {
90
+ --argc;
91
+ ++argv;
92
+ }
93
+ else {
94
+ vid = id___send__;
95
+ }
96
+ return rb_funcallv(recv, vid, argc, argv);
97
+ }
98
+ #endif
99
99
 
100
100
  typedef struct {
101
101
  int vmin;
@@ -107,26 +107,10 @@ rawmode_opt(int argc, VALUE *argv, rawmode_arg_t *opts)
107
107
  {
108
108
  rawmode_arg_t *optp = NULL;
109
109
  VALUE vopts;
110
- #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
111
110
  rb_scan_args(argc, argv, "0:", &vopts);
112
- #else
113
- vopts = Qnil;
114
- if (argc > 0) {
115
- vopts = argv[--argc];
116
- if (!NIL_P(vopts)) {
117
- # ifdef HAVE_RB_CHECK_HASH_TYPE
118
- vopts = rb_check_hash_type(vopts);
119
- if (NIL_P(vopts)) ++argc;
120
- # else
121
- Check_Type(vopts, T_HASH);
122
- # endif
123
- }
124
- }
125
- rb_scan_args(argc, argv, "0");
126
- #endif
127
111
  if (!NIL_P(vopts)) {
128
- VALUE vmin = rb_hash_aref(vopts, ID2SYM(rb_intern("min")));
129
- VALUE vtime = rb_hash_aref(vopts, ID2SYM(rb_intern("time")));
112
+ VALUE vmin = rb_hash_aref(vopts, ID2SYM(id_min));
113
+ VALUE vtime = rb_hash_aref(vopts, ID2SYM(id_time));
130
114
  /* default values by `stty raw` */
131
115
  opts->vmin = 1;
132
116
  opts->vtime = 0;
@@ -232,15 +216,8 @@ set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg)
232
216
  return setattr(fd, &r);
233
217
  }
234
218
 
235
- #ifdef GetReadFile
236
- #define GetReadFD(fptr) fileno(GetReadFile(fptr))
237
- #else
238
219
  #define GetReadFD(fptr) ((fptr)->fd)
239
- #endif
240
220
 
241
- #ifdef GetWriteFile
242
- #define GetWriteFD(fptr) fileno(GetWriteFile(fptr))
243
- #else
244
221
  static inline int
245
222
  get_write_fd(const rb_io_t *fptr)
246
223
  {
@@ -251,7 +228,6 @@ get_write_fd(const rb_io_t *fptr)
251
228
  return ofptr->fd;
252
229
  }
253
230
  #define GetWriteFD(fptr) get_write_fd(fptr)
254
- #endif
255
231
 
256
232
  #define FD_PER_IO 2
257
233
 
@@ -304,8 +280,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void
304
280
  }
305
281
  if (status) {
306
282
  if (status == -1) {
307
- errno = error;
308
- rb_sys_fail(0);
283
+ rb_syserr_fail(error, 0);
309
284
  }
310
285
  rb_jump_tag(status);
311
286
  }
@@ -548,16 +523,16 @@ console_set_winsize(VALUE io, VALUE size)
548
523
  int newrow, newcol;
549
524
  #endif
550
525
  VALUE row, col, xpixel, ypixel;
551
- #if defined TIOCSWINSZ
526
+ const VALUE *sz;
552
527
  int fd;
553
- #endif
554
528
 
555
529
  GetOpenFile(io, fptr);
556
530
  size = rb_Array(size);
557
- rb_scan_args((int)RARRAY_LEN(size), RARRAY_PTR(size), "22",
558
- &row, &col, &xpixel, &ypixel);
559
- #if defined TIOCSWINSZ
531
+ rb_check_arity(RARRAY_LENINT(size), 2, 4);
532
+ sz = RARRAY_CONST_PTR(size);
533
+ row = sz[0], col = sz[1], xpixel = sz[2], ypixel = sz[3];
560
534
  fd = GetWriteFD(fptr);
535
+ #if defined TIOCSWINSZ
561
536
  ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0;
562
537
  #define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
563
538
  SET(row);
@@ -567,24 +542,28 @@ console_set_winsize(VALUE io, VALUE size)
567
542
  #undef SET
568
543
  if (!setwinsize(fd, &ws)) rb_sys_fail(0);
569
544
  #elif defined _WIN32
570
- wh = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr));
571
- newrow = (SHORT)NUM2UINT(row);
572
- newcol = (SHORT)NUM2UINT(col);
573
- if (!getwinsize(GetReadFD(fptr), &ws)) {
574
- rb_sys_fail("GetConsoleScreenBufferInfo");
545
+ wh = (HANDLE)rb_w32_get_osfhandle(fd);
546
+ #define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
547
+ SET(row);
548
+ SET(col);
549
+ #undef SET
550
+ if (!NIL_P(xpixel)) (void)NUM2UINT(xpixel);
551
+ if (!NIL_P(ypixel)) (void)NUM2UINT(ypixel);
552
+ if (!GetConsoleScreenBufferInfo(wh, &ws)) {
553
+ rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo");
575
554
  }
576
555
  if ((ws.dwSize.X < newcol && (ws.dwSize.X = newcol, 1)) ||
577
556
  (ws.dwSize.Y < newrow && (ws.dwSize.Y = newrow, 1))) {
578
- if (!(SetConsoleScreenBufferSize(wh, ws.dwSize) || SET_LAST_ERROR)) {
579
- rb_sys_fail("SetConsoleScreenBufferInfo");
557
+ if (!SetConsoleScreenBufferSize(wh, ws.dwSize)) {
558
+ rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo");
580
559
  }
581
560
  }
582
561
  ws.srWindow.Left = 0;
583
562
  ws.srWindow.Top = 0;
584
563
  ws.srWindow.Right = newcol;
585
564
  ws.srWindow.Bottom = newrow;
586
- if (!(SetConsoleWindowInfo(wh, FALSE, &ws.srWindow) || SET_LAST_ERROR)) {
587
- rb_sys_fail("SetConsoleWindowInfo");
565
+ if (!SetConsoleWindowInfo(wh, FALSE, &ws.srWindow)) {
566
+ rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo");
588
567
  }
589
568
  #endif
590
569
  return io;
@@ -610,6 +589,7 @@ console_iflush(VALUE io)
610
589
  #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
611
590
  if (tcflush(fd, TCIFLUSH)) rb_sys_fail(0);
612
591
  #endif
592
+ (void)fd;
613
593
  return io;
614
594
  }
615
595
 
@@ -632,6 +612,7 @@ console_oflush(VALUE io)
632
612
  #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
633
613
  if (tcflush(fd, TCOFLUSH)) rb_sys_fail(0);
634
614
  #endif
615
+ (void)fd;
635
616
  return io;
636
617
  }
637
618
 
@@ -666,47 +647,141 @@ console_ioflush(VALUE io)
666
647
  return io;
667
648
  }
668
649
 
669
- #ifndef HAVE_RB_CLOEXEC_OPEN
670
- static int
671
- rb_cloexec_open(const char *pathname, int flags, mode_t mode)
650
+ static VALUE
651
+ console_beep(VALUE io)
672
652
  {
673
- int ret;
674
- #ifdef O_CLOEXEC
675
- /* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */
676
- flags |= O_CLOEXEC;
677
- #elif defined O_NOINHERIT
678
- flags |= O_NOINHERIT;
653
+ rb_io_t *fptr;
654
+ int fd;
655
+
656
+ GetOpenFile(io, fptr);
657
+ fd = GetWriteFD(fptr);
658
+ #ifdef _WIN32
659
+ (void)fd;
660
+ MessageBeep(0);
661
+ #else
662
+ if (write(fd, "\a", 1) < 0)
663
+ rb_sys_fail(0);
679
664
  #endif
680
- return open(pathname, flags, mode);
665
+ return io;
681
666
  }
682
667
 
683
- #define rb_update_max_fd(fd) (void)(fd)
668
+ #if defined _WIN32
669
+ static VALUE
670
+ console_goto(VALUE io, VALUE x, VALUE y)
671
+ {
672
+ rb_io_t *fptr;
673
+ int fd;
674
+ COORD pos;
675
+
676
+ GetOpenFile(io, fptr);
677
+ fd = GetWriteFD(fptr);
678
+ pos.X = NUM2UINT(x);
679
+ pos.Y = NUM2UINT(y);
680
+ if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
681
+ rb_syserr_fail(LAST_ERROR, 0);
682
+ }
683
+ return io;
684
+ }
685
+
686
+ static VALUE
687
+ console_cursor_pos(VALUE io)
688
+ {
689
+ rb_io_t *fptr;
690
+ int fd;
691
+ rb_console_size_t ws;
692
+
693
+ GetOpenFile(io, fptr);
694
+ fd = GetWriteFD(fptr);
695
+ if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
696
+ rb_syserr_fail(LAST_ERROR, 0);
697
+ }
698
+ return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.X), UINT2NUM(ws.dwCursorPosition.Y));
699
+ }
700
+
701
+ static VALUE
702
+ console_cursor_set(VALUE io, VALUE cpos)
703
+ {
704
+ cpos = rb_convert_type(cpos, T_ARRAY, "Array", "to_ary");
705
+ if (RARRAY_LEN(cpos) != 2) rb_raise(rb_eArgError, "expected 2D coordinate");
706
+ return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1));
707
+ }
708
+
709
+ #include "win32_vk.inc"
710
+
711
+ static VALUE
712
+ console_key_pressed_p(VALUE io, VALUE k)
713
+ {
714
+ int vk = -1;
715
+
716
+ if (FIXNUM_P(k)) {
717
+ vk = NUM2UINT(k);
718
+ }
719
+ else {
720
+ const struct vktable *t;
721
+ if (SYMBOL_P(k)) {
722
+ k = rb_sym2str(k);
723
+ }
724
+ else {
725
+ StringValueCStr(k);
726
+ }
727
+ t = console_win32_vk(RSTRING_PTR(k), RSTRING_LEN(k));
728
+ if (!t || (vk = (short)t->vk) == -1) {
729
+ rb_raise(rb_eArgError, "unknown virtual key code: %"PRIsVALUE, k);
730
+ }
731
+ }
732
+ return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse;
733
+ }
734
+ #else
735
+ # define console_goto rb_f_notimplement
736
+ # define console_cursor_pos rb_f_notimplement
737
+ # define console_cursor_set rb_f_notimplement
738
+ # define console_key_pressed_p rb_f_notimplement
684
739
  #endif
685
740
 
686
741
  /*
687
742
  * call-seq:
688
743
  * IO.console -> #<File:/dev/tty>
744
+ * IO.console(sym, *args)
689
745
  *
690
746
  * Returns an File instance opened console.
691
747
  *
748
+ * If +sym+ is given, it will be sent to the opened console with
749
+ * +args+ and the result will be returned instead of the console IO
750
+ * itself.
751
+ *
692
752
  * You must require 'io/console' to use this method.
693
753
  */
694
754
  static VALUE
695
- console_dev(VALUE klass)
755
+ console_dev(int argc, VALUE *argv, VALUE klass)
696
756
  {
697
757
  VALUE con = 0;
698
758
  rb_io_t *fptr;
759
+ VALUE sym = 0;
699
760
 
761
+ rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS);
762
+ if (argc) {
763
+ Check_Type(sym = argv[0], T_SYMBOL);
764
+ }
700
765
  if (klass == rb_cIO) klass = rb_cFile;
701
766
  if (rb_const_defined(klass, id_console)) {
702
767
  con = rb_const_get(klass, id_console);
703
- if (RB_TYPE_P(con, T_FILE)) {
704
- if ((fptr = RFILE(con)->fptr) && GetReadFD(fptr) != -1)
705
- return con;
768
+ if (!RB_TYPE_P(con, T_FILE) ||
769
+ (!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) {
770
+ rb_const_remove(klass, id_console);
771
+ con = 0;
706
772
  }
707
- rb_mod_remove_const(klass, ID2SYM(id_console));
708
773
  }
709
- {
774
+ if (sym) {
775
+ if (sym == ID2SYM(id_close) && argc == 1) {
776
+ if (con) {
777
+ rb_io_close(con);
778
+ rb_const_remove(klass, id_console);
779
+ con = 0;
780
+ }
781
+ return Qnil;
782
+ }
783
+ }
784
+ if (!con) {
710
785
  VALUE args[2];
711
786
  #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
712
787
  # define CONSOLE_DEVICE "/dev/tty"
@@ -725,7 +800,7 @@ console_dev(VALUE klass)
725
800
  int fd;
726
801
 
727
802
  #ifdef CONSOLE_DEVICE_FOR_WRITING
728
- fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_WRONLY, 0);
803
+ fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
729
804
  if (fd < 0) return Qnil;
730
805
  rb_update_max_fd(fd);
731
806
  args[1] = INT2FIX(O_WRONLY);
@@ -744,42 +819,126 @@ console_dev(VALUE klass)
744
819
  args[0] = INT2NUM(fd);
745
820
  con = rb_class_new_instance(2, args, klass);
746
821
  GetOpenFile(con, fptr);
747
- #ifdef HAVE_RUBY_IO_H
748
822
  fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
749
- #else
750
- fptr->path = ruby_strdup(CONSOLE_DEVICE);
751
- #endif
752
823
  #ifdef CONSOLE_DEVICE_FOR_WRITING
753
824
  GetOpenFile(out, ofptr);
754
- # ifdef HAVE_RB_IO_GET_WRITE_IO
755
825
  ofptr->pathv = fptr->pathv;
756
826
  fptr->tied_io_for_writing = out;
757
- # else
758
- fptr->f2 = ofptr->f;
759
- ofptr->f = 0;
760
- # endif
761
827
  ofptr->mode |= FMODE_SYNC;
762
828
  #endif
763
829
  fptr->mode |= FMODE_SYNC;
764
830
  rb_const_set(klass, id_console, con);
765
831
  }
832
+ if (sym) {
833
+ return rb_f_send(argc, argv, con);
834
+ }
766
835
  return con;
767
836
  }
768
837
 
838
+ /*
839
+ * call-seq:
840
+ * io.getch(min: nil, time: nil) -> char
841
+ *
842
+ * See IO#getch.
843
+ */
769
844
  static VALUE
770
845
  io_getch(int argc, VALUE *argv, VALUE io)
771
846
  {
772
- return rb_funcall2(io, rb_intern("getc"), argc, argv);
847
+ return rb_funcall2(io, id_getc, argc, argv);
848
+ }
849
+
850
+ #if ENABLE_IO_GETPASS
851
+ static VALUE
852
+ puts_call(VALUE io)
853
+ {
854
+ return rb_io_write(io, rb_default_rs);
855
+ }
856
+
857
+ static VALUE
858
+ getpass_call(VALUE io)
859
+ {
860
+ return ttymode(io, rb_io_gets, set_noecho, NULL);
861
+ }
862
+
863
+ static void
864
+ prompt(int argc, VALUE *argv, VALUE io)
865
+ {
866
+ if (argc > 0 && !NIL_P(argv[0])) {
867
+ VALUE str = argv[0];
868
+ StringValueCStr(str);
869
+ rb_check_safe_obj(str);
870
+ rb_io_write(io, str);
871
+ }
872
+ }
873
+
874
+ static VALUE
875
+ str_chomp(VALUE str)
876
+ {
877
+ if (!NIL_P(str)) {
878
+ str = rb_funcallv(str, rb_intern("chomp!"), 0, 0);
879
+ }
880
+ return str;
881
+ }
882
+
883
+ /*
884
+ * call-seq:
885
+ * io.getpass(prompt=nil) -> string
886
+ *
887
+ * Reads and returns a line without echo back.
888
+ * Prints +prompt+ unless it is +nil+.
889
+ *
890
+ * You must require 'io/console' to use this method.
891
+ */
892
+ static VALUE
893
+ console_getpass(int argc, VALUE *argv, VALUE io)
894
+ {
895
+ VALUE str, wio;
896
+
897
+ rb_check_arity(argc, 0, 1);
898
+ wio = rb_io_get_write_io(io);
899
+ if (wio == io && io == rb_stdin) wio = rb_stderr;
900
+ prompt(argc, argv, wio);
901
+ str = rb_ensure(getpass_call, io, puts_call, wio);
902
+ return str_chomp(str);
773
903
  }
774
904
 
905
+ /*
906
+ * call-seq:
907
+ * io.getpass(prompt=nil) -> string
908
+ *
909
+ * See IO#getpass.
910
+ */
911
+ static VALUE
912
+ io_getpass(int argc, VALUE *argv, VALUE io)
913
+ {
914
+ VALUE str;
915
+
916
+ rb_check_arity(argc, 0, 1);
917
+ prompt(argc, argv, io);
918
+ str = str_chomp(rb_funcallv(io, id_gets, 0, 0));
919
+ puts_call(io);
920
+ return str;
921
+ }
922
+ #endif
923
+
775
924
  /*
776
925
  * IO console methods
777
926
  */
778
927
  void
779
928
  Init_console(void)
780
929
  {
930
+ #undef rb_intern
781
931
  id_getc = rb_intern("getc");
932
+ #if ENABLE_IO_GETPASS
933
+ id_gets = rb_intern("gets");
934
+ #endif
782
935
  id_console = rb_intern("console");
936
+ id_close = rb_intern("close");
937
+ id_min = rb_intern("min");
938
+ id_time = rb_intern("time");
939
+ #ifndef HAVE_RB_F_SEND
940
+ id___send__ = rb_intern("__send__");
941
+ #endif
783
942
  InitVM(console);
784
943
  }
785
944
 
@@ -799,9 +958,20 @@ InitVM_console(void)
799
958
  rb_define_method(rb_cIO, "iflush", console_iflush, 0);
800
959
  rb_define_method(rb_cIO, "oflush", console_oflush, 0);
801
960
  rb_define_method(rb_cIO, "ioflush", console_ioflush, 0);
802
- rb_define_singleton_method(rb_cIO, "console", console_dev, 0);
961
+ rb_define_method(rb_cIO, "beep", console_beep, 0);
962
+ rb_define_method(rb_cIO, "goto", console_goto, 2);
963
+ rb_define_method(rb_cIO, "cursor", console_cursor_pos, 0);
964
+ rb_define_method(rb_cIO, "cursor=", console_cursor_set, 1);
965
+ rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1);
966
+ #if ENABLE_IO_GETPASS
967
+ rb_define_method(rb_cIO, "getpass", console_getpass, -1);
968
+ #endif
969
+ rb_define_singleton_method(rb_cIO, "console", console_dev, -1);
803
970
  {
804
- VALUE mReadable = rb_define_module_under(rb_cIO, "readable");
971
+ VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
805
972
  rb_define_method(mReadable, "getch", io_getch, -1);
973
+ #if ENABLE_IO_GETPASS
974
+ rb_define_method(mReadable, "getpass", io_getpass, -1);
975
+ #endif
806
976
  }
807
977
  }