diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-12-14 04:36:14 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-12-14 04:36:14 +0000 |
commit | dcca25f003df9fee9ce5f4e4172fe556be158aff (patch) | |
tree | 4b09ddde7e76b7b8b5576503c878ffb2d9eb862e | |
parent | cba0d62d9119a6722a18b092fab070d4b3946674 (diff) | |
download | ruby-dcca25f003df9fee9ce5f4e4172fe556be158aff.tar.gz |
* ext/zlib/zlib.c (gzfile_s_open): should close the IO if some error
occurs in initilizing.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30203 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | ext/zlib/zlib.c | 53 |
2 files changed, 49 insertions, 9 deletions
@@ -1,3 +1,8 @@ +Tue Dec 14 13:34:33 2010 NAKAMURA Usaku <usa@ruby-lang.org> + + * ext/zlib/zlib.c (gzfile_s_open): should close the IO if some error + occurs in initilizing. + Tue Dec 14 13:04:16 2010 NARUSE, Yui <naruse@ruby-lang.org> * lib/net/http.rb (Net::HTTPRequest#send_request_body_data): diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 970b85713e..3dd5699bdf 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -2456,6 +2456,19 @@ get_gzfile(VALUE obj) */ +typedef struct { + int argc; + VALUE *argv; + VALUE klass; +} new_wrap_arg_t; + +static VALUE +new_wrap(VALUE tmp) +{ + new_wrap_arg_t *arg = (new_wrap_arg_t *)tmp; + return rb_class_new_instance(arg->argc, arg->argv, arg->klass); +} + static VALUE gzfile_ensure_close(VALUE obj) { @@ -2468,6 +2481,35 @@ gzfile_ensure_close(VALUE obj) return Qnil; } +static VALUE +gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error) +{ + VALUE obj; + + if (close_io_on_error) { + int state = 0; + new_wrap_arg_t arg; + arg.argc = argc; + arg.argv = argv; + arg.klass = klass; + obj = rb_protect(new_wrap, (VALUE)&arg, &state); + if (state) { + rb_io_close(argv[0]); + rb_jump_tag(state); + } + } + else { + obj = rb_class_new_instance(argc, argv, klass); + } + + if (rb_block_given_p()) { + return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj); + } + else { + return obj; + } +} + /* * call-seq: Zlib::GzipFile.wrap(io) { |gz| ... } * @@ -2481,14 +2523,7 @@ gzfile_ensure_close(VALUE obj) static VALUE rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass) { - VALUE obj = rb_class_new_instance(argc, argv, klass); - - if (rb_block_given_p()) { - return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj); - } - else { - return obj; - } + return gzfile_wrap(argc, argv, klass, 0); } /* @@ -2505,7 +2540,7 @@ gzfile_s_open(int argc, VALUE *argv, VALUE klass, const char *mode) filename = argv[0]; io = rb_file_open_str(filename, mode); argv[0] = io; - return rb_gzfile_s_wrap(argc, argv, klass); + return gzfile_wrap(argc, argv, klass, 1); } /* |