io-console 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/console.c +628 -0
  2. data/extconf.rb +20 -0
  3. data/lib/console/size.rb +20 -0
  4. metadata +48 -0
data/console.c ADDED
@@ -0,0 +1,628 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /*
3
+ * console IO module
4
+ */
5
+ #include "ruby.h"
6
+ #ifdef HAVE_RUBY_IO_H
7
+ #include "ruby/io.h"
8
+ #else
9
+ #include "rubyio.h"
10
+ #endif
11
+
12
+ #ifndef HAVE_RB_IO_T
13
+ typedef OpenFile rb_io_t;
14
+ #endif
15
+
16
+ #ifdef HAVE_UNISTD_H
17
+ #include <unistd.h>
18
+ #endif
19
+ #ifdef HAVE_FCNTL_H
20
+ #include <fcntl.h>
21
+ #endif
22
+ #ifdef HAVE_SYS_IOCTL_H
23
+ #include <sys/ioctl.h>
24
+ #endif
25
+
26
+ #if defined HAVE_TERMIOS_H
27
+ # include <termios.h>
28
+ typedef struct termios conmode;
29
+
30
+ static int
31
+ setattr(int fd, conmode *t)
32
+ {
33
+ while (tcsetattr(fd, TCSAFLUSH, t)) {
34
+ if (errno != EINTR) return 0;
35
+ }
36
+ return 1;
37
+ }
38
+ # define getattr(fd, t) (tcgetattr(fd, t) == 0)
39
+ #elif defined HAVE_TERMIO_H
40
+ # include <termio.h>
41
+ typedef struct termio conmode;
42
+ # define setattr(fd, t) (ioctl(fd, TCSETAF, t) == 0)
43
+ # define getattr(fd, t) (ioctl(fd, TCGETA, t) == 0)
44
+ #elif defined HAVE_SGTTY_H
45
+ # include <sgtty.h>
46
+ typedef struct sgttyb conmode;
47
+ # ifdef HAVE_STTY
48
+ # define setattr(fd, t) (stty(fd, t) == 0)
49
+ # else
50
+ # define setattr(fd, t) (ioctl((fd), TIOCSETP, (t)) == 0)
51
+ # endif
52
+ # ifdef HAVE_GTTY
53
+ # define getattr(fd, t) (gtty(fd, t) == 0)
54
+ # else
55
+ # define getattr(fd, t) (ioctl((fd), TIOCGETP, (t)) == 0)
56
+ # endif
57
+ #elif defined _WIN32
58
+ #include <winioctl.h>
59
+ typedef DWORD conmode;
60
+
61
+ #ifdef HAVE_RB_W32_MAP_ERRNO
62
+ #define LAST_ERROR rb_w32_map_errno(GetLastError())
63
+ #else
64
+ #define LAST_ERROR EBADF
65
+ #endif
66
+ #define SET_LAST_ERROR (errno = LAST_ERROR, 0)
67
+
68
+ static int
69
+ setattr(int fd, conmode *t)
70
+ {
71
+ int x = SetConsoleMode((HANDLE)rb_w32_get_osfhandle(fd), *t);
72
+ if (!x) errno = LAST_ERROR;
73
+ return x;
74
+ }
75
+
76
+ static int
77
+ getattr(int fd, conmode *t)
78
+ {
79
+ int x = GetConsoleMode((HANDLE)rb_w32_get_osfhandle(fd), t);
80
+ if (!x) errno = LAST_ERROR;
81
+ return x;
82
+ }
83
+ #endif
84
+ #ifndef SET_LAST_ERROR
85
+ #define SET_LAST_ERROR (0)
86
+ #endif
87
+
88
+ #ifndef InitVM
89
+ #define InitVM(ext) {void InitVM_##ext(void);InitVM_##ext();}
90
+ #endif
91
+
92
+ static ID id_getc, id_console;
93
+
94
+ static void
95
+ set_rawmode(conmode *t)
96
+ {
97
+ #ifdef HAVE_CFMAKERAW
98
+ cfmakeraw(t);
99
+ #else
100
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
101
+ t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
102
+ t->c_oflag &= ~OPOST;
103
+ t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
104
+ t->c_cflag &= ~(CSIZE|PARENB);
105
+ t->c_cflag |= CS8;
106
+ #elif defined HAVE_SGTTY_H
107
+ t->sg_flags &= ~ECHO;
108
+ t->sg_flags |= RAW;
109
+ #elif defined _WIN32
110
+ *t = 0;
111
+ #endif
112
+ #endif
113
+ }
114
+
115
+ static void
116
+ set_noecho(conmode *t)
117
+ {
118
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
119
+ t->c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
120
+ #elif defined HAVE_SGTTY_H
121
+ t->sg_flags &= ~ECHO;
122
+ #elif defined _WIN32
123
+ *t &= ~ENABLE_ECHO_INPUT;
124
+ #endif
125
+ }
126
+
127
+ static void
128
+ set_echo(conmode *t)
129
+ {
130
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
131
+ t->c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL);
132
+ #elif defined HAVE_SGTTY_H
133
+ t->sg_flags |= ECHO;
134
+ #elif defined _WIN32
135
+ *t |= ENABLE_ECHO_INPUT;
136
+ #endif
137
+ }
138
+
139
+ static int
140
+ echo_p(conmode *t)
141
+ {
142
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
143
+ return (t->c_lflag & (ECHO | ECHOE | ECHOK | ECHONL)) != 0;
144
+ #elif defined HAVE_SGTTY_H
145
+ return (t->sg_flags & ECHO) != 0;
146
+ #elif defined _WIN32
147
+ return (*t & ENABLE_ECHO_INPUT) != 0;
148
+ #endif
149
+ }
150
+
151
+ static int
152
+ set_ttymode(int fd, conmode *t, void (*setter)(conmode *))
153
+ {
154
+ conmode r;
155
+ if (!getattr(fd, t)) return 0;
156
+ r = *t;
157
+ setter(&r);
158
+ return setattr(fd, &r);
159
+ }
160
+
161
+ #ifdef GetReadFile
162
+ #define GetReadFD(fptr) fileno(GetReadFile(fptr))
163
+ #else
164
+ #define GetReadFD(fptr) ((fptr)->fd)
165
+ #endif
166
+
167
+ #ifdef GetWriteFile
168
+ #define GetWriteFD(fptr) fileno(GetWriteFile(fptr))
169
+ #else
170
+ static inline int
171
+ get_write_fd(const rb_io_t *fptr)
172
+ {
173
+ VALUE wio = fptr->tied_io_for_writing;
174
+ rb_io_t *ofptr;
175
+ if (!wio) return fptr->fd;
176
+ GetOpenFile(wio, ofptr);
177
+ return ofptr->fd;
178
+ }
179
+ #define GetWriteFD(fptr) get_write_fd(fptr)
180
+ #endif
181
+
182
+ #define FD_PER_IO 2
183
+
184
+ static VALUE
185
+ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *))
186
+ {
187
+ rb_io_t *fptr;
188
+ int status = -1;
189
+ int error = 0;
190
+ int fd[FD_PER_IO];
191
+ conmode t[FD_PER_IO];
192
+ VALUE result = Qnil;
193
+
194
+ GetOpenFile(io, fptr);
195
+ fd[0] = GetReadFD(fptr);
196
+ if (fd[0] != -1) {
197
+ if (set_ttymode(fd[0], t+0, setter)) {
198
+ status = 0;
199
+ }
200
+ else {
201
+ error = errno;
202
+ fd[0] = -1;
203
+ }
204
+ }
205
+ fd[1] = GetWriteFD(fptr);
206
+ if (fd[1] != -1 && fd[1] != fd[0]) {
207
+ if (set_ttymode(fd[1], t+1, setter)) {
208
+ status = 0;
209
+ }
210
+ else {
211
+ error = errno;
212
+ fd[1] = -1;
213
+ }
214
+ }
215
+ if (status == 0) {
216
+ result = rb_protect(func, io, &status);
217
+ }
218
+ GetOpenFile(io, fptr);
219
+ if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) {
220
+ if (!setattr(fd[0], t+0)) {
221
+ error = errno;
222
+ status = -1;
223
+ }
224
+ }
225
+ if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(fptr)) {
226
+ if (!setattr(fd[1], t+1)) {
227
+ error = errno;
228
+ status = -1;
229
+ }
230
+ }
231
+ if (status) {
232
+ if (status == -1) {
233
+ errno = error;
234
+ rb_sys_fail(0);
235
+ }
236
+ rb_jump_tag(status);
237
+ }
238
+ return result;
239
+ }
240
+
241
+ /*
242
+ * call-seq:
243
+ * io.raw {|io| }
244
+ *
245
+ * Yields +self+ within raw mode.
246
+ *
247
+ * STDIN.raw(&:gets)
248
+ *
249
+ * will read and return a line with echo back and line editing.
250
+ */
251
+ static VALUE
252
+ console_raw(VALUE io)
253
+ {
254
+ return ttymode(io, rb_yield, set_rawmode);
255
+ }
256
+
257
+ /*
258
+ * call-seq:
259
+ * io.raw!
260
+ *
261
+ * Enables raw mode.
262
+ *
263
+ * If the terminal mode needs to be back, use io.raw { ... }.
264
+ */
265
+ static VALUE
266
+ console_set_raw(VALUE io)
267
+ {
268
+ conmode t;
269
+ rb_io_t *fptr;
270
+ int fd;
271
+
272
+ GetOpenFile(io, fptr);
273
+ fd = GetReadFD(fptr);
274
+ if (!getattr(fd, &t)) rb_sys_fail(0);
275
+ set_rawmode(&t);
276
+ if (!setattr(fd, &t)) rb_sys_fail(0);
277
+ return io;
278
+ }
279
+
280
+ static VALUE
281
+ getc_call(VALUE io)
282
+ {
283
+ return rb_funcall2(io, id_getc, 0, 0);
284
+ }
285
+
286
+ /*
287
+ * call-seq:
288
+ * io.getch -> char
289
+ *
290
+ * Reads and returns a character in raw mode.
291
+ */
292
+ static VALUE
293
+ console_getch(VALUE io)
294
+ {
295
+ return ttymode(io, getc_call, set_rawmode);
296
+ }
297
+
298
+ /*
299
+ * call-seq:
300
+ * io.noecho {|io| }
301
+ *
302
+ * Yields +self+ with disabling echo back.
303
+ *
304
+ * STDIN.noecho(&:gets)
305
+ *
306
+ * will read and return a line without echo back.
307
+ */
308
+ static VALUE
309
+ console_noecho(VALUE io)
310
+ {
311
+ return ttymode(io, rb_yield, set_noecho);
312
+ }
313
+
314
+ /*
315
+ * call-seq:
316
+ * io.echo = flag
317
+ *
318
+ * Enables/disables echo back.
319
+ */
320
+ static VALUE
321
+ console_set_echo(VALUE io, VALUE f)
322
+ {
323
+ conmode t;
324
+ rb_io_t *fptr;
325
+ int fd;
326
+
327
+ GetOpenFile(io, fptr);
328
+ fd = GetReadFD(fptr);
329
+ if (!getattr(fd, &t)) rb_sys_fail(0);
330
+ if (RTEST(f))
331
+ set_echo(&t);
332
+ else
333
+ set_noecho(&t);
334
+ if (!setattr(fd, &t)) rb_sys_fail(0);
335
+ return io;
336
+ }
337
+
338
+ /*
339
+ * call-seq:
340
+ * io.echo? -> true or false
341
+ *
342
+ * Returns +true+ if echo back is enabled.
343
+ */
344
+ static VALUE
345
+ console_echo_p(VALUE io)
346
+ {
347
+ conmode t;
348
+ rb_io_t *fptr;
349
+ int fd;
350
+
351
+ GetOpenFile(io, fptr);
352
+ fd = GetReadFD(fptr);
353
+ if (!getattr(fd, &t)) rb_sys_fail(0);
354
+ return echo_p(&t) ? Qtrue : Qfalse;
355
+ }
356
+
357
+ #if defined TIOCGWINSZ
358
+ typedef struct winsize rb_console_size_t;
359
+ #define getwinsize(fd, buf) (ioctl((fd), TIOCGWINSZ, (buf)) == 0)
360
+ #define setwinsize(fd, buf) (ioctl((fd), TIOCSWINSZ, (buf)) == 0)
361
+ #define winsize_row(buf) (buf)->ws_row
362
+ #define winsize_col(buf) (buf)->ws_col
363
+ #elif defined _WIN32
364
+ typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t;
365
+ #define getwinsize(fd, buf) ( \
366
+ GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), (buf)) || \
367
+ SET_LAST_ERROR)
368
+ #define winsize_row(buf) ((buf)->srWindow.Bottom - (buf)->srWindow.Top + 1)
369
+ #define winsize_col(buf) (buf)->dwSize.X
370
+ #endif
371
+
372
+ #if defined TIOCGWINSZ || defined _WIN32
373
+ #define USE_CONSOLE_GETSIZE 1
374
+ #endif
375
+
376
+ #ifdef USE_CONSOLE_GETSIZE
377
+ /*
378
+ * call-seq:
379
+ * io.winsize -> [rows, columns]
380
+ *
381
+ * Returns console size.
382
+ */
383
+ static VALUE
384
+ console_winsize(VALUE io)
385
+ {
386
+ rb_io_t *fptr;
387
+ int fd;
388
+ rb_console_size_t ws;
389
+
390
+ GetOpenFile(io, fptr);
391
+ fd = GetWriteFD(fptr);
392
+ if (!getwinsize(fd, &ws)) rb_sys_fail(0);
393
+ return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
394
+ }
395
+
396
+ /*
397
+ * call-seq:
398
+ * io.winsize = [rows, columns]
399
+ *
400
+ * Tries to set console size. The effect depends on the platform and
401
+ * the running environment.
402
+ */
403
+ static VALUE
404
+ console_set_winsize(VALUE io, VALUE size)
405
+ {
406
+ rb_io_t *fptr;
407
+ rb_console_size_t ws;
408
+ #if defined _WIN32
409
+ HANDLE wh;
410
+ int newrow, newcol;
411
+ #endif
412
+ VALUE row, col, xpixel, ypixel;
413
+ #if defined TIOCSWINSZ
414
+ int fd;
415
+ #endif
416
+
417
+ GetOpenFile(io, fptr);
418
+ size = rb_Array(size);
419
+ rb_scan_args((int)RARRAY_LEN(size), RARRAY_PTR(size), "22",
420
+ &row, &col, &xpixel, &ypixel);
421
+ #if defined TIOCSWINSZ
422
+ fd = GetWriteFD(fptr);
423
+ ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0;
424
+ #define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
425
+ SET(row);
426
+ SET(col);
427
+ SET(xpixel);
428
+ SET(ypixel);
429
+ #undef SET
430
+ if (!setwinsize(fd, &ws)) rb_sys_fail(0);
431
+ #elif defined _WIN32
432
+ wh = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr));
433
+ newrow = (SHORT)NUM2UINT(row);
434
+ newcol = (SHORT)NUM2UINT(col);
435
+ if (!getwinsize(GetReadFD(fptr), &ws)) {
436
+ rb_sys_fail("GetConsoleScreenBufferInfo");
437
+ }
438
+ if ((ws.dwSize.X < newcol && (ws.dwSize.X = newcol, 1)) ||
439
+ (ws.dwSize.Y < newrow && (ws.dwSize.Y = newrow, 1))) {
440
+ if (!(SetConsoleScreenBufferSize(wh, ws.dwSize) || SET_LAST_ERROR)) {
441
+ rb_sys_fail("SetConsoleScreenBufferInfo");
442
+ }
443
+ }
444
+ ws.srWindow.Left = 0;
445
+ ws.srWindow.Top = 0;
446
+ ws.srWindow.Right = newcol;
447
+ ws.srWindow.Bottom = newrow;
448
+ if (!(SetConsoleWindowInfo(wh, FALSE, &ws.srWindow) || SET_LAST_ERROR)) {
449
+ rb_sys_fail("SetConsoleWindowInfo");
450
+ }
451
+ #endif
452
+ return io;
453
+ }
454
+ #endif
455
+
456
+ /*
457
+ * call-seq:
458
+ * io.iflush
459
+ *
460
+ * Flushes input buffer in kernel.
461
+ */
462
+ static VALUE
463
+ console_iflush(VALUE io)
464
+ {
465
+ rb_io_t *fptr;
466
+ int fd;
467
+
468
+ GetOpenFile(io, fptr);
469
+ fd = GetReadFD(fptr);
470
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
471
+ if (tcflush(fd, TCIFLUSH)) rb_sys_fail(0);
472
+ #endif
473
+ return io;
474
+ }
475
+
476
+ /*
477
+ * call-seq:
478
+ * io.oflush
479
+ *
480
+ * Flushes output buffer in kernel.
481
+ */
482
+ static VALUE
483
+ console_oflush(VALUE io)
484
+ {
485
+ rb_io_t *fptr;
486
+ int fd;
487
+
488
+ GetOpenFile(io, fptr);
489
+ fd = GetWriteFD(fptr);
490
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
491
+ if (tcflush(fd, TCOFLUSH)) rb_sys_fail(0);
492
+ #endif
493
+ return io;
494
+ }
495
+
496
+ /*
497
+ * call-seq:
498
+ * io.ioflush
499
+ *
500
+ * Flushes input and output buffers in kernel.
501
+ */
502
+ static VALUE
503
+ console_ioflush(VALUE io)
504
+ {
505
+ rb_io_t *fptr;
506
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
507
+ int fd1, fd2;
508
+ #endif
509
+
510
+ GetOpenFile(io, fptr);
511
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
512
+ fd1 = GetReadFD(fptr);
513
+ fd2 = GetWriteFD(fptr);
514
+ if (fd2 != -1 && fd1 != fd2) {
515
+ if (tcflush(fd1, TCIFLUSH)) rb_sys_fail(0);
516
+ if (tcflush(fd2, TCOFLUSH)) rb_sys_fail(0);
517
+ }
518
+ else {
519
+ if (tcflush(fd1, TCIOFLUSH)) rb_sys_fail(0);
520
+ }
521
+ #endif
522
+ return io;
523
+ }
524
+
525
+ /*
526
+ * call-seq:
527
+ * IO.console -> #<File:/dev/tty>
528
+ *
529
+ * Returns an File instance opened console.
530
+ */
531
+ static VALUE
532
+ console_dev(VALUE klass)
533
+ {
534
+ VALUE con = 0;
535
+ rb_io_t *fptr;
536
+
537
+ if (klass == rb_cIO) klass = rb_cFile;
538
+ if (rb_const_defined(klass, id_console)) {
539
+ con = rb_const_get(klass, id_console);
540
+ if (TYPE(con) == T_FILE) {
541
+ if ((fptr = RFILE(con)->fptr) && GetReadFD(fptr) != -1)
542
+ return con;
543
+ }
544
+ rb_mod_remove_const(klass, ID2SYM(id_console));
545
+ }
546
+ {
547
+ VALUE args[2];
548
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
549
+ # define CONSOLE_DEVICE "/dev/tty"
550
+ #elif defined _WIN32
551
+ # define CONSOLE_DEVICE "con$"
552
+ # define CONSOLE_DEVICE_FOR_READING "conin$"
553
+ # define CONSOLE_DEVICE_FOR_WRITING "conout$"
554
+ #endif
555
+ #ifndef CONSOLE_DEVICE_FOR_READING
556
+ # define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE
557
+ #endif
558
+ #ifdef CONSOLE_DEVICE_FOR_WRITING
559
+ VALUE out;
560
+ rb_io_t *ofptr;
561
+ #endif
562
+ int fd;
563
+
564
+ #ifdef CONSOLE_DEVICE_FOR_WRITING
565
+ fd = open(CONSOLE_DEVICE_FOR_WRITING, O_WRONLY);
566
+ if (fd < 0) return Qnil;
567
+ rb_update_max_fd(fd);
568
+ args[1] = INT2FIX(O_WRONLY);
569
+ args[0] = INT2NUM(fd);
570
+ out = rb_class_new_instance(2, args, klass);
571
+ #endif
572
+ fd = open(CONSOLE_DEVICE_FOR_READING, O_RDWR);
573
+ if (fd < 0) {
574
+ #ifdef CONSOLE_DEVICE_FOR_WRITING
575
+ rb_io_close(out);
576
+ #endif
577
+ return Qnil;
578
+ }
579
+ rb_update_max_fd(fd);
580
+ args[1] = INT2FIX(O_RDWR);
581
+ args[0] = INT2NUM(fd);
582
+ con = rb_class_new_instance(2, args, klass);
583
+ GetOpenFile(con, fptr);
584
+ fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
585
+ #ifdef CONSOLE_DEVICE_FOR_WRITING
586
+ GetOpenFile(out, ofptr);
587
+ # ifdef HAVE_RB_IO_GET_WRITE_IO
588
+ ofptr->pathv = fptr->pathv;
589
+ fptr->tied_io_for_writing = out;
590
+ # else
591
+ fptr->f2 = ofptr->f;
592
+ ofptr->f = 0;
593
+ # endif
594
+ ofptr->mode |= FMODE_SYNC;
595
+ #endif
596
+ fptr->mode |= FMODE_SYNC;
597
+ rb_const_set(klass, id_console, con);
598
+ }
599
+ return con;
600
+ }
601
+
602
+ /*
603
+ * IO console methods
604
+ */
605
+ void
606
+ Init_console(void)
607
+ {
608
+ id_getc = rb_intern("getc");
609
+ id_console = rb_intern("console");
610
+ InitVM(console);
611
+ }
612
+
613
+ void
614
+ InitVM_console(void)
615
+ {
616
+ rb_define_method(rb_cIO, "raw", console_raw, 0);
617
+ rb_define_method(rb_cIO, "raw!", console_set_raw, 0);
618
+ rb_define_method(rb_cIO, "getch", console_getch, 0);
619
+ rb_define_method(rb_cIO, "echo=", console_set_echo, 1);
620
+ rb_define_method(rb_cIO, "echo?", console_echo_p, 0);
621
+ rb_define_method(rb_cIO, "noecho", console_noecho, 0);
622
+ rb_define_method(rb_cIO, "winsize", console_winsize, 0);
623
+ rb_define_method(rb_cIO, "winsize=", console_set_winsize, 1);
624
+ rb_define_method(rb_cIO, "iflush", console_iflush, 0);
625
+ rb_define_method(rb_cIO, "oflush", console_oflush, 0);
626
+ rb_define_method(rb_cIO, "ioflush", console_ioflush, 0);
627
+ rb_define_singleton_method(rb_cIO, "console", console_dev, 0);
628
+ }
data/extconf.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'mkmf'
2
+
3
+ ok = true
4
+ hdr = nil
5
+ case
6
+ when macro_defined?("_WIN32", "")
7
+ have_func("rb_w32_map_errno", "ruby.h")
8
+ when hdr = %w"termios.h termio.h".find {|h| have_header(h)}
9
+ have_func("cfmakeraw", hdr)
10
+ when have_header(hdr = "sgtty.h")
11
+ %w"stty gtty".each {|f| have_func(f, hdr)}
12
+ else
13
+ ok = false
14
+ end
15
+ have_header("sys/ioctl.h")
16
+ have_func("rb_io_get_write_io", "ruby/io.h")
17
+ have_func("dup3", "unistd.h")
18
+ if ok
19
+ create_makefile("io/console")
20
+ end
@@ -0,0 +1,20 @@
1
+ def IO.default_console_size
2
+ [
3
+ ENV["LINES"].to_i.nonzero? || 25,
4
+ ENV["COLUMNS"].to_i.nonzero? || 80,
5
+ ]
6
+ end
7
+
8
+ begin
9
+ require 'io/console'
10
+ rescue LoadError
11
+ class IO
12
+ alias console_size default_console_size
13
+ end
14
+ else
15
+ def IO.console_size
16
+ console.winsize
17
+ rescue NoMethodError
18
+ default_console_size
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: io-console
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.3'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nobu Nakada
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-06-24 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: add console capabilities to IO instances.
15
+ email: nobu@ruby-lang.org
16
+ executables: []
17
+ extensions:
18
+ - extconf.rb
19
+ extra_rdoc_files: []
20
+ files:
21
+ - console.c
22
+ - extconf.rb
23
+ - lib/console/size.rb
24
+ homepage: http://www.ruby-lang.org
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - .
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 1.8.10
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: Console interface
48
+ test_files: []