summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-io/src
diff options
context:
space:
mode:
authorksss <[email protected]>2017-12-17 14:50:43 +0900
committerksss <[email protected]>2017-12-17 18:02:37 +0900
commit35185e69bff725e0f11d49db9b2793185fe9927f (patch)
tree93c0a3f5fdb0a012a697e429ad535645d508fa1c /mrbgems/mruby-io/src
parentddb1aae41de507efb9ab3d7ec2edb23911888783 (diff)
downloadmruby-35185e69bff725e0f11d49db9b2793185fe9927f.tar.gz
mruby-35185e69bff725e0f11d49db9b2793185fe9927f.zip
Implement IO#initialize_copy
Diffstat (limited to 'mrbgems/mruby-io/src')
-rw-r--r--mrbgems/mruby-io/src/io.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c
index afd6dc7c3..643671d1e 100644
--- a/mrbgems/mruby-io/src/io.c
+++ b/mrbgems/mruby-io/src/io.c
@@ -530,6 +530,54 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
}
#endif
+static int
+mrb_dup(mrb_state *mrb, int fd)
+{
+ int new_fd;
+
+ if (fd < 0)
+ return fd;
+
+ new_fd = dup(fd);
+ if (new_fd == -1)
+ mrb_sys_fail(mrb, 0);
+ return new_fd;
+}
+
+mrb_value
+mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
+{
+ mrb_value orig;
+ mrb_value buf;
+ struct mrb_io *fptr_copy;
+ struct mrb_io *fptr_orig;
+
+ mrb_get_args(mrb, "o", &orig);
+ fptr_copy = (struct mrb_io *)DATA_PTR(copy);
+ if (fptr_copy != NULL) {
+ fptr_finalize(mrb, fptr_copy, FALSE);
+ mrb_free(mrb, fptr_copy);
+ }
+ fptr_copy = (struct mrb_io *)mrb_io_alloc(mrb);
+ fptr_orig = io_get_open_fptr(mrb, orig);
+
+ buf = mrb_iv_get(mrb, orig, mrb_intern_cstr(mrb, "@buf"));
+ mrb_iv_set(mrb, copy, mrb_intern_cstr(mrb, "@buf"), buf);
+
+ fptr_copy->fd = mrb_dup(mrb, fptr_orig->fd);
+ fptr_copy->fd2 = mrb_dup(mrb, fptr_orig->fd2);
+ fptr_copy->pid = fptr_orig->pid;
+ fptr_copy->readable = fptr_orig->readable;
+ fptr_copy->writable = fptr_orig->writable;
+ fptr_copy->sync = fptr_orig->sync;
+ fptr_copy->is_socket = fptr_orig->is_socket;
+
+ DATA_TYPE(copy) = &mrb_io_type;
+ DATA_PTR(copy) = fptr_copy;
+
+ return copy;
+}
+
mrb_value
mrb_io_initialize(mrb_state *mrb, mrb_value io)
{
@@ -1238,6 +1286,7 @@ mrb_init_io(mrb_state *mrb)
#endif
mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ANY()); /* 15.2.20.5.21 (x)*/
+ mrb_define_method(mrb, io, "initialize_copy", mrb_io_initialize_copy, MRB_ARGS_REQ(1));
mrb_define_method(mrb, io, "_check_readable", mrb_io_check_readable, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "isatty", mrb_io_isatty, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "sync", mrb_io_sync, MRB_ARGS_NONE());