mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
build/command.rb: route mrbc output through tempfile to avoid pipe race
The previous IO.popen capture of mrbc stdout (`-o-`) is vulnerable to a Windows MinGW race: with parallel rake (-m), stdout pipe inheritance can allow unrelated `_pp` build-progress messages from sibling worker threads to leak into the captured pipe content, corrupting the generated C file (recently seen as `CC build/...` text inside gem_test.c, causing compile errors at unrelated lines). Switch to `mrbc -o <tmpfile>` so the output is materialised in a file before merging into the destination, fully isolating mrbc from the parent's STDOUT. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -343,16 +343,21 @@ module MRuby
|
||||
opt = @compile_options % {funcname: funcname}
|
||||
opt << " -S" if cdump
|
||||
opt << " -s" if static
|
||||
# Have mrbc write to a private tempfile (-o) instead of stdout (-o-)
|
||||
# to avoid pipe-inheritance races with parallel rake on Windows MinGW,
|
||||
# where unrelated _pp build-progress lines from sibling workers can
|
||||
# leak into the captured stdout and corrupt the generated C file.
|
||||
tmpout = "#{out.path}.#{funcname}.mrbcout"
|
||||
opt = opt.sub(/\s-o-(?=\s|\z)/, %Q[ -o "#{filename tmpout}"])
|
||||
cmd = %["#{filename @command}" #{opt} #{filename(infiles).map{|f| %["#{f}"]}.join(' ')}]
|
||||
puts cmd if Rake.verbose
|
||||
IO.popen(cmd, 'r') do |io|
|
||||
out.puts io.read
|
||||
end
|
||||
# if mrbc execution fail, drop the file
|
||||
unless $?.success?
|
||||
unless system(cmd)
|
||||
rm_f tmpout
|
||||
rm_f out.path
|
||||
fail "Command failed with status (#{$?.exitstatus}): [#{cmd[0,42]}...]"
|
||||
end
|
||||
out.write File.binread(tmpout)
|
||||
rm_f tmpout
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user