Spec-Zone.ru › Ruby 3.3

класс PTY

Родитель:
Объект

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

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

Лицензия

© Авторские права 1998 года Акинори Ито.

Данное программное обеспечение может быть свободно перераспределено для этой цели, полностью или частично, при условии, что данное уведомление об авторском праве полностью включено во все копии данного программного обеспечения и приложений, а также производных от него.

Это программное обеспечение предоставляется «как есть», без каких-либо гарантий, явных или подразумеваемых, по любым вопросам, включая, но не ограничиваясь, гарантиями пригодности для конкретной цели или товарной пригодности, или результатами, полученными от использования данного программного обеспечения.

Методы Публичного класса

check(pid, raise = false) → Process::Status или nil Показать исходный код
check(pid, true) → nil или вызывает 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.

getpty
Псевдоним для: spawn
open → [master_io, slave_file] Показать исходный код
open {|(master_io, slave_file)| ... } → значение блока
static VALUE
pty_open(VALUE klass)
{
    int master_fd, slave_fd;
    char slavename[DEVICELEN];

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

    VALUE master_path = rb_obj_freeze(rb_sprintf("masterpty:%s", slavename));
    VALUE master_io = rb_io_open_descriptor(rb_cIO, master_fd, FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX, master_path, RUBY_IO_TIMEOUT_DEFAULT, NULL);

    VALUE slave_path = rb_obj_freeze(rb_str_new_cstr(slavename));
    VALUE slave_file = rb_io_open_descriptor(rb_cFile, slave_fd, FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX | FMODE_TTY, slave_path, RUBY_IO_TIMEOUT_DEFAULT, NULL);

    VALUE 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([env,] command_line) { |r, w, pid| ... } Показать исходный код
spawn([env,] command_line) → [r, w, pid]
spawn([env,] command, arguments, ...) { |r, w, pid| ... }
spawn([env,] command, arguments, ...) → [r, w, pid]
static VALUE
pty_getpty(int argc, VALUE *argv, VALUE self)
{
    VALUE res;
    struct pty_info info;
    char SlaveName[DEVICELEN];

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

    VALUE pty_path = rb_obj_freeze(rb_str_new_cstr(SlaveName));
    VALUE rport = rb_io_open_descriptor(
        rb_cFile, info.fd, FMODE_READABLE, pty_path, RUBY_IO_TIMEOUT_DEFAULT, NULL
    );

    int wpty_fd = rb_cloexec_dup(info.fd);
    if (wpty_fd == -1) {
        rb_sys_fail("dup()");
    }
    VALUE wport = rb_io_open_descriptor(
        rb_cFile, wpty_fd, FMODE_WRITABLE | FMODE_TRUNC | FMODE_CREATE | FMODE_SYNC,
        pty_path, RUBY_IO_TIMEOUT_DEFAULT, NULL
    );

    res = rb_ary_new2(3);
    rb_ary_store(res, 0, rport);
    rb_ary_store(res, 1, 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, и стандартный ввод/вывод/ошибка перенаправляются на слейв-устройство.

env — это необязательный хэш, предоставляющий дополнительные переменные среды для запущенного pty.

# sets FOO to "bar"
PTY.spawn({"FOO"=>"bar"}, "printenv", "FOO") { |r,w,pid| p r.read } #=> "bar\r\n"
# unsets FOO
PTY.spawn({"FOO"=>nil}, "printenv", "FOO") { |r,w,pid| p r.read } #=> ""

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

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

В режиме без блока, это возвращает массив размером три, [r, w, pid].

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

r

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

w

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

pid

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

Также алиасируется как: getpty

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

Spec-Zone.ru

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