Skip to content

Commit 213714b

Browse files
Merge pull request #7841 from rubygems/deivid-rodriguez/backport-binstubs-fix
Protect creating RubyGems binstubs with a file lock (cherry picked from commit c40def1)
1 parent b989057 commit 213714b

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

bundler/lib/bundler/rubygems_ext.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,30 @@ def self.freebsd_platform?
3030
end
3131
end
3232

33+
# Can be removed once RubyGems 3.5.14 support is dropped
34+
unless Gem.respond_to?(:open_file_with_flock)
35+
def self.open_file_with_flock(path, &block)
36+
flags = File.exist?(path) ? "r+" : "a+"
37+
38+
File.open(path, flags) do |io|
39+
begin
40+
io.flock(File::LOCK_EX)
41+
rescue Errno::ENOSYS, Errno::ENOTSUP
42+
end
43+
yield io
44+
rescue Errno::ENOLCK # NFS
45+
if Thread.main != Thread.current
46+
raise
47+
else
48+
File.open(path, flags, &block)
49+
end
50+
end
51+
end
52+
end
53+
3354
require "rubygems/specification"
3455

35-
# Can be removed once RubyGems 3.5.15 support is dropped
56+
# Can be removed once RubyGems 3.5.14 support is dropped
3657
VALIDATES_FOR_RESOLUTION = Specification.new.respond_to?(:validate_for_resolution).freeze
3758

3859
class Specification

bundler/lib/bundler/rubygems_gem_installer.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,26 @@ def generate_plugins
8181
end
8282
end
8383

84+
if Bundler.rubygems.provides?("< 3.5.15")
85+
def generate_bin_script(filename, bindir)
86+
bin_script_path = File.join bindir, formatted_program_filename(filename)
87+
88+
Gem.open_file_with_flock("#{bin_script_path}.lock") do
89+
require "fileutils"
90+
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
91+
92+
File.open(bin_script_path, "wb", 0o755) do |file|
93+
file.write app_script_text(filename)
94+
file.chmod(options[:prog_mode] || 0o755)
95+
end
96+
end
97+
98+
verbose bin_script_path
99+
100+
generate_windows_script filename, bindir
101+
end
102+
end
103+
84104
def build_extensions
85105
extension_cache_path = options[:bundler_extension_cache_path]
86106
extension_dir = spec.extension_dir

0 commit comments

Comments
 (0)