Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more
Creates and managed pseudo terminals (PTYs). See also en.wikipedia.org/wiki/Pseudo_terminal
Checks the status of the child process specified by pid
.
Returns nil
if the process is still alive. If the process is
not alive, will return a Process::Status
or raise a
PTY::ChildExited
(if raise
was true).
pid
The process id of the process to check
raise
If true and the process identified by pid
is no longer alive a
PTY::ChildExited
is raised.
Returns nil or a Process::Status
when raise
is
false.
static VALUE pty_check(int argc, VALUE *argv, VALUE self) { VALUE pid, exc; pid_t cpid; int status; rb_scan_args(argc, argv, "11", &pid, &exc); cpid = rb_waitpid(NUM2PIDT(pid), &status, WNOHANG|WUNTRACED); if (cpid == -1 || cpid == 0) return Qnil; if (!RTEST(exc)) return rb_last_status_get(); raise_from_check(cpid, status); return Qnil; /* not reached */ }
Spawns the specified command on a newly allocated pty.
The command’s controlling tty is set to the slave device of the pty and its standard input/output/error is redirected to the slave device.
command_line
The full command line to run
command
The command to run, as a String.
args
Zero or more arguments, as Strings, representing the arguments to
command
In the non-block form this returns an array of size three, [r, w,
pid]
. In the block form the block will be called with these as
arguments, |r,w,pid|
:
r
An IO that can be read from that contains the command’s standard output and standard error
w
An IO that can be written to that is the command’s standard input
pid
The process identifier for the command.
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_mode_flags("r"); rfptr->fd = info.fd; rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName)); wfptr->mode = rb_io_mode_flags("w") | FMODE_SYNC; wfptr->fd = 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; }
Allocates a pty (pseudo-terminal).
In the non-block form, returns a two element array, [master_io,
slave_file]
.
In the block form, yields two arguments master_io, slave_file
and the value of the block is returned from open
.
The IO and File are both closed after the block completes if they haven’t been already closed.
The arguments in both forms are:
master_io
the master of the pty, as an IO.
slave_file
the slave of the pty, as a File. The path to the terminal device is
available via slave_file.path
PTY.open {|m, s| p m #=> #<IO:masterpty:/dev/pts/1> p s #=> #<File:/dev/pts/1> p s.path #=> "/dev/pts/1" } # Change the buffering type in factor command, # assuming that factor uses stdio for stdout buffering. # If IO.pipe is used instead of PTY.open, # this code deadlocks because factor's stdout is fully buffered. require 'io/console' # for IO#raw! m, s = PTY.open s.raw! # disable newline conversion. r, w = IO.pipe pid = spawn("factor", :in=>r, :out=>s) r.close s.close w.puts "42" p m.gets #=> "42: 2 3 7\n" w.puts "144" p m.gets #=> "144: 2 2 2 2 3 3\n" w.close # The result of read operation when pty slave is closed is platform # dependent. ret = begin m.gets # FreeBSD returns nil. rescue Errno::EIO # GNU/Linux raises EIO. nil end p ret #=> nil
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; }
Spawns the specified command on a newly allocated pty.
The command’s controlling tty is set to the slave device of the pty and its standard input/output/error is redirected to the slave device.
command_line
The full command line to run
command
The command to run, as a String.
args
Zero or more arguments, as Strings, representing the arguments to
command
In the non-block form this returns an array of size three, [r, w,
pid]
. In the block form the block will be called with these as
arguments, |r,w,pid|
:
r
An IO that can be read from that contains the command’s standard output and standard error
w
An IO that can be written to that is the command’s standard input
pid
The process identifier for the command.
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_mode_flags("r"); rfptr->fd = info.fd; rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName)); wfptr->mode = rb_io_mode_flags("w") | FMODE_SYNC; wfptr->fd = 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; }
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.