In Files

  • io/console/console.c
  • io/nonblock/nonblock.c
  • io/wait/wait.c

Class/Module Index [+]

Quicksearch

IO

Public Class Methods

console → # click to toggle source
console(sym, *args)

Returns an File instance opened console.

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.

You must require 'io/console' to use this method.

 
               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);
    }
    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) ||
            (!(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 (!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
# define CONSOLE_DEVICE "con$"
# define CONSOLE_DEVICE_FOR_READING "conin$"
# define CONSOLE_DEVICE_FOR_WRITING "conout$"
#endif
#ifndef CONSOLE_DEVICE_FOR_READING
# define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE
#endif
#ifdef CONSOLE_DEVICE_FOR_WRITING
        VALUE out;
        rb_io_t *ofptr;
#endif
        int fd;

#ifdef CONSOLE_DEVICE_FOR_WRITING
        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) {
#ifdef CONSOLE_DEVICE_FOR_WRITING
            rb_io_close(out);
#endif
            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
        GetOpenFile(out, ofptr);
        ofptr->pathv = fptr->pathv;
        fptr->tied_io_for_writing = out;
        ofptr->mode |= FMODE_SYNC;
#endif
        fptr->mode |= FMODE_SYNC;
        rb_const_set(klass, id_console, con);
    }
    if (sym) {
        return rb_f_send(argc, argv, con);
    }
    return con;
}
            
console_size() click to toggle source
default_console_size() click to toggle source

fallback to console window size

 
               # File io/console/lib/console/size.rb, line 2
def IO.default_console_size
  [
    ENV["LINES"].to_i.nonzero? || 25,
    ENV["COLUMNS"].to_i.nonzero? || 80,
  ]
end
            
Also aliased as: console_size

Public Instance Methods

beep() click to toggle source
 
               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
    if (write(fd, "\a", 1) < 0)
        rb_sys_fail(0);
#endif
    return io;
}
            
cooked {|io| } click to toggle source

Yields self within cooked mode.

STDIN.cooked(&:gets)

will read and return a line with echo back and line editing.

You must require 'io/console' to use this method.

 
               static VALUE
console_cooked(VALUE io)
{
    return ttymode(io, rb_yield, set_cookedmode, NULL);
}
            
cooked! click to toggle source

Enables cooked mode.

If the terminal mode needs to be back, use io.cooked { … }.

You must require 'io/console' to use this method.

 
               static VALUE
console_set_cooked(VALUE io)
{
    conmode t;
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    set_cookedmode(&t, NULL);
    if (!setattr(fd, &t)) rb_sys_fail(0);
    return io;
}
            
cursor() click to toggle source
 
               static VALUE
console_cursor_pos(VALUE io)
{
    rb_io_t *fptr;
    int fd;
    rb_console_size_t ws;

    GetOpenFile(io, fptr);
    fd = GetWriteFD(fptr);
    if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
        rb_syserr_fail(LAST_ERROR, 0);
    }
    return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.X), UINT2NUM(ws.dwCursorPosition.Y));
}
            
cursor=(p1) click to toggle source
 
               static VALUE
console_cursor_set(VALUE io, VALUE cpos)
{
    cpos = rb_convert_type(cpos, T_ARRAY, "Array", "to_ary");
    if (RARRAY_LEN(cpos) != 2) rb_raise(rb_eArgError, "expected 2D coordinate");
    return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1));
}
            
echo = flag click to toggle source

Enables/disables echo back. On some platforms, all combinations of this flags and raw/cooked mode may not be valid.

You must require 'io/console' to use this method.

 
               static VALUE
console_set_echo(VALUE io, VALUE f)
{
    conmode t;
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    if (RTEST(f))
        set_echo(&t, NULL);
    else
        set_noecho(&t, NULL);
    if (!setattr(fd, &t)) rb_sys_fail(0);
    return io;
}
            
echo? → true or false click to toggle source

