From 818b4ea9b16e3570b431b86da9a24a5743b29617 Mon Sep 17 00:00:00 2001 From: "NARUSE, Yui" Date: Tue, 30 Jan 2024 10:24:31 +0900 Subject: [PATCH] merge revision(s) e5a4f757bdf5dc3d8c329ddd268432f9ecc7bff6: [Backport #20086] Fix Window private file mapping unlink EACCES issue. (#9358) * Don't return early. * Add missing `mapping` assignment. * Make debug logs conditional. --- io_buffer.c | 18 ++++++++++++------ test/ruby/test_io_buffer.rb | 32 ++++++++++++++------------------ 2 files changed, 26 insertions(+), 24 deletions(-) --- io_buffer.c | 18 ++++++++++++------ test/ruby/test_io_buffer.rb | 28 ++++++++++++---------------- version.h | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/io_buffer.c b/io_buffer.c index 3c47f659bc..7e580c8633 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -42,6 +42,8 @@ enum { // This is used to validate the flags given by the user. RB_IO_BUFFER_FLAGS_MASK = RB_IO_BUFFER_EXTERNAL | RB_IO_BUFFER_INTERNAL | RB_IO_BUFFER_MAPPED | RB_IO_BUFFER_SHARED | RB_IO_BUFFER_LOCKED | RB_IO_BUFFER_PRIVATE | RB_IO_BUFFER_READONLY, + + RB_IO_BUFFER_DEBUG = 0, }; struct rb_io_buffer { @@ -113,6 +115,7 @@ io_buffer_map_file(struct rb_io_buffer *buffer, int descriptor, size_t size, rb_ } HANDLE mapping = CreateFileMapping(file, NULL, protect, 0, 0, NULL); + if (RB_IO_BUFFER_DEBUG) fprintf(stderr, "io_buffer_map_file:CreateFileMapping -> %p\n", mapping); if (!mapping) rb_sys_fail("io_buffer_map_descriptor:CreateFileMapping"); void *base = MapViewOfFile(mapping, access, (DWORD)(offset >> 32), (DWORD)(offset & 0xFFFFFFFF), size); @@ -213,9 +216,13 @@ io_buffer_initialize(VALUE self, struct rb_io_buffer *buffer, void *base, size_t buffer->size = size; buffer->flags = flags; RB_OBJ_WRITE(self, &buffer->source, source); + +#if defined(_WIN32) + buffer->mapping = NULL; +#endif } -static int +static void io_buffer_free(struct rb_io_buffer *buffer) { if (buffer->base) { @@ -247,18 +254,17 @@ io_buffer_free(struct rb_io_buffer *buffer) buffer->size = 0; buffer->flags = 0; buffer->source = Qnil; - - return 1; } #if defined(_WIN32) if (buffer->mapping) { - CloseHandle(buffer->mapping); + if (RB_IO_BUFFER_DEBUG) fprintf(stderr, "io_buffer_free:CloseHandle -> %p\n", buffer->mapping); + if (!CloseHandle(buffer->mapping)) { + fprintf(stderr, "io_buffer_free:GetLastError -> %d\n", GetLastError()); + } buffer->mapping = NULL; } #endif - - return 0; } void diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb index b4b63b1eda..321b6534ee 100644 --- a/test/ruby/test_io_buffer.rb +++ b/test/ruby/test_io_buffer.rb @@ -521,24 +521,20 @@ class TestIOBuffer < Test::Unit::TestCase def test_private Tempfile.create(%w"buffer .txt") do |file| file.write("Hello World") - file.close - assert_separately(["-W0", "-", file.path], "#{<<-"begin;"}\n#{<<-'end;'}") - begin; - file = File.open(ARGV[0], "r+") - buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::PRIVATE) - begin - assert buffer.private? - refute buffer.readonly? - buffer.set_string("J") + buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::PRIVATE) + begin + assert buffer.private? + refute buffer.readonly? - # It was not changed because the mapping was private: - file.seek(0) - assert_equal "Hello World", file.read - ensure - buffer&.free - end - end; + buffer.set_string("J") + + # It was not changed because the mapping was private: + file.seek(0) + assert_equal "Hello World", file.read + ensure + buffer&.free + end end end end diff --git a/version.h b/version.h index 3d2bc9bb28..1380a16baa 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 0 +#define RUBY_PATCHLEVEL 1 #include "ruby/version.h" #include "ruby/internal/abi.h"