win32: Fix a handle leak in rb_w32_read_internal

One of its early returns after `setup_overlapped` did not close the event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hiroshi SHIBATAandClaude Opus 5.5 committed 2026-10-25 11:57:31 +09:00
1 parent 4cd0b82a1b
commit 764d1d3a73
5 files changed
+40
Notes: git 2026-10-25 02:58:06 +00:00

No files matched your search

+1
View File
@@ -0,0 +1 @@
handle_count.o: $(ruby_headers) $(hdrdir)/ruby/win32.h
+4
View File
@@ -0,0 +1,4 @@
# frozen_string_literal: false
if $mingw or $mswin
create_makefile("-test-/win32/handle_count")
end
@@ -0,0 +1,16 @@
#include <ruby.h>
static VALUE
handle_count(VALUE self)
{
DWORD count;
if (!GetProcessHandleCount(GetCurrentProcess(), &count)) rb_sys_fail("GetProcessHandleCount");
return ULONG2NUM(count);
}
void
Init_handle_count(void)
{
VALUE m = rb_define_module_under(rb_define_module("Bug"), "Win32");
rb_define_module_function(m, "handle_count", handle_count, 0);
}
+18
View File
@@ -0,0 +1,18 @@
# frozen_string_literal: false
require 'test/unit'
module Bug
module Win32
class TestHandleCount < Test::Unit::TestCase
def test_read_nonblock_on_empty_pipe
require '-test-/win32/handle_count'
IO.pipe do |r, w|
r.read_nonblock(1, exception: false)
before = Bug::Win32.handle_count
1000.times {r.read_nonblock(1, exception: false)}
assert_operator(Bug::Win32.handle_count - before, :<, 100)
end
end
end
end
end if /mswin|mingw/ =~ RUBY_PLATFORM
+1
View File
@@ -7433,6 +7433,7 @@ rb_w32_read_internal(int fd, void *buf, size_t size, rb_off_t *offset)
err = GetLastError();
if (err == ERROR_NO_DATA && (_osfile(fd) & FPIPE)) {
DWORD state;
CloseHandle(ol.hEvent);
if (GetNamedPipeHandleState((HANDLE)_osfhnd(fd), &state, NULL, NULL, NULL, NULL, 0) && (state & PIPE_NOWAIT)) {
errno = EWOULDBLOCK;
}