Returns true if echo back is enabled.

You must require 'io/console' to use this method.

 
               static VALUE
console_echo_p(VALUE io)
{
    conmode t;
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    return echo_p(&t) ? Qtrue : Qfalse;
}
            
getch(min: nil, time: nil) → char click to toggle source

Reads and returns a character in raw mode.

See #raw for details on the parameters.

You must require 'io/console' to use this method.

 
               static VALUE
console_getch(int argc, VALUE *argv, VALUE io)
{
    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
    return ttymode(io, getc_call, set_rawmode, optp);
}
            
getpass(prompt=nil) → string click to toggle source

Reads and returns a line without echo back. Prints prompt unless it is nil.

You must require 'io/console' to use this method.

 
               static VALUE
console_getpass(int argc, VALUE *argv, VALUE io)
{
    VALUE str, wio;

    rb_check_arity(argc, 0, 1);
    wio = rb_io_get_write_io(io);
    if (wio == io && io == rb_stdin) wio = rb_stderr;
    prompt(argc, argv, wio);
    str = rb_ensure(getpass_call, io, puts_call, wio);
    return str_chomp(str);
}
            
goto(p1, p2) click to toggle source
 
               static VALUE
console_goto(VALUE io, VALUE x, VALUE y)
{
    rb_io_t *fptr;
    int fd;
    COORD pos;

    GetOpenFile(io, fptr);
    fd = GetWriteFD(fptr);
    pos.X = NUM2UINT(x);
    pos.Y = NUM2UINT(y);
    if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
        rb_syserr_fail(LAST_ERROR, 0);
    }
    return io;
}
            
iflush click to toggle source

Flushes input buffer in kernel.

You must require 'io/console' to use this method.

 
               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
    if (tcflush(fd, TCIFLUSH)) rb_sys_fail(0);
#endif
    (void)fd;
    return io;
}
            
ioflush click to toggle source

Flushes input and output buffers in kernel.

You must require 'io/console' to use this method.

 
               static VALUE
console_ioflush(VALUE io)
{
    rb_io_t *fptr;
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    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)) rb_sys_fail(0);
        if (tcflush(fd2, TCOFLUSH)) rb_sys_fail(0);
    }
    else {
        if (tcflush(fd1, TCIOFLUSH)) rb_sys_fail(0);
    }
#endif
    return io;
}
            
noecho {|io| } click to toggle source

Yields self with disabling echo back.

STDIN.noecho(&:gets)

will read and return a line without echo back.

You must require 'io/console' to use this method.

 
               static VALUE
console_noecho(VALUE io)
{
    return ttymode(io, rb_yield, set_noecho, NULL);
}
            
nonblock {|io| } → io click to toggle source
nonblock(boolean) {|io| } → io

Yields self in non-blocking mode.

When false is given as an argument, self is yielded in blocking mode. The original mode is restored after the block is executed.

 
               static VALUE
rb_io_nonblock_block(int argc, VALUE *argv, VALUE io)
{
    int nb = 1;
    rb_io_t *fptr;
    int f, restore[2];

    GetOpenFile(io, fptr);
    if (argc > 0) {
        VALUE v;
        rb_scan_args(argc, argv, "01", &v);
        nb = RTEST(v);
    }
    f = io_nonblock_mode(fptr->fd);
    restore[0] = fptr->fd;
    restore[1] = f;
    if (!io_nonblock_set(fptr->fd, f, nb))
        return rb_yield(io);
    return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore);
}
            
nonblock = boolean → boolean click to toggle source

Enables non-blocking mode on a stream when set to true, and blocking mode when set to false.

 
               static VALUE
rb_io_nonblock_set(VALUE io, VALUE nb)
{
    rb_io_t *fptr;
    GetOpenFile(io, fptr);
    if (RTEST(nb))
        rb_io_set_nonblock(fptr);
    else
        io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb));
    return io;
}
            
