diff options
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 59 |
1 files changed, 58 insertions, 1 deletions
@@ -133,7 +133,7 @@ static VALUE argf; static ID id_write, id_read, id_getc, id_flush, id_readpartial; static VALUE sym_mode, sym_perm, sym_extenc, sym_intenc, sym_encoding, sym_open_args; -static VALUE sym_textmode, sym_binmode; +static VALUE sym_textmode, sym_binmode, sym_autoclose; struct timeval rb_time_interval(VALUE); @@ -6319,6 +6319,9 @@ rb_io_stdio_file(rb_io_t *fptr) * If the value is truth value, same as "b" in argument <code>mode</code>. * :binmode :: * If the value is truth value, same as "t" in argument <code>mode</code>. + * :autoclose :: + * If the value is +false+, the _fd_ will be kept open after this + * +IO+ instance gets finalized. * * Also <code>opt</code> can have same keys in <code>String#encode</code> for * controlling conversion between the external encoding and the internal encoding. @@ -6389,6 +6392,9 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io) rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError)); } #endif + if (!NIL_P(opt) && rb_hash_aref(opt, sym_autoclose) == Qfalse) { + fmode |= FMODE_PREP; + } MakeOpenFile(io, fp); fp->fd = fd; fp->mode = fmode; @@ -6483,6 +6489,53 @@ rb_io_s_for_fd(int argc, VALUE *argv, VALUE klass) return io; } +/* + * call-seq: + * ios.autoclose? => true or false + * + * Returns +true+ if the underlying file descriptor of _ios_ will be + * closed automatically at its finalization, otherwise +false+. + */ + +static VALUE +rb_io_autoclose_p(VALUE io) +{ + rb_io_t *fptr; + rb_secure(4); + GetOpenFile(io, fptr); + return (fptr->mode & FMODE_PREP) ? Qfalse : Qtrue; +} + +/* + * call-seq: + * io.autoclose = bool => true or false + * + * Sets auto-close flag. + * + * f = open("/dev/null") + * IO.for_fd(f.fileno) + * # ... + * f.gets # may cause IOError + * + * f = open("/dev/null") + * IO.for_fd(f.fileno).autoclose = true + * # ... + * f.gets # won't cause IOError + */ + +static VALUE +rb_io_set_autoclose(VALUE io, VALUE autoclose) +{ + rb_io_t *fptr; + rb_secure(4); + GetOpenFile(io, fptr); + if (!RTEST(autoclose)) + fptr->mode |= FMODE_PREP; + else + fptr->mode &= ~FMODE_PREP; + return io; +} + static void argf_mark(void *ptr) { @@ -9803,6 +9856,9 @@ Init_IO(void) rb_define_method(rb_cIO, "internal_encoding", rb_io_internal_encoding, 0); rb_define_method(rb_cIO, "set_encoding", rb_io_set_encoding, -1); + rb_define_method(rb_cIO, "autoclose?", rb_io_autoclose_p, 0); + rb_define_method(rb_cIO, "autoclose=", rb_io_set_autoclose, 1); + rb_define_variable("$stdin", &rb_stdin); rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>"); rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter); @@ -9957,4 +10013,5 @@ Init_IO(void) sym_open_args = ID2SYM(rb_intern("open_args")); sym_textmode = ID2SYM(rb_intern("textmode")); sym_binmode = ID2SYM(rb_intern("binmode")); + sym_autoclose = ID2SYM(rb_intern("autoclose")); } |