diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-03-21 10:52:31 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-03-21 10:52:31 +0000 |
commit | ed2dd5e3f497448356205e5f965d55850e32bae6 (patch) | |
tree | b86b3a31332d1271f9af519e334bf2f4a788ecab /io.c | |
parent | daa739876f1bbd14b043a6361e9d434d324afff5 (diff) | |
download | ruby-ed2dd5e3f497448356205e5f965d55850e32bae6.tar.gz |
* io.c (rb_io_initialize): add autoclose argument to control close
at finalization. [ruby-core:26222]
* io.c (rb_io_autoclose_p, rb_io_set_autoclose): new methods.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26999 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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")); } |