io-console 0.4.7-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +46 -0
- data/ext/io/console/console.c +1002 -0
- data/ext/io/console/extconf.rb +30 -0
- data/ext/io/console/win32_vk.inc +1391 -0
- data/lib/2.2/io/console.so +0 -0
- data/lib/2.3/io/console.so +0 -0
- data/lib/2.4/io/console.so +0 -0
- data/lib/2.5/io/console.so +0 -0
- data/lib/io/console.rb +5 -0
- data/lib/io/console/size.rb +23 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d0d7feada83f3628959f3070c85ae4ed74317c0d8c5a7f27c198ab0bc22c3fe5
|
4
|
+
data.tar.gz: 744a9bbb6129118c2e24e1065fde4aa2618fc5d14a2d247e188d06802eeb9168
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0a536b75cf29c4d4fdc6e78dc9b3d77380caf9b165ba2a3b55210dbc1051de9883ae8b3b352ab4eafc132da3fbfffa2d354fe81e6b4b943071f75009592bb694
|
7
|
+
data.tar.gz: 0d0f3cb369529430127d19584a7a8f701d77b41c57f0ddf4c622e0e21e2288c651d3591dd9cca8de4e149bc7649f92b14be38e92ee47214f35bbfb28348f7edf
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
|
+
SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# IO.console
|
2
|
+
|
3
|
+
Add console capabilities to IO instances.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'io-console'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install io-console
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'io/console'
|
25
|
+
|
26
|
+
IO.console -> #<File:/dev/tty>
|
27
|
+
IO.console(sym, *args)
|
28
|
+
```
|
29
|
+
|
30
|
+
Returns an File instance opened console.
|
31
|
+
|
32
|
+
If `sym` is given, it will be sent to the opened console with `args` and the result will be returned instead of the console IO itself.
|
33
|
+
|
34
|
+
## Development
|
35
|
+
|
36
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
37
|
+
|
38
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
39
|
+
|
40
|
+
## Contributing
|
41
|
+
|
42
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/io-console.
|
43
|
+
|
44
|
+
## License
|
45
|
+
|
46
|
+
The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
|
@@ -0,0 +1,1002 @@
|
|
1
|
+
/* -*- c-file-style: "ruby" -*- */
|
2
|
+
/*
|
3
|
+
* console IO module
|
4
|
+
*/
|
5
|
+
#include "ruby.h"
|
6
|
+
#include "ruby/io.h"
|
7
|
+
|
8
|
+
#ifdef HAVE_UNISTD_H
|
9
|
+
#include <unistd.h>
|
10
|
+
#endif
|
11
|
+
#ifdef HAVE_FCNTL_H
|
12
|
+
#include <fcntl.h>
|
13
|
+
#endif
|
14
|
+
#ifdef HAVE_SYS_IOCTL_H
|
15
|
+
#include <sys/ioctl.h>
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#if defined HAVE_TERMIOS_H
|
19
|
+
# include <termios.h>
|
20
|
+
typedef struct termios conmode;
|
21
|
+
|
22
|
+
static int
|
23
|
+
setattr(int fd, conmode *t)
|
24
|
+
{
|
25
|
+
while (tcsetattr(fd, TCSAFLUSH, t)) {
|
26
|
+
if (errno != EINTR) return 0;
|
27
|
+
}
|
28
|
+
return 1;
|
29
|
+
}
|
30
|
+
# define getattr(fd, t) (tcgetattr(fd, t) == 0)
|
31
|
+
#elif defined HAVE_TERMIO_H
|
32
|
+
# include <termio.h>
|
33
|
+
typedef struct termio conmode;
|
34
|
+
# define setattr(fd, t) (ioctl(fd, TCSETAF, t) == 0)
|
35
|
+
# define getattr(fd, t) (ioctl(fd, TCGETA, t) == 0)
|
36
|
+
#elif defined HAVE_SGTTY_H
|
37
|
+
# include <sgtty.h>
|
38
|
+
typedef struct sgttyb conmode;
|
39
|
+
# ifdef HAVE_STTY
|
40
|
+
# define setattr(fd, t) (stty(fd, t) == 0)
|
41
|
+
# else
|
42
|
+
# define setattr(fd, t) (ioctl((fd), TIOCSETP, (t)) == 0)
|
43
|
+
# endif
|
44
|
+
# ifdef HAVE_GTTY
|
45
|
+
# define getattr(fd, t) (gtty(fd, t) == 0)
|
46
|
+
# else
|
47
|
+
# define getattr(fd, t) (ioctl((fd), TIOCGETP, (t)) == 0)
|
48
|
+
# endif
|
49
|
+
#elif defined _WIN32
|
50
|
+
#include <winioctl.h>
|
51
|
+
typedef DWORD conmode;
|
52
|
+
|
53
|
+
#define LAST_ERROR rb_w32_map_errno(GetLastError())
|
54
|
+
#define SET_LAST_ERROR (errno = LAST_ERROR, 0)
|
55
|
+
|
56
|
+
static int
|
57
|
+
setattr(int fd, conmode *t)
|
58
|
+
{
|
59
|
+
int x = SetConsoleMode((HANDLE)rb_w32_get_osfhandle(fd), *t);
|
60
|
+
if (!x) errno = LAST_ERROR;
|
61
|
+
return x;
|
62
|
+
}
|
63
|
+
|
64
|
+
static int
|
65
|
+
getattr(int fd, conmode *t)
|
66
|
+
{
|
67
|
+
int x = GetConsoleMode((HANDLE)rb_w32_get_osfhandle(fd), t);
|
68
|
+
if (!x) errno = LAST_ERROR;
|
69
|
+
return x;
|
70
|
+
}
|
71
|
+
#endif
|
72
|
+
#ifndef SET_LAST_ERROR
|
73
|
+
#define SET_LAST_ERROR (0)
|
74
|
+
#endif
|
75
|
+
|
76
|
+
static ID id_getc, id_console, id_close, id_min, id_time;
|
77
|
+
#if ENABLE_IO_GETPASS
|
78
|
+
static ID id_gets;
|
79
|
+
#endif
|
80
|
+
|
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
|
+
|
100
|
+
typedef struct {
|
101
|
+
int vmin;
|
102
|
+
int vtime;
|
103
|
+
} rawmode_arg_t;
|
104
|
+
|
105
|
+
static rawmode_arg_t *
|
106
|
+
rawmode_opt(int argc, VALUE *argv, rawmode_arg_t *opts)
|
107
|
+
{
|
108
|
+
rawmode_arg_t *optp = NULL;
|
109
|
+
VALUE vopts;
|
110
|
+
rb_scan_args(argc, argv, "0:", &vopts);
|
111
|
+
if (!NIL_P(vopts)) {
|
112
|
+
VALUE vmin = rb_hash_aref(vopts, ID2SYM(id_min));
|
113
|
+
VALUE vtime = rb_hash_aref(vopts, ID2SYM(id_time));
|
114
|
+
/* default values by `stty raw` */
|
115
|
+
opts->vmin = 1;
|
116
|
+
opts->vtime = 0;
|
117
|
+
if (!NIL_P(vmin)) {
|
118
|
+
opts->vmin = NUM2INT(vmin);
|
119
|
+
optp = opts;
|
120
|
+
}
|
121
|
+
if (!NIL_P(vtime)) {
|
122
|
+
VALUE v10 = INT2FIX(10);
|
123
|
+
vtime = rb_funcall3(vtime, '*', 1, &v10);
|
124
|
+
opts->vtime = NUM2INT(vtime);
|
125
|
+
optp = opts;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
return optp;
|
129
|
+
}
|
130
|
+
|
131
|
+
static void
|
132
|
+
set_rawmode(conmode *t, void *arg)
|
133
|
+
{
|
134
|
+
#ifdef HAVE_CFMAKERAW
|
135
|
+
cfmakeraw(t);
|
136
|
+
t->c_lflag &= ~(ECHOE|ECHOK);
|
137
|
+
#elif defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
138
|
+
t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
139
|
+
t->c_oflag &= ~OPOST;
|
140
|
+
t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN);
|
141
|
+
t->c_cflag &= ~(CSIZE|PARENB);
|
142
|
+
t->c_cflag |= CS8;
|
143
|
+
#elif defined HAVE_SGTTY_H
|
144
|
+
t->sg_flags &= ~ECHO;
|
145
|
+
t->sg_flags |= RAW;
|
146
|
+
#elif defined _WIN32
|
147
|
+
*t = 0;
|
148
|
+
#endif
|
149
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
150
|
+
if (arg) {
|
151
|
+
const rawmode_arg_t *r = arg;
|
152
|
+
if (r->vmin >= 0) t->c_cc[VMIN] = r->vmin;
|
153
|
+
if (r->vtime >= 0) t->c_cc[VTIME] = r->vtime;
|
154
|
+
}
|
155
|
+
#endif
|
156
|
+
}
|
157
|
+
|
158
|
+
static void
|
159
|
+
set_cookedmode(conmode *t, void *arg)
|
160
|
+
{
|
161
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
162
|
+
t->c_iflag |= (BRKINT|ISTRIP|ICRNL|IXON);
|
163
|
+
t->c_oflag |= OPOST;
|
164
|
+
t->c_lflag |= (ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN);
|
165
|
+
#elif defined HAVE_SGTTY_H
|
166
|
+
t->sg_flags |= ECHO;
|
167
|
+
t->sg_flags &= ~RAW;
|
168
|
+
#elif defined _WIN32
|
169
|
+
*t |= ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT;
|
170
|
+
#endif
|
171
|
+
}
|
172
|
+
|
173
|
+
static void
|
174
|
+
set_noecho(conmode *t, void *arg)
|
175
|
+
{
|
176
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
177
|
+
t->c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
178
|
+
#elif defined HAVE_SGTTY_H
|
179
|
+
t->sg_flags &= ~ECHO;
|
180
|
+
#elif defined _WIN32
|
181
|
+
*t &= ~ENABLE_ECHO_INPUT;
|
182
|
+
#endif
|
183
|
+
}
|
184
|
+
|
185
|
+
static void
|
186
|
+
set_echo(conmode *t, void *arg)
|
187
|
+
{
|
188
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
189
|
+
t->c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL);
|
190
|
+
#elif defined HAVE_SGTTY_H
|
191
|
+
t->sg_flags |= ECHO;
|
192
|
+
#elif defined _WIN32
|
193
|
+
*t |= ENABLE_ECHO_INPUT;
|
194
|
+
#endif
|
195
|
+
}
|
196
|
+
|
197
|
+
static int
|
198
|
+
echo_p(conmode *t)
|
199
|
+
{
|
200
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
201
|
+
return (t->c_lflag & (ECHO | ECHONL)) != 0;
|
202
|
+
#elif defined HAVE_SGTTY_H
|
203
|
+
return (t->sg_flags & ECHO) != 0;
|
204
|
+
#elif defined _WIN32
|
205
|
+
return (*t & ENABLE_ECHO_INPUT) != 0;
|
206
|
+
#endif
|
207
|
+
}
|
208
|
+
|
209
|
+
static int
|
210
|
+
set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg)
|
211
|
+
{
|
212
|
+
conmode r;
|
213
|
+
if (!getattr(fd, t)) return 0;
|
214
|
+
r = *t;
|
215
|
+
setter(&r, arg);
|
216
|
+
return setattr(fd, &r);
|
217
|
+
}
|
218
|
+
|
219
|
+
#define GetReadFD(fptr) ((fptr)->fd)
|
220
|
+
|
221
|
+
static inline int
|
222
|
+
get_write_fd(const rb_io_t *fptr)
|
223
|
+
{
|
224
|
+
VALUE wio = fptr->tied_io_for_writing;
|
225
|
+
rb_io_t *ofptr;
|
226
|
+
if (!wio) return fptr->fd;
|
227
|
+
GetOpenFile(wio, ofptr);
|
228
|
+
return ofptr->fd;
|
229
|
+
}
|
230
|
+
#define GetWriteFD(fptr) get_write_fd(fptr)
|
231
|
+
|
232
|
+
#define FD_PER_IO 2
|
233
|
+
|
234
|
+
static VALUE
|
235
|
+
ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void *arg)
|
236
|
+
{
|
237
|
+
rb_io_t *fptr;
|
238
|
+
int status = -1;
|
239
|
+
int error = 0;
|
240
|
+
int fd[FD_PER_IO];
|
241
|
+
conmode t[FD_PER_IO];
|
242
|
+
VALUE result = Qnil;
|
243
|
+
|
244
|
+
GetOpenFile(io, fptr);
|
245
|
+
fd[0] = GetReadFD(fptr);
|
246
|
+
if (fd[0] != -1) {
|
247
|
+
if (set_ttymode(fd[0], t+0, setter, arg)) {
|
248
|
+
status = 0;
|
249
|
+
}
|
250
|
+
else {
|
251
|
+
error = errno;
|
252
|
+
fd[0] = -1;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
fd[1] = GetWriteFD(fptr);
|
256
|
+
if (fd[1] != -1 && fd[1] != fd[0]) {
|
257
|
+
if (set_ttymode(fd[1], t+1, setter, arg)) {
|
258
|
+
status = 0;
|
259
|
+
}
|
260
|
+
else {
|
261
|
+
error = errno;
|
262
|
+
fd[1] = -1;
|
263
|
+
}
|
264
|
+
}
|
265
|
+
if (status == 0) {
|
266
|
+
result = rb_protect(func, io, &status);
|
267
|
+
}
|
268
|
+
GetOpenFile(io, fptr);
|
269
|
+
if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) {
|
270
|
+
if (!setattr(fd[0], t+0)) {
|
271
|
+
error = errno;
|
272
|
+
status = -1;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(fptr)) {
|
276
|
+
if (!setattr(fd[1], t+1)) {
|
277
|
+
error = errno;
|
278
|
+
status = -1;
|
279
|
+
}
|
280
|
+
}
|
281
|
+
if (status) {
|
282
|
+
if (status == -1) {
|
283
|
+
rb_syserr_fail(error, 0);
|
284
|
+
}
|
285
|
+
rb_jump_tag(status);
|
286
|
+
}
|
287
|
+
return result;
|
288
|
+
}
|
289
|
+
|
290
|
+
/*
|
291
|
+
* call-seq:
|
292
|
+
* io.raw(min: nil, time: nil) {|io| }
|
293
|
+
*
|
294
|
+
* Yields +self+ within raw mode.
|
295
|
+
*
|
296
|
+
* STDIN.raw(&:gets)
|
297
|
+
*
|
298
|
+
* will read and return a line without echo back and line editing.
|
299
|
+
*
|
300
|
+
* The parameter +min+ specifies the minimum number of bytes that
|
301
|
+
* should be received when a read operation is performed. (default: 1)
|
302
|
+
*
|
303
|
+
* The parameter +time+ specifies the timeout in _seconds_ with a
|
304
|
+
* precision of 1/10 of a second. (default: 0)
|
305
|
+
*
|
306
|
+
* Refer to the manual page of termios for further details.
|
307
|
+
*
|
308
|
+
* You must require 'io/console' to use this method.
|
309
|
+
*/
|
310
|
+
static VALUE
|
311
|
+
console_raw(int argc, VALUE *argv, VALUE io)
|
312
|
+
{
|
313
|
+
rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
|
314
|
+
return ttymode(io, rb_yield, set_rawmode, optp);
|
315
|
+
}
|
316
|
+
|
317
|
+
/*
|
318
|
+
* call-seq:
|
319
|
+
* io.raw!(min: nil, time: nil)
|
320
|
+
*
|
321
|
+
* Enables raw mode.
|
322
|
+
*
|
323
|
+
* If the terminal mode needs to be back, use io.raw { ... }.
|
324
|
+
*
|
325
|
+
* See IO#raw for details on the parameters.
|
326
|
+
*
|
327
|
+
* You must require 'io/console' to use this method.
|
328
|
+
*/
|
329
|
+
static VALUE
|
330
|
+
console_set_raw(int argc, VALUE *argv, VALUE io)
|
331
|
+
{
|
332
|
+
conmode t;
|
333
|
+
rb_io_t *fptr;
|
334
|
+
int fd;
|
335
|
+
rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
|
336
|
+
|
337
|
+
GetOpenFile(io, fptr);
|
338
|
+
fd = GetReadFD(fptr);
|
339
|
+
if (!getattr(fd, &t)) rb_sys_fail(0);
|
340
|
+
set_rawmode(&t, optp);
|
341
|
+
if (!setattr(fd, &t)) rb_sys_fail(0);
|
342
|
+
return io;
|
343
|
+
}
|
344
|
+
|
345
|
+
/*
|
346
|
+
* call-seq:
|
347
|
+
* io.cooked {|io| }
|
348
|
+
*
|
349
|
+
* Yields +self+ within cooked mode.
|
350
|
+
*
|
351
|
+
* STDIN.cooked(&:gets)
|
352
|
+
*
|
353
|
+
* will read and return a line with echo back and line editing.
|
354
|
+
*
|
355
|
+
* You must require 'io/console' to use this method.
|
356
|
+
*/
|
357
|
+
static VALUE
|
358
|
+
console_cooked(VALUE io)
|
359
|
+
{
|
360
|
+
return ttymode(io, rb_yield, set_cookedmode, NULL);
|
361
|
+
}
|
362
|
+
|
363
|
+
/*
|
364
|
+
* call-seq:
|
365
|
+
* io.cooked!
|
366
|
+
*
|
367
|
+
* Enables cooked mode.
|
368
|
+
*
|
369
|
+
* If the terminal mode needs to be back, use io.cooked { ... }.
|
370
|
+
*
|
371
|
+
* You must require 'io/console' to use this method.
|
372
|
+
*/
|
373
|
+
static VALUE
|
374
|
+
console_set_cooked(VALUE io)
|
375
|
+
{
|
376
|
+
conmode t;
|
377
|
+
rb_io_t *fptr;
|
378
|
+
int fd;
|
379
|
+
|
380
|
+
GetOpenFile(io, fptr);
|
381
|
+
fd = GetReadFD(fptr);
|
382
|
+
if (!getattr(fd, &t)) rb_sys_fail(0);
|
383
|
+
set_cookedmode(&t, NULL);
|
384
|
+
if (!setattr(fd, &t)) rb_sys_fail(0);
|
385
|
+
return io;
|
386
|
+
}
|
387
|
+
|
388
|
+
static VALUE
|
389
|
+
getc_call(VALUE io)
|
390
|
+
{
|
391
|
+
return rb_funcallv(io, id_getc, 0, 0);
|
392
|
+
}
|
393
|
+
|
394
|
+
/*
|
395
|
+
* call-seq:
|
396
|
+
* io.getch(min: nil, time: nil) -> char
|
397
|
+
*
|
398
|
+
* Reads and returns a character in raw mode.
|
399
|
+
*
|
400
|
+
* See IO#raw for details on the parameters.
|
401
|
+
*
|
402
|
+
* You must require 'io/console' to use this method.
|
403
|
+
*/
|
404
|
+
static VALUE
|
405
|
+
console_getch(int argc, VALUE *argv, VALUE io)
|
406
|
+
{
|
407
|
+
rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
|
408
|
+
return ttymode(io, getc_call, set_rawmode, optp);
|
409
|
+
}
|
410
|
+
|
411
|
+
/*
|
412
|
+
* call-seq:
|
413
|
+
* io.noecho {|io| }
|
414
|
+
*
|
415
|
+
* Yields +self+ with disabling echo back.
|
416
|
+
*
|
417
|
+
* STDIN.noecho(&:gets)
|
418
|
+
*
|
419
|
+
* will read and return a line without echo back.
|
420
|
+
*
|
421
|
+
* You must require 'io/console' to use this method.
|
422
|
+
*/
|
423
|
+
static VALUE
|
424
|
+
console_noecho(VALUE io)
|
425
|
+
{
|
426
|
+
return ttymode(io, rb_yield, set_noecho, NULL);
|
427
|
+
}
|
428
|
+
|
429
|
+
/*
|
430
|
+
* call-seq:
|
431
|
+
* io.echo = flag
|
432
|
+
*
|
433
|
+
* Enables/disables echo back.
|
434
|
+
* On some platforms, all combinations of this flags and raw/cooked
|
435
|
+
* mode may not be valid.
|
436
|
+
*
|
437
|
+
* You must require 'io/console' to use this method.
|
438
|
+
*/
|
439
|
+
static VALUE
|
440
|
+
console_set_echo(VALUE io, VALUE f)
|
441
|
+
{
|
442
|
+
conmode t;
|
443
|
+
rb_io_t *fptr;
|
444
|
+
int fd;
|
445
|
+
|
446
|
+
GetOpenFile(io, fptr);
|
447
|
+
fd = GetReadFD(fptr);
|
448
|
+
if (!getattr(fd, &t)) rb_sys_fail(0);
|
449
|
+
if (RTEST(f))
|
450
|
+
set_echo(&t, NULL);
|
451
|
+
else
|
452
|
+
set_noecho(&t, NULL);
|
453
|
+
if (!setattr(fd, &t)) rb_sys_fail(0);
|
454
|
+
return io;
|
455
|
+
}
|
456
|
+
|
457
|
+
/*
|
458
|
+
* call-seq:
|
459
|
+
* io.echo? -> true or false
|
460
|
+
*
|
461
|
+
* Returns +true+ if echo back is enabled.
|
462
|
+
*
|
463
|
+
* You must require 'io/console' to use this method.
|
464
|
+
*/
|
465
|
+
static VALUE
|
466
|
+
console_echo_p(VALUE io)
|
467
|
+
{
|
468
|
+
conmode t;
|
469
|
+
rb_io_t *fptr;
|
470
|
+
int fd;
|
471
|
+
|
472
|
+
GetOpenFile(io, fptr);
|
473
|
+
fd = GetReadFD(fptr);
|
474
|
+
if (!getattr(fd, &t)) rb_sys_fail(0);
|
475
|
+
return echo_p(&t) ? Qtrue : Qfalse;
|
476
|
+
}
|
477
|
+
|
478
|
+
#if defined TIOCGWINSZ
|
479
|
+
typedef struct winsize rb_console_size_t;
|
480
|
+
#define getwinsize(fd, buf) (ioctl((fd), TIOCGWINSZ, (buf)) == 0)
|
481
|
+
#define setwinsize(fd, buf) (ioctl((fd), TIOCSWINSZ, (buf)) == 0)
|
482
|
+
#define winsize_row(buf) (buf)->ws_row
|
483
|
+
#define winsize_col(buf) (buf)->ws_col
|
484
|
+
#elif defined _WIN32
|
485
|
+
typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t;
|
486
|
+
#define getwinsize(fd, buf) ( \
|
487
|
+
GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), (buf)) || \
|
488
|
+
SET_LAST_ERROR)
|
489
|
+
#define winsize_row(buf) ((buf)->srWindow.Bottom - (buf)->srWindow.Top + 1)
|
490
|
+
#define winsize_col(buf) (buf)->dwSize.X
|
491
|
+
#endif
|
492
|
+
|
493
|
+
#if defined TIOCGWINSZ || defined _WIN32
|
494
|
+
#define USE_CONSOLE_GETSIZE 1
|
495
|
+
#endif
|
496
|
+
|
497
|
+
#ifdef USE_CONSOLE_GETSIZE
|
498
|
+
/*
|
499
|
+
* call-seq:
|
500
|
+
* io.winsize -> [rows, columns]
|
501
|
+
*
|
502
|
+
* Returns console size.
|
503
|
+
*
|
504
|
+
* You must require 'io/console' to use this method.
|
505
|
+
*/
|
506
|
+
static VALUE
|
507
|
+
console_winsize(VALUE io)
|
508
|
+
{
|
509
|
+
rb_io_t *fptr;
|
510
|
+
int fd;
|
511
|
+
rb_console_size_t ws;
|
512
|
+
|
513
|
+
GetOpenFile(io, fptr);
|
514
|
+
fd = GetWriteFD(fptr);
|
515
|
+
if (!getwinsize(fd, &ws)) rb_sys_fail(0);
|
516
|
+
return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
|
517
|
+
}
|
518
|
+
|
519
|
+
/*
|
520
|
+
* call-seq:
|
521
|
+
* io.winsize = [rows, columns]
|
522
|
+
*
|
523
|
+
* Tries to set console size. The effect depends on the platform and
|
524
|
+
* the running environment.
|
525
|
+
*
|
526
|
+
* You must require 'io/console' to use this method.
|
527
|
+
*/
|
528
|
+
static VALUE
|
529
|
+
console_set_winsize(VALUE io, VALUE size)
|
530
|
+
{
|
531
|
+
rb_io_t *fptr;
|
532
|
+
rb_console_size_t ws;
|
533
|
+
#if defined _WIN32
|
534
|
+
HANDLE wh;
|
535
|
+
int newrow, newcol;
|
536
|
+
BOOL ret;
|
537
|
+
#endif
|
538
|
+
VALUE row, col, xpixel, ypixel;
|
539
|
+
const VALUE *sz;
|
540
|
+
int fd;
|
541
|
+
long sizelen;
|
542
|
+
|
543
|
+
GetOpenFile(io, fptr);
|
544
|
+
size = rb_Array(size);
|
545
|
+
if ((sizelen = RARRAY_LEN(size)) != 2 && sizelen != 4) {
|
546
|
+
rb_raise(rb_eArgError,
|
547
|
+
"wrong number of arguments (given %ld, expected 2 or 4)",
|
548
|
+
sizelen);
|
549
|
+
}
|
550
|
+
sz = RARRAY_CONST_PTR(size);
|
551
|
+
row = sz[0], col = sz[1], xpixel = ypixel = Qnil;
|
552
|
+
if (sizelen == 4) xpixel = sz[2], ypixel = sz[3];
|
553
|
+
fd = GetWriteFD(fptr);
|
554
|
+
#if defined TIOCSWINSZ
|
555
|
+
ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0;
|
556
|
+
#define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
|
557
|
+
SET(row);
|
558
|
+
SET(col);
|
559
|
+
SET(xpixel);
|
560
|
+
SET(ypixel);
|
561
|
+
#undef SET
|
562
|
+
if (!setwinsize(fd, &ws)) rb_sys_fail(0);
|
563
|
+
#elif defined _WIN32
|
564
|
+
wh = (HANDLE)rb_w32_get_osfhandle(fd);
|
565
|
+
#define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
|
566
|
+
SET(row);
|
567
|
+
SET(col);
|
568
|
+
#undef SET
|
569
|
+
if (!NIL_P(xpixel)) (void)NUM2UINT(xpixel);
|
570
|
+
if (!NIL_P(ypixel)) (void)NUM2UINT(ypixel);
|
571
|
+
if (!GetConsoleScreenBufferInfo(wh, &ws)) {
|
572
|
+
rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo");
|
573
|
+
}
|
574
|
+
ws.dwSize.X = newcol;
|
575
|
+
ret = SetConsoleScreenBufferSize(wh, ws.dwSize);
|
576
|
+
ws.srWindow.Left = 0;
|
577
|
+
ws.srWindow.Top = 0;
|
578
|
+
ws.srWindow.Right = newcol-1;
|
579
|
+
ws.srWindow.Bottom = newrow-1;
|
580
|
+
if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) {
|
581
|
+
rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo");
|
582
|
+
}
|
583
|
+
/* retry when shrinking buffer after shrunk window */
|
584
|
+
if (!ret && !SetConsoleScreenBufferSize(wh, ws.dwSize)) {
|
585
|
+
rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo");
|
586
|
+
}
|
587
|
+
/* remove scrollbar if possible */
|
588
|
+
if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) {
|
589
|
+
rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo");
|
590
|
+
}
|
591
|
+
#endif
|
592
|
+
return io;
|
593
|
+
}
|
594
|
+
#endif
|
595
|
+
|
596
|
+
/*
|
597
|
+
* call-seq:
|
598
|
+
* io.iflush
|
599
|
+
*
|
600
|
+
* Flushes input buffer in kernel.
|
601
|
+
*
|
602
|
+
* You must require 'io/console' to use this method.
|
603
|
+
*/
|
604
|
+
static VALUE
|
605
|
+
console_iflush(VALUE io)
|
606
|
+
{
|
607
|
+
rb_io_t *fptr;
|
608
|
+
int fd;
|
609
|
+
|
610
|
+
GetOpenFile(io, fptr);
|
611
|
+
fd = GetReadFD(fptr);
|
612
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
613
|
+
if (tcflush(fd, TCIFLUSH)) rb_sys_fail(0);
|
614
|
+
#endif
|
615
|
+
(void)fd;
|
616
|
+
return io;
|
617
|
+
}
|
618
|
+
|
619
|
+
/*
|
620
|
+
* call-seq:
|
621
|
+
* io.oflush
|
622
|
+
*
|
623
|
+
* Flushes output buffer in kernel.
|
624
|
+
*
|
625
|
+
* You must require 'io/console' to use this method.
|
626
|
+
*/
|
627
|
+
static VALUE
|
628
|
+
console_oflush(VALUE io)
|
629
|
+
{
|
630
|
+
rb_io_t *fptr;
|
631
|
+
int fd;
|
632
|
+
|
633
|
+
GetOpenFile(io, fptr);
|
634
|
+
fd = GetWriteFD(fptr);
|
635
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
636
|
+
if (tcflush(fd, TCOFLUSH)) rb_sys_fail(0);
|
637
|
+
#endif
|
638
|
+
(void)fd;
|
639
|
+
return io;
|
640
|
+
}
|
641
|
+
|
642
|
+
/*
|
643
|
+
* call-seq:
|
644
|
+
* io.ioflush
|
645
|
+
*
|
646
|
+
* Flushes input and output buffers in kernel.
|
647
|
+
*
|
648
|
+
* You must require 'io/console' to use this method.
|
649
|
+
*/
|
650
|
+
static VALUE
|
651
|
+
console_ioflush(VALUE io)
|
652
|
+
{
|
653
|
+
rb_io_t *fptr;
|
654
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
655
|
+
int fd1, fd2;
|
656
|
+
#endif
|
657
|
+
|
658
|
+
GetOpenFile(io, fptr);
|
659
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
660
|
+
fd1 = GetReadFD(fptr);
|
661
|
+
fd2 = GetWriteFD(fptr);
|
662
|
+
if (fd2 != -1 && fd1 != fd2) {
|
663
|
+
if (tcflush(fd1, TCIFLUSH)) rb_sys_fail(0);
|
664
|
+
if (tcflush(fd2, TCOFLUSH)) rb_sys_fail(0);
|
665
|
+
}
|
666
|
+
else {
|
667
|
+
if (tcflush(fd1, TCIOFLUSH)) rb_sys_fail(0);
|
668
|
+
}
|
669
|
+
#endif
|
670
|
+
return io;
|
671
|
+
}
|
672
|
+
|
673
|
+
static VALUE
|
674
|
+
console_beep(VALUE io)
|
675
|
+
{
|
676
|
+
rb_io_t *fptr;
|
677
|
+
int fd;
|
678
|
+
|
679
|
+
GetOpenFile(io, fptr);
|
680
|
+
fd = GetWriteFD(fptr);
|
681
|
+
#ifdef _WIN32
|
682
|
+
(void)fd;
|
683
|
+
MessageBeep(0);
|
684
|
+
#else
|
685
|
+
if (write(fd, "\a", 1) < 0)
|
686
|
+
rb_sys_fail(0);
|
687
|
+
#endif
|
688
|
+
return io;
|
689
|
+
}
|
690
|
+
|
691
|
+
#if defined _WIN32
|
692
|
+
static VALUE
|
693
|
+
console_goto(VALUE io, VALUE x, VALUE y)
|
694
|
+
{
|
695
|
+
rb_io_t *fptr;
|
696
|
+
int fd;
|
697
|
+
COORD pos;
|
698
|
+
|
699
|
+
GetOpenFile(io, fptr);
|
700
|
+
fd = GetWriteFD(fptr);
|
701
|
+
pos.X = NUM2UINT(x);
|
702
|
+
pos.Y = NUM2UINT(y);
|
703
|
+
if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
|
704
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
705
|
+
}
|
706
|
+
return io;
|
707
|
+
}
|
708
|
+
|
709
|
+
static VALUE
|
710
|
+
console_cursor_pos(VALUE io)
|
711
|
+
{
|
712
|
+
rb_io_t *fptr;
|
713
|
+
int fd;
|
714
|
+
rb_console_size_t ws;
|
715
|
+
|
716
|
+
GetOpenFile(io, fptr);
|
717
|
+
fd = GetWriteFD(fptr);
|
718
|
+
if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
|
719
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
720
|
+
}
|
721
|
+
return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.X), UINT2NUM(ws.dwCursorPosition.Y));
|
722
|
+
}
|
723
|
+
|
724
|
+
static VALUE
|
725
|
+
console_cursor_set(VALUE io, VALUE cpos)
|
726
|
+
{
|
727
|
+
cpos = rb_convert_type(cpos, T_ARRAY, "Array", "to_ary");
|
728
|
+
if (RARRAY_LEN(cpos) != 2) rb_raise(rb_eArgError, "expected 2D coordinate");
|
729
|
+
return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1));
|
730
|
+
}
|
731
|
+
|
732
|
+
#include "win32_vk.inc"
|
733
|
+
|
734
|
+
static VALUE
|
735
|
+
console_key_pressed_p(VALUE io, VALUE k)
|
736
|
+
{
|
737
|
+
int vk = -1;
|
738
|
+
|
739
|
+
if (FIXNUM_P(k)) {
|
740
|
+
vk = NUM2UINT(k);
|
741
|
+
}
|
742
|
+
else {
|
743
|
+
const struct vktable *t;
|
744
|
+
const char *kn;
|
745
|
+
if (SYMBOL_P(k)) {
|
746
|
+
k = rb_sym2str(k);
|
747
|
+
kn = RSTRING_PTR(k);
|
748
|
+
}
|
749
|
+
else {
|
750
|
+
kn = StringValuePtr(k);
|
751
|
+
}
|
752
|
+
t = console_win32_vk(kn, RSTRING_LEN(k));
|
753
|
+
if (!t || (vk = (short)t->vk) == -1) {
|
754
|
+
rb_raise(rb_eArgError, "unknown virtual key code: % "PRIsVALUE, k);
|
755
|
+
}
|
756
|
+
}
|
757
|
+
return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse;
|
758
|
+
}
|
759
|
+
#else
|
760
|
+
# define console_goto rb_f_notimplement
|
761
|
+
# define console_cursor_pos rb_f_notimplement
|
762
|
+
# define console_cursor_set rb_f_notimplement
|
763
|
+
# define console_key_pressed_p rb_f_notimplement
|
764
|
+
#endif
|
765
|
+
|
766
|
+
/*
|
767
|
+
* call-seq:
|
768
|
+
* IO.console -> #<File:/dev/tty>
|
769
|
+
* IO.console(sym, *args)
|
770
|
+
*
|
771
|
+
* Returns an File instance opened console.
|
772
|
+
*
|
773
|
+
* If +sym+ is given, it will be sent to the opened console with
|
774
|
+
* +args+ and the result will be returned instead of the console IO
|
775
|
+
* itself.
|
776
|
+
*
|
777
|
+
* You must require 'io/console' to use this method.
|
778
|
+
*/
|
779
|
+
static VALUE
|
780
|
+
console_dev(int argc, VALUE *argv, VALUE klass)
|
781
|
+
{
|
782
|
+
VALUE con = 0;
|
783
|
+
rb_io_t *fptr;
|
784
|
+
VALUE sym = 0;
|
785
|
+
|
786
|
+
rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS);
|
787
|
+
if (argc) {
|
788
|
+
Check_Type(sym = argv[0], T_SYMBOL);
|
789
|
+
}
|
790
|
+
if (klass == rb_cIO) klass = rb_cFile;
|
791
|
+
if (rb_const_defined(klass, id_console)) {
|
792
|
+
con = rb_const_get(klass, id_console);
|
793
|
+
if (!RB_TYPE_P(con, T_FILE) ||
|
794
|
+
(!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) {
|
795
|
+
rb_const_remove(klass, id_console);
|
796
|
+
con = 0;
|
797
|
+
}
|
798
|
+
}
|
799
|
+
if (sym) {
|
800
|
+
if (sym == ID2SYM(id_close) && argc == 1) {
|
801
|
+
if (con) {
|
802
|
+
rb_io_close(con);
|
803
|
+
rb_const_remove(klass, id_console);
|
804
|
+
con = 0;
|
805
|
+
}
|
806
|
+
return Qnil;
|
807
|
+
}
|
808
|
+
}
|
809
|
+
if (!con) {
|
810
|
+
VALUE args[2];
|
811
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
|
812
|
+
# define CONSOLE_DEVICE "/dev/tty"
|
813
|
+
#elif defined _WIN32
|
814
|
+
# define CONSOLE_DEVICE "con$"
|
815
|
+
# define CONSOLE_DEVICE_FOR_READING "conin$"
|
816
|
+
# define CONSOLE_DEVICE_FOR_WRITING "conout$"
|
817
|
+
#endif
|
818
|
+
#ifndef CONSOLE_DEVICE_FOR_READING
|
819
|
+
# define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE
|
820
|
+
#endif
|
821
|
+
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
822
|
+
VALUE out;
|
823
|
+
rb_io_t *ofptr;
|
824
|
+
#endif
|
825
|
+
int fd;
|
826
|
+
|
827
|
+
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
828
|
+
fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
|
829
|
+
if (fd < 0) return Qnil;
|
830
|
+
rb_update_max_fd(fd);
|
831
|
+
args[1] = INT2FIX(O_WRONLY);
|
832
|
+
args[0] = INT2NUM(fd);
|
833
|
+
out = rb_class_new_instance(2, args, klass);
|
834
|
+
#endif
|
835
|
+
fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
|
836
|
+
if (fd < 0) {
|
837
|
+
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
838
|
+
rb_io_close(out);
|
839
|
+
#endif
|
840
|
+
return Qnil;
|
841
|
+
}
|
842
|
+
rb_update_max_fd(fd);
|
843
|
+
args[1] = INT2FIX(O_RDWR);
|
844
|
+
args[0] = INT2NUM(fd);
|
845
|
+
con = rb_class_new_instance(2, args, klass);
|
846
|
+
GetOpenFile(con, fptr);
|
847
|
+
fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
|
848
|
+
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
849
|
+
GetOpenFile(out, ofptr);
|
850
|
+
ofptr->pathv = fptr->pathv;
|
851
|
+
fptr->tied_io_for_writing = out;
|
852
|
+
ofptr->mode |= FMODE_SYNC;
|
853
|
+
#endif
|
854
|
+
fptr->mode |= FMODE_SYNC;
|
855
|
+
rb_const_set(klass, id_console, con);
|
856
|
+
}
|
857
|
+
if (sym) {
|
858
|
+
return rb_f_send(argc, argv, con);
|
859
|
+
}
|
860
|
+
return con;
|
861
|
+
}
|
862
|
+
|
863
|
+
/*
|
864
|
+
* call-seq:
|
865
|
+
* io.getch(min: nil, time: nil) -> char
|
866
|
+
*
|
867
|
+
* See IO#getch.
|
868
|
+
*/
|
869
|
+
static VALUE
|
870
|
+
io_getch(int argc, VALUE *argv, VALUE io)
|
871
|
+
{
|
872
|
+
return rb_funcallv(io, id_getc, argc, argv);
|
873
|
+
}
|
874
|
+
|
875
|
+
#if ENABLE_IO_GETPASS
|
876
|
+
static VALUE
|
877
|
+
puts_call(VALUE io)
|
878
|
+
{
|
879
|
+
return rb_io_write(io, rb_default_rs);
|
880
|
+
}
|
881
|
+
|
882
|
+
static VALUE
|
883
|
+
getpass_call(VALUE io)
|
884
|
+
{
|
885
|
+
return ttymode(io, rb_io_gets, set_noecho, NULL);
|
886
|
+
}
|
887
|
+
|
888
|
+
static void
|
889
|
+
prompt(int argc, VALUE *argv, VALUE io)
|
890
|
+
{
|
891
|
+
if (argc > 0 && !NIL_P(argv[0])) {
|
892
|
+
VALUE str = argv[0];
|
893
|
+
StringValueCStr(str);
|
894
|
+
rb_check_safe_obj(str);
|
895
|
+
rb_io_write(io, str);
|
896
|
+
}
|
897
|
+
}
|
898
|
+
|
899
|
+
static VALUE
|
900
|
+
str_chomp(VALUE str)
|
901
|
+
{
|
902
|
+
if (!NIL_P(str)) {
|
903
|
+
str = rb_funcallv(str, rb_intern("chomp!"), 0, 0);
|
904
|
+
}
|
905
|
+
return str;
|
906
|
+
}
|
907
|
+
|
908
|
+
/*
|
909
|
+
* call-seq:
|
910
|
+
* io.getpass(prompt=nil) -> string
|
911
|
+
*
|
912
|
+
* Reads and returns a line without echo back.
|
913
|
+
* Prints +prompt+ unless it is +nil+.
|
914
|
+
*
|
915
|
+
* You must require 'io/console' to use this method.
|
916
|
+
*/
|
917
|
+
static VALUE
|
918
|
+
console_getpass(int argc, VALUE *argv, VALUE io)
|
919
|
+
{
|
920
|
+
VALUE str, wio;
|
921
|
+
|
922
|
+
rb_check_arity(argc, 0, 1);
|
923
|
+
wio = rb_io_get_write_io(io);
|
924
|
+
if (wio == io && io == rb_stdin) wio = rb_stderr;
|
925
|
+
prompt(argc, argv, wio);
|
926
|
+
str = rb_ensure(getpass_call, io, puts_call, wio);
|
927
|
+
return str_chomp(str);
|
928
|
+
}
|
929
|
+
|
930
|
+
/*
|
931
|
+
* call-seq:
|
932
|
+
* io.getpass(prompt=nil) -> string
|
933
|
+
*
|
934
|
+
* See IO#getpass.
|
935
|
+
*/
|
936
|
+
static VALUE
|
937
|
+
io_getpass(int argc, VALUE *argv, VALUE io)
|
938
|
+
{
|
939
|
+
VALUE str;
|
940
|
+
|
941
|
+
rb_check_arity(argc, 0, 1);
|
942
|
+
prompt(argc, argv, io);
|
943
|
+
str = str_chomp(rb_funcallv(io, id_gets, 0, 0));
|
944
|
+
puts_call(io);
|
945
|
+
return str;
|
946
|
+
}
|
947
|
+
#endif
|
948
|
+
|
949
|
+
/*
|
950
|
+
* IO console methods
|
951
|
+
*/
|
952
|
+
void
|
953
|
+
Init_console(void)
|
954
|
+
{
|
955
|
+
#undef rb_intern
|
956
|
+
id_getc = rb_intern("getc");
|
957
|
+
#if ENABLE_IO_GETPASS
|
958
|
+
id_gets = rb_intern("gets");
|
959
|
+
#endif
|
960
|
+
id_console = rb_intern("console");
|
961
|
+
id_close = rb_intern("close");
|
962
|
+
id_min = rb_intern("min");
|
963
|
+
id_time = rb_intern("time");
|
964
|
+
#ifndef HAVE_RB_F_SEND
|
965
|
+
id___send__ = rb_intern("__send__");
|
966
|
+
#endif
|
967
|
+
InitVM(console);
|
968
|
+
}
|
969
|
+
|
970
|
+
void
|
971
|
+
InitVM_console(void)
|
972
|
+
{
|
973
|
+
rb_define_method(rb_cIO, "raw", console_raw, -1);
|
974
|
+
rb_define_method(rb_cIO, "raw!", console_set_raw, -1);
|
975
|
+
rb_define_method(rb_cIO, "cooked", console_cooked, 0);
|
976
|
+
rb_define_method(rb_cIO, "cooked!", console_set_cooked, 0);
|
977
|
+
rb_define_method(rb_cIO, "getch", console_getch, -1);
|
978
|
+
rb_define_method(rb_cIO, "echo=", console_set_echo, 1);
|
979
|
+
rb_define_method(rb_cIO, "echo?", console_echo_p, 0);
|
980
|
+
rb_define_method(rb_cIO, "noecho", console_noecho, 0);
|
981
|
+
rb_define_method(rb_cIO, "winsize", console_winsize, 0);
|
982
|
+
rb_define_method(rb_cIO, "winsize=", console_set_winsize, 1);
|
983
|
+
rb_define_method(rb_cIO, "iflush", console_iflush, 0);
|
984
|
+
rb_define_method(rb_cIO, "oflush", console_oflush, 0);
|
985
|
+
rb_define_method(rb_cIO, "ioflush", console_ioflush, 0);
|
986
|
+
rb_define_method(rb_cIO, "beep", console_beep, 0);
|
987
|
+
rb_define_method(rb_cIO, "goto", console_goto, 2);
|
988
|
+
rb_define_method(rb_cIO, "cursor", console_cursor_pos, 0);
|
989
|
+
rb_define_method(rb_cIO, "cursor=", console_cursor_set, 1);
|
990
|
+
rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1);
|
991
|
+
#if ENABLE_IO_GETPASS
|
992
|
+
rb_define_method(rb_cIO, "getpass", console_getpass, -1);
|
993
|
+
#endif
|
994
|
+
rb_define_singleton_method(rb_cIO, "console", console_dev, -1);
|
995
|
+
{
|
996
|
+
VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
|
997
|
+
rb_define_method(mReadable, "getch", io_getch, -1);
|
998
|
+
#if ENABLE_IO_GETPASS
|
999
|
+
rb_define_method(mReadable, "getpass", io_getpass, -1);
|
1000
|
+
#endif
|
1001
|
+
}
|
1002
|
+
}
|