Skip to content

Commit 97f8cb6

Browse files
Merge pull request #7806 from rubygems/deivid-rodriguez/safe-windows-binstubs
Protect creating binstubs with a file lock (cherry picked from commit ebb535e)
1 parent 603ca33 commit 97f8cb6

File tree

2 files changed

+21
-26
lines changed

2 files changed

+21
-26
lines changed

lib/rubygems.rb

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ def self.read_binary(path)
760760

761761
##
762762
# Safely write a file in binary mode on all platforms.
763+
763764
def self.write_binary(path, data)
764765
open_file(path, "wb") do |io|
765766
io.write data
@@ -771,33 +772,30 @@ def self.write_binary(path, data)
771772
end
772773

773774
##
774-
# Open a file with given flags. It requires special logic on Windows, like
775-
# protecting access with flock
775+
# Open a file with given flags
776776

777777
def self.open_file(path, flags, &block)
778-
if !java_platform? && win_platform?
779-
open_file_with_flock(path, flags, &block)
780-
else
781-
open_file_without_flock(path, flags, &block)
782-
end
778+
File.open(path, flags, &block)
783779
end
784780

785781
##
786782
# Open a file with given flags, and protect access with flock
787783

788-
def self.open_file_with_flock(path, flags, &block)
784+
def self.open_file_with_flock(path, &block)
785+
flags = File.exist?(path) ? "r+" : "a+"
786+
789787
File.open(path, flags) do |io|
790788
begin
791789
io.flock(File::LOCK_EX)
792790
rescue Errno::ENOSYS, Errno::ENOTSUP
793791
end
794792
yield io
795-
end
796-
rescue Errno::ENOLCK # NFS
797-
if Thread.main != Thread.current
798-
raise
799-
else
800-
open_file_without_flock(path, flags, &block)
793+
rescue Errno::ENOLCK # NFS
794+
if Thread.main != Thread.current
795+
raise
796+
else
797+
open_file(path, flags, &block)
798+
end
801799
end
802800
end
803801

@@ -1297,10 +1295,6 @@ def clear_default_specs
12971295

12981296
private
12991297

1300-
def open_file_without_flock(path, flags, &block)
1301-
File.open(path, flags, &block)
1302-
end
1303-
13041298
def already_loaded?(file)
13051299
$LOADED_FEATURES.any? do |feature_path|
13061300
feature_path.end_with?(file) && default_gem_load_paths.any? {|load_path_entry| feature_path == "#{load_path_entry}/#{file}" }

lib/rubygems/installer.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def check_executable_overwrite(filename) # :nodoc:
222222
ruby_executable = false
223223
existing = nil
224224

225-
Gem.open_file_with_flock generated_bin, "rb+" do |io|
225+
File.open generated_bin, "rb" do |io|
226226
line = io.gets
227227
shebang = /^#!.*ruby/o
228228

@@ -500,8 +500,7 @@ def generate_bin # :nodoc:
500500
dir_mode = options[:prog_mode] || (mode | 0o111)
501501

502502
unless dir_mode == mode
503-
require "fileutils"
504-
FileUtils.chmod dir_mode, bin_path
503+
File.chmod dir_mode, bin_path
505504
end
506505

507506
check_executable_overwrite filename
@@ -539,12 +538,14 @@ def generate_plugins # :nodoc:
539538
def generate_bin_script(filename, bindir)
540539
bin_script_path = File.join bindir, formatted_program_filename(filename)
541540

542-
require "fileutils"
543-
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
541+
Gem.open_file_with_flock("#{bin_script_path}.lock") do
542+
require "fileutils"
543+
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
544544

545-
File.open bin_script_path, "wb", 0o755 do |file|
546-
file.print app_script_text(filename)
547-
file.chmod(options[:prog_mode] || 0o755)
545+
File.open(bin_script_path, "wb", 0o755) do |file|
546+
file.write app_script_text(filename)
547+
file.chmod(options[:prog_mode] || 0o755)
548+
end
548549
end
549550

550551
verbose bin_script_path

0 commit comments

Comments
 (0)