Class: Winproc::PTY

Inherits:
Object
  • Object
show all
Defined in:
lib/winproc.rb,
ext/winproc/winproc.c

Overview

-------------------------------------------------------------------- PTY ---

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



1183
1184
1185
1186
1187
1188
1189
# File 'ext/winproc/winproc.c', line 1183

static VALUE
pty_initialize(int argc, VALUE *argv, VALUE self)
{
    (void)argc; (void)argv; (void)self;
    rb_raise(eError, "winproc: pseudoconsoles are created by Winproc.pty");
    return self;
}

Instance Method Details

#_close_ptyObject



1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
# File 'ext/winproc/winproc.c', line 1220

static VALUE
pty_close_pty(VALUE self)
{
    pty_t *t = pty_get(self);
    if (t->closed || !t->hpc) { t->closed = 1; return Qnil; }
    {
        pclosepty_t c; c.hpc = t->hpc;
        rb_thread_call_without_gvl(pty_close_fn, &c, NULL, NULL);
    }
    t->hpc = NULL;
    t->closed = 1;
    return Qnil;
}

#_resize(vcols, vrows) ⇒ Object



1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
# File 'ext/winproc/winproc.c', line 1191

static VALUE
pty_resize(VALUE self, VALUE vcols, VALUE vrows)
{
    pty_t *t = pty_live(self);
    int cols = NUM2INT(vcols), rows = NUM2INT(vrows);
    COORD size;
    HRESULT hr;
    if (cols < 1 || cols > 0x7FFF || rows < 1 || rows > 0x7FFF)
        rb_raise(rb_eArgError, "winproc: cols/rows must be 1..32767");
    size.X = (SHORT)cols; size.Y = (SHORT)rows;
    hr = p_ResizePseudoConsole(t->hpc, size);
    if (FAILED(hr)) raise_code(eOSError, "ResizePseudoConsole", (DWORD)(hr & 0xFFFF));
    t->cols = cols; t->rows = rows;
    return self;
}

#close(kill: true) ⇒ Object

Deadlock-free teardown, exact order (§2.6):

1. kill: true and child alive -> process.kill
2. close the OUTPUT stream (cancels any in-flight read; the blocked
 reader raises Closed) — makes step 4 safe on pre-24H2 Windows
3. close the INPUT stream
4. ClosePseudoConsole(hPC) (GVL released; output pipe gone, no deadlock)
5. memoize the child's exit code if exited, then process.close

Idempotent. After close, pty.process.exitstatus still answers (memoized).



432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'lib/winproc.rb', line 432

def close(kill: true)
  return nil if closed?

  begin
    @process.kill if kill && process_alive_safely?
  rescue Winproc::Error
    # best-effort; teardown must proceed
  end
  @output.close
  @input.close
  Winproc.run_blocking { _close_pty }
  @process.close
  nil
end

#closed?Boolean

Returns:

  • (Boolean)


1234
# File 'ext/winproc/winproc.c', line 1234

static VALUE pty_closed_p(VALUE self) { return pty_get(self)->closed ? Qtrue : Qfalse; }

#colsObject



1207
# File 'ext/winproc/winproc.c', line 1207

static VALUE pty_cols(VALUE self) { return INT2NUM(pty_get(self)->cols); }

#processObject

The child Process; use it for wait/kill/exitstatus.



422
# File 'lib/winproc.rb', line 422

def process = @process

#read(maxlen = 65_536) ⇒ Object

Raw bytes from the terminal output stream (UTF-8 text interleaved with VT escape sequences, verbatim). Binary (ASCII-8BIT) String; nil at EOF.



406
407
408
# File 'lib/winproc.rb', line 406

def read(maxlen = 65_536)
  Winproc.run_blocking { @output._read(maxlen) }
end

#resize(cols, rows) ⇒ Object

ResizePseudoConsole. 1..32767 each (COORD is SHORT).



417
418
419
# File 'lib/winproc.rb', line 417

def resize(cols, rows)
  _resize(Integer(cols), Integer(rows))
end

#rowsObject



1208
# File 'ext/winproc/winproc.c', line 1208

static VALUE pty_rows(VALUE self) { return INT2NUM(pty_get(self)->rows); }

#write(bytes) ⇒ Object

Bytes to the terminal input stream. Plain text = keystrokes; control keys are VT sequences. Send UTF-8. "\r" is Enter (not "\n").



412
413
414
# File 'lib/winproc.rb', line 412

def write(bytes)
  Winproc.run_blocking { @input._write(bytes) }
end