aboutsummaryrefslogtreecommitdiffstats
path: root/ext/zlib
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-12-14 04:36:14 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-12-14 04:36:14 +0000
commitdcca25f003df9fee9ce5f4e4172fe556be158aff (patch)
tree4b09ddde7e76b7b8b5576503c878ffb2d9eb862e /ext/zlib
parentcba0d62d9119a6722a18b092fab070d4b3946674 (diff)
downloadruby-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
Diffstat (limited to 'ext/zlib')
-rw-r--r--ext/zlib/zlib.c53
1 files changed, 44 insertions, 9 deletions
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);
}
/*