nonblock? → boolean click to toggle source

Returns true if an IO object is in non-blocking mode.

 
               static VALUE
rb_io_nonblock_p(VALUE io)
{
    rb_io_t *fptr;
    GetOpenFile(io, fptr);
    if (io_nonblock_mode(fptr->fd) & O_NONBLOCK)
        return Qtrue;
    return Qfalse;
}
            
nread → int click to toggle source

Returns number of bytes that can be read without blocking. Returns zero if no information available.

 
               static VALUE
io_nread(VALUE io)
{
    rb_io_t *fptr;
    int len;
    ioctl_arg n;

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    len = rb_io_read_pending(fptr);
    if (len > 0) return INT2FIX(len);
    if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
    if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
    if (n > 0) return ioctl_arg2num(n);
    return INT2FIX(0);
}
            
oflush click to toggle source

Flushes output buffer in kernel.

You must require 'io/console' to use this method.

 
               static VALUE
console_oflush(VALUE 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)) rb_sys_fail(0);
#endif
    (void)fd;
    return io;
}
            
pressed?(p1) click to toggle source
 
               static VALUE
console_key_pressed_p(VALUE io, VALUE k)
{
    int vk = -1;

    if (FIXNUM_P(k)) {
        vk = NUM2UINT(k);
    }
    else {
        const struct vktable *t;
        const char *kn;
        if (SYMBOL_P(k)) {
            k = rb_sym2str(k);
            kn = RSTRING_PTR(k);
        }
        else {
            kn = StringValuePtr(k);
        }
        t = console_win32_vk(kn, RSTRING_LEN(k));
        if (!t || (vk = (short)t->vk) == -1) {
            rb_raise(rb_eArgError, "unknown virtual key code: % "PRIsVALUE, k);
        }
    }
    return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse;
}
            
raw(min: nil, time: nil) {|io| } click to toggle source

Yields self within raw mode.

STDIN.raw(&:gets)

will read and return a line without echo back and line editing.

The parameter min specifies the minimum number of bytes that should be received when a read operation is performed. (default: 1)

The parameter time specifies the timeout in seconds with a precision of 1/10 of a second. (default: 0)

Refer to the manual page of termios for further details.

You must require 'io/console' to use this method.

 
               static VALUE
console_raw(int argc, VALUE *argv, VALUE io)
{
    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
    return ttymode(io, rb_yield, set_rawmode, optp);
}
            
raw!(min: nil, time: nil) click to toggle source

Enables raw mode.

If the terminal mode needs to be back, use io.raw { … }.

See #raw for details on the parameters.

You must require 'io/console' to use this method.

 
               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, &opts);

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    set_rawmode(&t, optp);
    if (!setattr(fd, &t)) rb_sys_fail(0);
    return io;
}
            
ready? → true, false or nil click to toggle source

Returns true if input available without blocking, or false. Returns nil if no information available.

 
               static VALUE
io_ready_p(VALUE io)
{
    rb_io_t *fptr;
    struct timeval tv = {0, 0};

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    if (rb_io_read_pending(fptr)) return Qtrue;
    if (wait_for_single_fd(fptr, RB_WAITFD_IN, &tv))
        return Qtrue;
    return Qfalse;
}
            
wait(timeout = nil, mode = :read) → IO, true or nil click to toggle source

Waits until IO is readable or writable without blocking and returns self, or nil when times out. Returns true immediately when buffered data is available. Optional parameter mode is one of :read, :write, or :read_write.

 
               static VALUE
