ruby-changes:37583
From: nobu <ko1@a...>
Date: Fri, 20 Feb 2015 17:27:21 +0900 (JST)
Subject: [ruby-changes:37583] nobu:r49664 (trunk): file.c: fix handle leak
nobu 2015-02-20 17:27:14 +0900 (Fri, 20 Feb 2015) New Revision: 49664 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=49664 Log: file.c: fix handle leak * file.c (rb_file_identical_p): fix handle leak, ensure to close the handle of the first argument. Modified files: trunk/ChangeLog trunk/file.c trunk/test/ruby/test_file_exhaustive.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 49663) +++ ChangeLog (revision 49664) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Feb 20 17:27:12 2015 Nobuyoshi Nakada <nobu@r...> + + * file.c (rb_file_identical_p): fix handle leak, ensure to close + the handle of the first argument. + Fri Feb 20 17:19:23 2015 Nobuyoshi Nakada <nobu@r...> * win32/win32.c (different_device_p): compare by volume serial Index: test/ruby/test_file_exhaustive.rb =================================================================== --- test/ruby/test_file_exhaustive.rb (revision 49663) +++ test/ruby/test_file_exhaustive.rb (revision 49664) @@ -311,6 +311,8 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/ruby/test_file_exhaustive.rb#L311 assert_raise(IOError) { File.identical?(@file, io) } + File.unlink(@file) + assert_file.not_exist?(@file) end def test_s_size Index: file.c =================================================================== --- file.c (revision 49663) +++ file.c (revision 49664) @@ -1053,6 +1053,25 @@ w32_io_info(VALUE *file, BY_HANDLE_FILE_ https://github.com/ruby/ruby/blob/trunk/file.c#L1053 if (ret) CloseHandle(ret); return INVALID_HANDLE_VALUE; } + +static VALUE +close_handle(VALUE h) +{ + CloseHandle((HANDLE)h); + return Qfalse; +} + +struct w32_io_info_args { + VALUE *fname; + BY_HANDLE_FILE_INFORMATION *st; +}; + +static VALUE +call_w32_io_info(VALUE arg) +{ + struct w32_io_info_args *p = (void *)arg; + return (VALUE)w32_io_info(p->fname, p->st); +} #endif /* @@ -1916,8 +1935,15 @@ rb_file_identical_p(VALUE obj, VALUE fna https://github.com/ruby/ruby/blob/trunk/file.c#L1935 # ifdef _WIN32 f1 = w32_io_info(&fname1, &st1); if (f1 == INVALID_HANDLE_VALUE) return Qfalse; - f2 = w32_io_info(&fname2, &st2); - if (f1) CloseHandle(f1); + if (f1) { + struct w32_io_info_args arg; + arg.fname = &fname2; + arg.st = &st2; + f2 = (HANDLE)rb_ensure(call_w32_io_info, (VALUE)&arg, close_handle, (VALUE)f1); + } + else { + f2 = w32_io_info(&fname2, &st2); + } if (f2 == INVALID_HANDLE_VALUE) return Qfalse; if (f2) CloseHandle(f2); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/