Spec-Zone.ru › Ruby 2.6

модуль PTY

Создаёт и управляет псевдотерминалами (PTY). См. также en.wikipedia.org/wiki/Pseudo_terminal

PTY позволяет вам выделять новые терминалы с помощью ::open или ::spawn новый терминал с определённой командой.

Пример

В этом примере мы изменим тип буферизации в команде factor, предполагая, что фактор использует stdio для буферизации stdout.

Если IO.pipe используется вместо PTY.open, этот код застопорится, потому что stdout фактора полностью буферизован.

# start by requiring the standard library PTY
require 'pty'

master, slave = PTY.open
read, write = IO.pipe
pid = spawn("factor", :in=>read, :out=>slave)
read.close     # we dont need the read
slave.close    # or the slave

# pipe "42" to the factor command
write.puts "42"
# output the response from factor
p master.gets #=> "42: 2 3 7\n"

# pipe "144" to factor and print out the response
write.puts "144"
p master.gets #=> "144: 2 2 2 2 3 3\n"
write.close # close the pipe

# The result of read operation when pty slave is closed is platform
# dependent.
ret = begin
        master.gets     # FreeBSD returns nil.
      rescue Errno::EIO # GNU/Linux raises EIO.
        nil
      end
p ret #=> nil

Лицензия

C) Copyright 1998 by Akinori Ito.

This software may be redistributed freely for this purpose, in full
or in part, provided that this entire copyright notice is included
on any copies of this software and applications and derivations thereof.

This software is provided on an "as is" basis, without warranty of any
kind, either expressed or implied, as to any matter including, but not
limited to warranty of fitness of purpose, or merchantability, or
results obtained from use of this software.

Методы открытого класса

check(pid, raise = false) → Process::Status or nil Показать исходный код
check(pid, true) → nil or raises PTY::ChildExited
static VALUE
pty_check(int argc, VALUE *argv, VALUE self)
{
    VALUE pid, exc;
    rb_pid_t cpid;
    int status;
    const int flag =
#ifdef WNOHANG
        WNOHANG|
#endif
#ifdef WUNTRACED
        WUNTRACED|
#endif
        0;

    rb_scan_args(argc, argv, "11", &pid, &exc);
    cpid = rb_waitpid(NUM2PIDT(pid), &status, flag);
    if (cpid == -1 || cpid == 0) return Qnil;

    if (!RTEST(exc)) return rb_last_status_get();
    raise_from_check(cpid, status);

    UNREACHABLE_RETURN(Qnil);
}

Проверяет состояние дочернего процесса, указанного pid. Возвращает nil, если процесс всё ещё активен.

Если процесс не активен, и raise было true, будет вызвано исключение PTY::ChildExited. В противном случае будет возвращён экземпляр Process::Status.

pid

Идентификатор процесса для проверки

raise

Если true и процесс, идентифицированный pid, больше не активен, то генерируется исключение PTY::ChildExited.

spawn(command_line) { |r, w, pid| ... } Показать исходный код
spawn(command_line) → [r, w, pid]
spawn(command, arguments, ...) { |r, w, pid| ... }
spawn(command, arguments, ...) → [r, w, pid]
static VALUE
pty_getpty(int argc, VALUE *argv, VALUE self)
{
    VALUE res;
    struct pty_info info;
    rb_io_t *wfptr,*rfptr;
    VALUE rport = rb_obj_alloc(rb_cFile);
    VALUE wport = rb_obj_alloc(rb_cFile);
    char SlaveName[DEVICELEN];

    MakeOpenFile(rport, rfptr);
    MakeOpenFile(wport, wfptr);

    establishShell(argc, argv, &info, SlaveName);

    rfptr->mode = rb_io_modestr_fmode("r");
    rfptr->fd = info.fd;
    rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName));

    wfptr->mode = rb_io_modestr_fmode("w") | FMODE_SYNC;
    wfptr->fd = rb_cloexec_dup(info.fd);
    if (wfptr->fd == -1)
        rb_sys_fail("dup()");
    rb_update_max_fd(wfptr->fd);
    wfptr->pathv = rfptr->pathv;

    res = rb_ary_new2(3);
    rb_ary_store(res,0,(VALUE)rport);
    rb_ary_store(res,1,(VALUE)wport);
    rb_ary_store(res,2,PIDT2NUM(info.child_pid));

    if (rb_block_given_p()) {
        rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info);
        return Qnil;
    }
    return res;
}

Запускает указанную команду в новом выделенном pty. Также можно использовать псевдоним ::getpty.

Контролирующий tty команды устанавливается на служебное устройство pty, а её стандартный ввод/вывод/ошибка перенаправляются на служебное устройство.