io_wait_readwrite(int argc, VALUE *argv, VALUE io)
{
    rb_io_t *fptr;
    struct timeval timerec;
    struct timeval *tv = NULL;
    int event = 0;
    int i;

    GetOpenFile(io, fptr);
    for (i = 0; i < argc; ++i) {
        if (SYMBOL_P(argv[i])) {
            event |= wait_mode_sym(argv[i]);
        }
        else {
            *(tv = &timerec) = rb_time_interval(argv[i]);
        }
    }
    /* rb_time_interval() and might_mode() might convert the argument */
    rb_io_check_closed(fptr);
    if (!event) event = RB_WAITFD_IN;
    if ((event & RB_WAITFD_IN) && rb_io_read_pending(fptr))
        return Qtrue;
    if (wait_for_single_fd(fptr, event, tv))
        return io;
    return Qnil;
}
            
wait_readable → IO, true or nil click to toggle source
wait_readable(timeout) → IO, true or nil

Waits until IO is readable without blocking and returns self, or nil when times out. Returns true immediately when buffered data is available.

 
               static VALUE
io_wait_readable(int argc, VALUE *argv, VALUE io)
{
    rb_io_t *fptr;
    struct timeval timerec;
    struct timeval *tv;

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    tv = get_timeout(argc, argv, &timerec);
    if (rb_io_read_pending(fptr)) return Qtrue;
    if (wait_for_single_fd(fptr, RB_WAITFD_IN, tv)) {
        return io;
    }
    return Qnil;
}
            
wait_writable → IO click to toggle source
wait_writable(timeout) → IO or nil

Waits until IO is writable without blocking and returns self or nil when times out.

 
               static VALUE
io_wait_writable(int argc, VALUE *argv, VALUE io)
{
    rb_io_t *fptr;
    struct timeval timerec;
    struct timeval *tv;

    GetOpenFile(io, fptr);
    rb_io_check_writable(fptr);
    tv = get_timeout(argc, argv, &timerec);
    if (wait_for_single_fd(fptr, RB_WAITFD_OUT, tv)) {
        return io;
    }
    return Qnil;
}
            
winsize → [rows, columns] click to toggle source

Returns console size.

You must require 'io/console' to use this method.

 
               static VALUE
console_winsize(VALUE io)
{
    rb_io_t *fptr;
    int fd;
    rb_console_size_t ws;

    GetOpenFile(io, fptr);
    fd = GetWriteFD(fptr);
    if (!getwinsize(fd, &ws)) rb_sys_fail(0);
    return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
}
            
winsize = [rows, columns] click to toggle source

Tries to set console size. The effect depends on the platform and the running environment.

You must require 'io/console' to use this method.

 
               static VALUE
console_set_winsize(VALUE io, VALUE size)
{
    rb_io_t *fptr;
    rb_console_size_t ws;
#if defined _WIN32
    HANDLE wh;
    int newrow, newcol;
    BOOL ret;
#endif
    VALUE row, col, xpixel, ypixel;
    const VALUE *sz;
    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);
    }
    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(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)
    SET(row);
    SET(col);
    SET(xpixel);
    SET(ypixel);
#undef SET
    if (!setwinsize(fd, &ws)) rb_sys_fail(0);
#elif defined _WIN32
    wh = (HANDLE)rb_w32_get_osfhandle(fd);
#define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
    SET(row);
    SET(col);
#undef SET
    if (!NIL_P(xpixel)) (void)NUM2UINT(xpixel);
    if (!NIL_P(ypixel)) (void)NUM2UINT(ypixel);
    if (!GetConsoleScreenBufferInfo(wh, &ws)) {
        rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo");
    }
    ws.dwSize.X = newcol;
    ret = SetConsoleScreenBufferSize(wh, ws.dwSize);
    ws.srWindow.Left = 0;
    ws.srWindow.Top = 0;
    ws.srWindow.Right = newcol-1;
    ws.srWindow.Bottom = newrow-1;
    if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) {
        rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo");
    }
    /* retry when shrinking buffer after shrunk window */
    if (!ret && !SetConsoleScreenBufferSize(wh, ws.dwSize)) {
        rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo");
    }
    /* remove scrollbar if possible */
    if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) {
        rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo");
    }
#endif
    return io;
}