Skip to content

Commit

Permalink
WindowsFile: Retrieve correct Win32 error codes
Browse files Browse the repository at this point in the history
WindowsFile calls GetLastError via win32-api to retrieve win32 error
code but the error code may be already reset by Ruby's internal code
so that it can't retrive a correct error code. Sometimes it causes
random unrecoverable errors when in_tail plugin tries to read a
non-existent file like the following:

  2021-04-14 03:15:45 +0000 [error]: #2 Fluent::Win32Error code: 158, The segment is already unlocked.: C:/path/to/log.txt

Fiddle or FFI has a method to avoid this issue:

  * Fiddle.win32_last_error
    https://ruby-doc.org/stdlib-3.0.0/libdoc/fiddle/rdoc/Fiddle.html#method-c-win32_last_error
  * FFI::LastError.winapi_error
    https://www.rubydoc.info/github/ffi/ffi/FFI/LastError#winapi_error-instance_method

We've added an equivalent method for win32-api:

  cosmo0920/win32-api#55

This commit replaces the retrieving the error code with this method.

Signed-off-by: Takuro Ashie <ashie@clear-code.com>
  • Loading branch information
ashie committed Apr 19, 2021
1 parent 8c7d674 commit a51ee09
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 1 deletion.
1 change: 1 addition & 0 deletions fluentd.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Gem::Specification.new do |gem|
fake_platform = ENV['GEM_BUILD_FAKE_PLATFORM'].to_s
gem.platform = fake_platform unless fake_platform.empty?
if /mswin|mingw/ =~ fake_platform || (/mswin|mingw/ =~ RUBY_PLATFORM && fake_platform.empty?)
gem.add_runtime_dependency("win32-api", [">= 1.10", "< 2.0.0"])
gem.add_runtime_dependency("win32-service", ["~> 2.1.5"])
gem.add_runtime_dependency("win32-ipc", ["~> 0.7.0"])
gem.add_runtime_dependency("win32-event", ["~> 0.6.3"])
Expand Down
2 changes: 1 addition & 1 deletion lib/fluent/plugin/file_wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def initialize(path, mode='r', sharemode=FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_S
@file_handle = CreateFile.call(@path, access, sharemode,
0, creationdisposition, FILE_ATTRIBUTE_NORMAL, 0)
if @file_handle == INVALID_HANDLE_VALUE
err = GetLastError.call
err = Win32::API.last_error
if err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND || err == ERROR_ACCESS_DENIED
raise Errno::ENOENT
end
Expand Down

0 comments on commit a51ee09

Please sign in to comment.