aboutsummaryrefslogtreecommitdiffstats
path: root/ext/pty
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-15 13:48:51 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-15 13:48:51 +0000
commit4da3316ca317e2f8ec75c07aaec0de094b1db8ed (patch)
tree0b3a55b22abf2e18dbb7c9d49ed8646a00042c5d /ext/pty
parent005e7565377af1d8403732dea8bee16d272530b9 (diff)
downloadruby-4da3316ca317e2f8ec75c07aaec0de094b1db8ed.tar.gz
* ext/pty/pty.c (pty_open): new method PTY.open.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20761 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/pty')
-rw-r--r--ext/pty/pty.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 88163d7ad5..76da867a48 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -369,6 +369,67 @@ getDevice(int *master, int *slave, char SlaveName[DEVICELEN])
}
static VALUE
+pty_close_pty(VALUE assoc)
+{
+ VALUE io;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ io = rb_ary_entry(assoc, i);
+ if (TYPE(io) == T_FILE && 0 <= RFILE(io)->fptr->fd)
+ rb_io_close(io);
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * master_io, slave_file = PTY.open
+ * PTY.open {|master_io, slave_file| ... }
+ *
+ * Allocates a pty (pseudo-terminal).
+ *
+ * It returns an array which contains an IO object and a File object.
+ * The former is the master of the pty.
+ * The latter is the slave of the pty.
+ *
+ * If a block is given, it yields the array instead of return.
+ * The value of the block is returned.
+ * master_io and slave_file is closed when return if they are not closed.
+ *
+ * The filename of the slave is slave_file.path.
+ */
+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);
+
+ master_io = rb_obj_alloc(rb_cIO);
+ MakeOpenFile(master_io, master_fptr);
+ master_fptr->mode = rb_io_mode_flags("r+");
+ master_fptr->fd = master_fd;
+ master_fptr->pathv = rb_obj_freeze(rb_sprintf(" pty %s", slavename));
+
+ slave_file = rb_obj_alloc(rb_cFile);
+ MakeOpenFile(slave_file, slave_fptr);
+ slave_fptr->mode = rb_io_mode_flags("r+");
+ 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;
+}
+
+static VALUE
pty_detach_process(struct pty_info *info)
{
rb_detach_process(info->child_pid);
@@ -464,6 +525,7 @@ Init_pty()
rb_define_module_function(cPTY,"getpty",pty_getpty,-1);
rb_define_module_function(cPTY,"spawn",pty_getpty,-1);
rb_define_singleton_method(cPTY,"check",pty_check,-1);
+ rb_define_singleton_method(cPTY,"open",pty_open,0);
eChildExited = rb_define_class_under(cPTY,"ChildExited",rb_eRuntimeError);
rb_define_method(eChildExited,"status",echild_status,0);