command и command_line - полные команды для выполнения, заданные в виде String. Любые дополнительные arguments будут переданы команде.

Возвращаемые значения

В неблокирующей форме возвращается массив размером три, [r, w, pid].

В блочной форме эти же значения будут переданы в блок:

r

Читaемый IO, содержащий стандартный вывод и стандартную ошибку команды

w

Записываемый IO, являющийся стандартным вводом команды

pid

Идентификатор процесса для команды.

open → [master_io, slave_file] Показать исходный код
open {|master_io, slave_file| ... } → block value
static VALUE
pty_open(VALUE klass)
{
    int master_fd, slave_fd;
    char slavename[DEVICELEN];
    VALUE master_io, slave_file;
    rb_io_t *master_fptr, *slave_fptr;
    VALUE assoc;

    getDevice(&master_fd, &slave_fd, slavename, 1);

    master_io = rb_obj_alloc(rb_cIO);
    MakeOpenFile(master_io, master_fptr);
    master_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX;
    master_fptr->fd = master_fd;
    master_fptr->pathv = rb_obj_freeze(rb_sprintf("masterpty:%s", slavename));

    slave_file = rb_obj_alloc(rb_cFile);
    MakeOpenFile(slave_file, slave_fptr);
    slave_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX | FMODE_TTY;
    slave_fptr->fd = slave_fd;
    slave_fptr->pathv = rb_obj_freeze(rb_str_new_cstr(slavename));

    assoc = rb_assoc_new(master_io, slave_file);
    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, assoc, pty_close_pty, assoc);
    }
    return assoc;
}

Выделяет pty (псевдотерминал).

В блочной форме передаёт два аргумента master_io, slave_file, а возвращаемое значение блока возвращается из open.

И IO, и File оба закрываются после завершения блока, если они ещё не закрыты.

PTY.open {|master, slave|
  p master      #=> #<IO:masterpty:/dev/pts/1>
  p slave      #=> #<File:/dev/pts/1>
  p slave.path #=> "/dev/pts/1"
}

В неблокирующей форме возвращается массив из двух элементов, [master_io, slave_file].

master, slave = PTY.open
# do something with master for IO, or the slave file

Аргументы в обеих формах:

master_io

ведущий pty, как IO.

slave_file

ведомый pty, как File. Путь к устройству терминала доступен через slave_file.path

IO#raw! можно использовать для отключения преобразования символов перевода строки:

require 'io/console'
PTY.open {|m, s|
  s.raw!
  ...
}
spawn(command_line) { |r, w, pid| ... } Показать исходный код
spawn(command_line) → [r, w, pid]
spawn(command, arguments, ...) { |r, w, pid| ... }
spawn(command, arguments, ...) → [r, w, pid]
static VALUE
pty_getpty(int argc, VALUE *argv, VALUE self)
{
    VALUE res;
    struct pty_info info;
    rb_io_t *wfptr,*rfptr;
    VALUE rport = rb_obj_alloc(rb_cFile);
    VALUE wport = rb_obj_alloc(rb_cFile);
    char SlaveName[DEVICELEN];

    MakeOpenFile(rport, rfptr);
    MakeOpenFile(wport, wfptr);

    establishShell(argc, argv, &info, SlaveName);

    rfptr->mode = rb_io_modestr_fmode("r");
    rfptr->fd = info.fd;
    rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName));

    wfptr->mode = rb_io_modestr_fmode("w") | FMODE_SYNC;
    wfptr->fd = rb_cloexec_dup(info.fd);
    if (wfptr->fd == -1)
        rb_sys_fail("dup()");
    rb_update_max_fd(wfptr->fd);
    wfptr->pathv = rfptr->pathv;

    res = rb_ary_new2(3);
    rb_ary_store(res,0,(VALUE)rport);
    rb_ary_store(res,1,(VALUE)wport);
    rb_ary_store(res,2,PIDT2NUM(info.child_pid));

    if (rb_block_given_p()) {
        rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info);
        return Qnil;
    }
    return res;
}

Запускает указанную команду в новом выделенном pty. Также можно использовать псевдоним ::getpty.

Контролирующий tty команды устанавливается на служебное устройство pty, а её стандартный ввод/вывод/ошибка перенаправляются на служебное устройство.

command и command_line - полные команды для выполнения, заданные в виде String. Любые дополнительные arguments будут переданы команде.

Возвращаемые значения

В неблокирующей форме возвращается массив размером три, [r, w, pid].

В блочной форме эти же значения будут переданы в блок:

r

Читaемый IO, содержащий стандартный вывод и стандартную ошибку команды

w

Записываемый IO, являющийся стандартным вводом команды

pid

Идентификатор процесса для команды.

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API