modul PTY
Erstellt und verwaltet Pseudo-Terminals (PTYs). Siehe auch en.wikipedia.org/wiki/Pseudo_terminal
PTY ermöglicht es Ihnen, neue Terminals mit ::open oder ::spawn ein neues Terminal mit einem bestimmten Befehl zu belegen.
Beispiel
In diesem Beispiel ändern wir den Puffertyp im factor-Befehl, vorausgesetzt, factor verwendet stdio für die Pufferung der Standardausgabe.
Wenn anstelle von PTY.open IO.pipe verwendet wird, friert dieser Code ein, da die Standardausgabe von factor vollständig gepuffert ist.
# 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
Lizenz
© Copyright 1998 von Akinori Ito.
Diese Software darf für diesen Zweck frei weiterverteilt werden, ganz oder teilweise, vorausgesetzt, diese vollständige Copyright-Anmerkung ist auf allen Kopien dieser Software und daraus abgeleiteten Anwendungen und Ableitungen enthalten.
Diese Software wird "wie besehen" zur Verfügung gestellt, ohne jegliche Garantie, weder ausdrücklich noch stillschweigend, in Bezug auf jegliche Angelegenheit, einschließlich, aber nicht beschränkt auf Garantie der Eignung für einen bestimmten Zweck oder der Marktfähigkeit, oder Ergebnisse, die aus der Verwendung dieser Software erzielt werden.
Öffentliche Klassenmethoden
Source
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);
}
Überprüft den Status des durch pid angegebenen Kindprozesses. Gibt nil zurück, wenn der Prozess noch läuft.
Wenn der Prozess nicht mehr läuft und raise auf true gesetzt war, wird eine Ausnahme vom Typ PTY::ChildExited ausgelöst. Andernfalls wird eine Instanz von Process::Status zurückgegeben.
pid-
Die Prozess-ID des zu prüfenden Prozesses
raise-
Wenn
trueund der durchpididentifizierte Prozess nicht mehr läuft, wird einePTY::ChildExitedausgelöst.
Source
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;
}
Belegt ein PTY (Pseudo-Terminal).
In der Blockform wird ein Array aus zwei Elementen (master_io, slave_file) übergeben, und der Wert des Blocks wird von open zurückgegeben.
Die IO- und File-Objekte werden nach Abschluss des Blocks geschlossen, wenn sie nicht bereits geschlossen wurden.
PTY.open {|master, slave| p master #=> #<IO:masterpty:/dev/pts/1> p slave #=> #<File:/dev/pts/1> p slave.path #=> "/dev/pts/1" }
In der Nicht-Block-Form wird ein zweielementiges Array zurückgegeben: [master_io, slave_file].
master, slave = PTY.open # do something with master for IO, or the slave file
Die Argumente in beiden Formen sind
master_io-
Das Master-Ende des PTY als
IO-Objekt. slave_file-
Das Slave-Ende des PTY als
File-Objekt. Der Pfad zum Terminal-Gerät ist überslave_file.pathverfügbar.
IO#raw! kann verwendet werden, um Zeilenumbruchkonvertierungen zu deaktivieren.
require 'io/console' PTY.open {|m, s| s.raw! # ... }
Source
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;
}
Startet den angegebenen Befehl auf einem neu belegten PTY. Sie können auch den Alias ::getpty verwenden.
Das steuernde TTY des Befehls wird auf das Slave-Gerät des PTY gesetzt, und seine Standardeingabe/-ausgabe/-fehler werden auf das Slave-Gerät umgeleitet.
env ist ein optionaler Hash, der zusätzliche Umgebungsvariablen für das gestartete PTY bereitstellt.
# sets FOO to "bar" PTY.spawn({"FOO"=>"bar"}, "printenv", "FOO") do |r, w, pid| p r.read #=> "bar\r\n" ensure r.close; w.close; Process.wait(pid) end # unsets FOO PTY.spawn({"FOO"=>nil}, "printenv", "FOO") do |r, w, pid| p r.read #=> "" ensure r.close; w.close; Process.wait(pid) end
command und command_line sind die vollständigen auszuführenden Befehle, gegeben als String. Zusätzliche arguments werden an den Befehl übergeben.
Rückgabewerte
In der Nicht-Block-Form gibt dies ein Array der Größe drei zurück: [r, w, pid].
In der Blockform werden dieselben Werte an den Block übergeben.
r-
Ein lesbares
IO-Objekt, das die Standardausgabe und die Standardfehlerausgabe des Befehls enthält. w-
Ein beschreibbares
IO-Objekt, das die Standardeingabe des Befehls darstellt. pid-
Die Prozesskennung für den Befehl.
Bereinigung
Diese Methode bereinigt nicht wie das Schließen von IOs oder das Warten auf einen Kindprozess, außer dass der Prozess im Blockform getrennt wird, um zu verhindern, dass er zu einem Zombie wird (siehe Process.detach). Jegliche andere Bereinigung liegt in der Verantwortung des Aufrufers. Wenn Sie auf pid warten, stellen Sie sicher, dass Sie sowohl r als auch w schließen, bevor Sie dies tun. Dies in umgekehrter Reihenfolge kann auf einigen Betriebssystemen zu einem Deadlock führen.