├── .gitattributes ├── .github ├── FUNDING.yml ├── actions │ └── upload-binary │ │ └── action.yml └── workflows │ ├── ucrt.yml │ ├── mingw.yml_ │ └── mswin.yml ├── git_log_utc.rb ├── .gitignore ├── old_patches ├── test │ ├── test-ruby-test_gc_compact.rb.patch │ ├── r65943_ruby-test_dir.rb.patch │ ├── mkmf-base.rb.patch │ ├── rl_test-ruby-test_encoding.rb.patch │ ├── rubygems-test_gem_ext_cargo_builder.rb.patch │ ├── irb-test_locale.rb.patch │ ├── drb-test_drbobject.rb.patch │ ├── ruby-test_native_fiber.patch │ ├── resolv-test_dns.rb.patch │ ├── irb-test_command.rb.patch │ ├── irb-test-command.patch │ ├── net-http-test_https.rb.patch │ ├── win32ole-test_win32ole.rb.patch │ ├── rdoc_all.patch │ └── net_openssl_ctx.rb.patch ├── common.mk.patch ├── unicode.org.patch ├── post_config │ └── config.h.patch ├── all │ ├── gems.rb-power-assert.patch │ └── gems-bundled_gems.patch ├── mswin │ └── gem-bundled_gems-rbs.patch ├── msys2 │ ├── gem-bundled_gems-rbs.patch │ └── configure.ac_debug.patch ├── spec │ ├── mspec-lib-mspec-helpers.patch │ ├── ruby-command_line-rubyopt_spec.rb.patch │ ├── rl_ruby-optional-capi-thread_spec.rb.patch │ ├── ruby-core-main-using_spec.rb.patch │ ├── 64855_ruby-core-encoding-converter-search_convpath_spec.rb.patch │ ├── 65098_ruby-core-array.patch │ ├── ruby-library-socket-socket-getnameinfo_spec.rb.patch │ ├── ruby-core-file_time.patch │ ├── mspec_multi_v.patch │ └── ruby-mingw_additions.patch ├── gc.c.patch ├── _install_lib-rubygems.patch ├── __readline_warnings.patch ├── __operating_system.rb.patch ├── ssl_1.1.1e_eol.patch ├── 65470_lib-rubygems-installer.rb.patch ├── pr_2028.patch ├── 14968_28.patch ├── pr_1878.patch ├── r65962_14968_32.patch ├── tool-transcode-tblgen.rb.patch ├── 14968_28._revert_65929.patch ├── 65470_lib-rubygems.patch ├── 15310_0001-thread_pthread.c-close-race-from-UBF_TIMER-and-non-G.patch └── 14867_2018-10-29_1.patch ├── local_use ├── vcpkg_update.ps1 ├── vcpkg_first_run.ps1 ├── msys2_ucrt.ps1 └── msys2_mingw.ps1 ├── mswin ├── ruby_builtin_dlls.manifest └── ruby-exe.xml ├── patches_test ├── tool-test-init.rb.patch ├── json-test_helper.rb.patch ├── ruby-test_require_lib.rb.patch ├── did_you_mean-helper.rb.patch ├── objspace-test_objspace.rb.patch ├── ruby-test_default_gems.rb.patch ├── mkmf_from_install.patch ├── ruby-test_ast.rb.patch ├── ruby-test_process.rb.patch ├── -ext--win32-test_dln.rb.patch ├── open_port_issues.patch └── rubygems_all.patch ├── patches_install_all └── _install_lib-mkmf.rb.patch ├── patches_install_mswin ├── prelude.rb-ssl.patch ├── win32-setup.mak.patch └── win32-configure.bat.patch ├── patches_spec └── ruby-core-kernel-require_spec.rb.patch ├── cli_test_bash ├── LICENSE ├── local.ps1.sample ├── set_vcvars_env.ps1 ├── manifest_mingw.xml ├── 1_1_pre_build.rb ├── patches_install_msys2 ├── _install_win32-ruby.manifest.patch └── 0001-Add-C-ext-win32-dll_directory-as-an-alternative-to-f.patch ├── 1_4_post_install_bin_files.rb ├── patches_basic_boot ├── bootstraptest.patch └── basictest.patch ├── apply_patches_only.ps1 ├── README.md ├── 1_2_post_install_common.rb ├── Local-Use.md ├── patches_ri2 └── msys2_installation.rb.patch_ ├── 1_0_build_install_mswin.ps1 ├── 1_2_post_install.rb ├── 1_3_post_install.rb ├── trunk_msys2.ps1 └── 1_0_build_install_msys2_64.ps1 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text eol=lf 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: MSP-Greg 4 | -------------------------------------------------------------------------------- /git_log_utc.rb: -------------------------------------------------------------------------------- 1 | begin 2 | info = %x[git log -n1 --pretty=format:"%H%n%ct%n%s"].split "\n" 3 | time = Time.at(info[1].to_i).utc 4 | out = "\nRuby Commit\n#{info[0]}\n #{time}\n #{info[2]}\n" 5 | STDOUT.syswrite out 6 | end 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /git 3 | /install/ 4 | /ruby-mingw/ 5 | /ruby-mswin/ 6 | /ruby-ucrt/ 7 | /ruby 8 | /rubyinstaller2 9 | /ruby_readline 10 | /zips 11 | .downloaded-cache/ 12 | 13 | *.txt 14 | *.log 15 | *.7z 16 | 17 | local.ps1 18 | /z_testing.rb 19 | temp_*.ps1 20 | 21 | -------------------------------------------------------------------------------- /.github/actions/upload-binary/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Upload Ruby binary' 2 | description: 'Upload Ruby binary' 3 | author: 'MSP-Greg' 4 | inputs: 5 | ruby_path: 6 | description: 'path to ruby root folder (TOPDIR)' 7 | default: '' 8 | runs: 9 | using: 'node20' 10 | main: 'index.js' 11 | -------------------------------------------------------------------------------- /old_patches/test/test-ruby-test_gc_compact.rb.patch: -------------------------------------------------------------------------------- 1 | # bypass return to test 2 | diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb 3 | index d2b2c1bb47..6e0867a7d3 100644 4 | --- a/test/ruby/test_gc_compact.rb 5 | +++ b/test/ruby/test_gc_compact.rb 6 | @@ -2,7 +2,7 @@ 7 | require 'test/unit' 8 | require 'fiddle' 9 | 10 | -return 11 | +# return 12 | 13 | class TestGCCompact < Test::Unit::TestCase 14 | def memory_location(obj) 15 | -------------------------------------------------------------------------------- /old_patches/common.mk.patch: -------------------------------------------------------------------------------- 1 | diff --git a/common.mk b/common.mk 2 | index 6377bd9940..bb7203dacb 100644 3 | --- a/common.mk 4 | +++ b/common.mk 5 | @@ -19,7 +19,7 @@ enable_shared = $(ENABLE_SHARED:no=) 6 | 7 | UNICODE_VERSION = 12.1.0 8 | UNICODE_EMOJI_VERSION = 12.0 9 | -UNICODE_BETA = YES 10 | +UNICODE_BETA = NO 11 | 12 | ### set the following environment variable or uncomment the line if 13 | ### the Unicode data files should be updated completely on every update ('make up',...). 14 | -------------------------------------------------------------------------------- /local_use/vcpkg_update.ps1: -------------------------------------------------------------------------------- 1 | # Updates Microsoft/vcpkg packages needed to build Ruby must be run from 2 | # the base Microsoft/vcpkg folder, typically C:/vcpkg 3 | # remember to update the repo with 'git pull' 4 | 5 | if (Test-Path -Path vcpkg.exe -PathType Leaf ) { 6 | $vcpkg_depends = 'libffi libyaml openssl readline-win32 zlib' 7 | ./bootstrap-vcpkg.bat 8 | ./vcpkg upgrade --no-dry-run --triplet=x64-windows $vcpkg_depends.split(' ') 9 | } else { 10 | echo "`nMust start from vcpkg install folder, typically C:/vcpkg`n" 11 | } 12 | -------------------------------------------------------------------------------- /mswin/ruby_builtin_dlls.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /local_use/vcpkg_first_run.ps1: -------------------------------------------------------------------------------- 1 | # Installs (first run) Microsoft/vcpkg packages needed to build Ruby must be run 2 | # from the base Microsoft/vcpkg folder, typically C:/vcpkg 3 | # remember to update the repo with 'git pull' 4 | 5 | if (Test-Path -Path vcpkg.exe -PathType Leaf ) { 6 | $vcpkg_depends = 'libffi libyaml openssl readline-win32 zlib' 7 | ./bootstrap-vcpkg.bat 8 | ./vcpkg install --triplet=x64-windows $vcpkg_depends.split(' ') 9 | } else { 10 | echo "`nMust start from vcpkg install folder, typically C:/vcpkg`n" 11 | } 12 | -------------------------------------------------------------------------------- /patches_test/tool-test-init.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/tool/test/init.rb b/tool/test/init.rb 2 | index 3fd1419a9c..e780a7ebb9 100644 3 | --- a/tool/test/init.rb 4 | +++ b/tool/test/init.rb 5 | @@ -6,9 +6,9 @@ 6 | # Preserve the gem environment prepared by tool/runruby.rb for test-tool, which uses bundled gems. 7 | ENV["BUNDLED_#{gem_env}"] = ENV[gem_env] 8 | 9 | - ENV[gem_env] = "".freeze 10 | + # ENV[gem_env] = "".freeze 11 | end 12 | -ENV["GEM_SKIP"] = "".freeze 13 | +# ENV["GEM_SKIP"] = "".freeze 14 | 15 | ENV.delete("RUBY_CODESIGN") 16 | 17 | -------------------------------------------------------------------------------- /patches_test/json-test_helper.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/json/test_helper.rb b/test/json/test_helper.rb 2 | index 24cde4348c..8cde5725f5 100644 3 | --- a/test/json/test_helper.rb 4 | +++ b/test/json/test_helper.rb 5 | @@ -1,4 +1,4 @@ 6 | -$LOAD_PATH.unshift(File.expand_path('../../../ext', __FILE__), File.expand_path('../../../lib', __FILE__)) 7 | +# $LOAD_PATH.unshift(File.expand_path('../../../ext', __FILE__), File.expand_path('../../../lib', __FILE__)) 8 | 9 | if ENV["JSON_COVERAGE"] 10 | # This test helper is loaded inside Ruby's own test suite, so we try to not mess it up. 11 | -------------------------------------------------------------------------------- /old_patches/unicode.org.patch: -------------------------------------------------------------------------------- 1 | diff --git a/tool/downloader.rb b/tool/downloader.rb 2 | index 77eab26f63..35e5d92e5c 100644 3 | --- a/tool/downloader.rb 4 | +++ b/tool/downloader.rb 5 | @@ -71,7 +71,7 @@ def self.download(name, dir = nil, since = true, options = {}) 6 | 7 | class Unicode < self 8 | INDEX = {} # cache index file information across files in the same directory 9 | - UNICODE_PUBLIC = "http://www.unicode.org/Public/" 10 | + UNICODE_PUBLIC = "https://www.unicode.org/Public/" 11 | 12 | def self.download(name, dir = nil, since = true, options = {}) 13 | options = options.dup 14 | -------------------------------------------------------------------------------- /old_patches/post_config/config.h.patch: -------------------------------------------------------------------------------- 1 | diff --git a/config.h b/config_b.h 2 | index 4c97795..151908e 100644 3 | --- a/.ext/include/x64-mingw32/ruby/config.h 4 | +++ b/.ext/include/x64-mingw32/ruby/config.h 5 | @@ -288,8 +288,8 @@ 6 | #define LIBDIR_BASENAME "lib" 7 | #define EXECUTABLE_EXTS ".exe",".com",".cmd",".bat" 8 | #define HAVE__SETJMPEX 1 9 | -#define RUBY_SETJMP(env) setjmpex((env)) 10 | -#define RUBY_LONGJMP(env,val) longjmp((env),val) 11 | +#define RUBY_SETJMP(env) __builtin_setjmp((env)) 12 | +#define RUBY_LONGJMP(env,val) __builtin_longjmp((env),val) 13 | #define RUBY_JMP_BUF jmp_buf 14 | #define RUBY_USE_SETJMPEX 1 15 | #define USE_MJIT 1 16 | -------------------------------------------------------------------------------- /old_patches/test/r65943_ruby-test_dir.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/ruby/test_dir.rb b/test/ruby/test_dir.rb 2 | index e3dcd7fef4..e248c818b6 100644 3 | --- a/test/ruby/test_dir.rb 4 | +++ b/test/ruby/test_dir.rb 5 | @@ -377,8 +377,9 @@ def test_home 6 | assert_equal(@nodir, Dir.home("")) 7 | end 8 | if user = ENV["USER"] 9 | + tilde = windows? ? "~" : "~#{user}" 10 | assert_nothing_raised(ArgumentError) do 11 | - assert_equal(File.expand_path("~#{user}"), Dir.home(user)) 12 | + assert_equal(File.expand_path(tilde), Dir.home(user)) 13 | end 14 | end 15 | %W[no:such:user \u{7559 5b88}:\u{756a}].each do |user| 16 | -------------------------------------------------------------------------------- /old_patches/test/mkmf-base.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | allows running tests from standard ruby install 3 | diff --git a/test/mkmf/base.rb b/test/mkmf/base.rb 4 | index 80dec1421a..5c787b1f8e 100644 5 | --- a/test/mkmf/base.rb 6 | +++ b/test/mkmf/base.rb 7 | @@ -1,13 +1,5 @@ 8 | # frozen_string_literal: false 9 | -$extmk = true 10 | -require 'rbconfig' 11 | -RbConfig.fire_update!("top_srcdir", File.expand_path("../..", __dir__)) 12 | -File.foreach(RbConfig::CONFIG["topdir"]+"/Makefile") do |line| 13 | - if /^CC_WRAPPER\s*=\s*/ =~ line 14 | - RbConfig.fire_update!('CC_WRAPPER', $'.strip) 15 | - break 16 | - end 17 | -end 18 | +$extmk = false 19 | 20 | require 'test/unit' 21 | require 'mkmf' 22 | -------------------------------------------------------------------------------- /patches_test/ruby-test_require_lib.rb.patch: -------------------------------------------------------------------------------- 1 | # load files from install, not src 2 | diff --git a/test/ruby/test_require_lib.rb b/test/ruby/test_require_lib.rb 3 | index a88279727e..92f67f453d 100644 4 | --- a/test/ruby/test_require_lib.rb 5 | +++ b/test/ruby/test_require_lib.rb 6 | @@ -1,8 +1,11 @@ 7 | # frozen_string_literal: true 8 | require 'test/unit' 9 | +require 'rbconfig' 10 | 11 | class TestRequireLib < Test::Unit::TestCase 12 | - libdir = __dir__ + '/../../lib' 13 | + 14 | + temp = RbConfig::CONFIG['rubylibdir'] 15 | + libdir = Dir.exist?(temp) ? temp : (__dir__ + '/../../lib') 16 | 17 | # .rb files at lib 18 | scripts = Dir.glob('*.rb', base: libdir).map {|f| f.chomp('.rb')} 19 | -------------------------------------------------------------------------------- /patches_install_all/_install_lib-mkmf.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/mkmf.rb b/lib/mkmf.rb 2 | index 73459ffeb9..e9a92703e0 100644 3 | --- a/lib/mkmf.rb 4 | +++ b/lib/mkmf.rb 5 | @@ -248,6 +248,10 @@ def map_dir(dir, map = nil) 6 | elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include") + "/ruby.h") 7 | $topdir ||= RbConfig::CONFIG["topdir"] 8 | $arch_hdrdir = "$(extout)/include/$(arch)" 9 | + elsif File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h") 10 | + $extmk = false 11 | + $topdir = $top_srcdir = $hdrdir 12 | + $arch_hdrdir = RbConfig::CONFIG["rubyarchhdrdir"] 13 | else 14 | abort < e 15 | +end 16 | + 17 | class Binding 18 | # :nodoc: 19 | def irb(...) 20 | -------------------------------------------------------------------------------- /patches_spec/ruby-core-kernel-require_spec.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/spec/ruby/core/kernel/require_spec.rb b/spec/ruby/core/kernel/require_spec.rb 2 | index 81777c5313..b17482e079 100644 3 | --- a/spec/ruby/core/kernel/require_spec.rb 4 | +++ b/spec/ruby/core/kernel/require_spec.rb 5 | @@ -27,7 +27,9 @@ 6 | features = out.lines.map { |line| File.basename(line.chomp, '.*') } 7 | 8 | # Ignore CRuby internals 9 | - features -= %w[encdb transdb windows_1252 windows_31j] 10 | + # mswin will load rbconfig 11 | + features -= RUBY_PLATFORM.include?('mswin') ? 12 | + %w[encdb transdb windows_1252 windows_31j rbconfig] : %w[encdb transdb windows_1252 windows_31j] 13 | features.reject! { |feature| feature.end_with?('-fake') } 14 | 15 | features.sort.should == provided.sort 16 | -------------------------------------------------------------------------------- /local_use/msys2_ucrt.ps1: -------------------------------------------------------------------------------- 1 | # Install/Update msys2 and ucrt packages needed to build Ruby 2 | # must be run from the base MSYS2 folder, typically C:/msys64 3 | 4 | if (Test-Path -Path ./usr/bin/pacman.exe -PathType Leaf ) { 5 | $msys2_pkgs = 'autoconf-wrapper autogen automake-wrapper bison diffutils libtool m4 make patch re2c texinfo texinfo-tex compression' 6 | $gcc_depends = '__make __pkgconf __libmangle-git __tools-git __gcc __gmp __libffi __libyaml __openssl __ragel __readline' 7 | 8 | $pre = 'mingw-w64-ucrt-x86_64-' 9 | 10 | ./usr/bin/pacman.exe -Syuu --needed 11 | ./usr/bin/pacman.exe -S --noconfirm --needed $msys2_pkgs.split(' ') 12 | ./usr/bin/pacman.exe -S --noconfirm --needed $gcc_depends.replace('__', $pre).split(' ') 13 | } else { 14 | echo "`nMust start from MSYS2 install folder, typically C:/msys64`n" 15 | } 16 | -------------------------------------------------------------------------------- /patches_test/objspace-test_objspace.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb 2 | index 4e09fe1af7..e1d988ed16 100644 3 | --- a/test/objspace/test_objspace.rb 4 | +++ b/test/objspace/test_objspace.rb 5 | @@ -141,7 +141,8 @@ def test_reachable_objects_from 6 | end 7 | 8 | def test_reachable_objects_during_iteration 9 | - omit 'flaky on Visual Studio with: [BUG] Unnormalized Fixnum value' if /mswin/ =~ RUBY_PLATFORM 10 | + omit 'flaky on Visual Studio with: [BUG] Unnormalized Fixnum value' if RUBY_PLATFORM.include?('mswin') 11 | + omit 'Skipped on mingw, intermittent failure' if ENV.key?('CI') && RUBY_PLATFORM.include?('mingw') 12 | opts = %w[--disable-gem --disable=frozen-string-literal -robjspace] 13 | assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}" 14 | begin; 15 | -------------------------------------------------------------------------------- /old_patches/spec/ruby-command_line-rubyopt_spec.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/spec/ruby/command_line/rubyopt_spec.rb b/spec/ruby/command_line/rubyopt_spec.rb 2 | index 18a5959b18..734db8d519 100644 3 | --- a/spec/ruby/command_line/rubyopt_spec.rb 4 | +++ b/spec/ruby/command_line/rubyopt_spec.rb 5 | @@ -25,12 +25,12 @@ 6 | guard -> { not CROSS_COMPILING } do 7 | it "prints the version number for '-v'" do 8 | ENV["RUBYOPT"] = '-v' 9 | - ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") 10 | + ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION 11 | end 12 | 13 | it "ignores whitespace around the option" do 14 | ENV["RUBYOPT"] = ' -v ' 15 | - ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") 16 | + ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /old_patches/msys2/configure.ac_debug.patch: -------------------------------------------------------------------------------- 1 | diff --git a/configure.ac b/configure.ac 2 | index ae560297ad..082ef467d7 100644 3 | --- a/configure.ac 4 | +++ b/configure.ac 5 | @@ -880,8 +880,8 @@ AS_IF([test "$GCC" = yes], [ 6 | # suppress annoying -Wstrict-overflow warnings 7 | RUBY_TRY_CFLAGS(-fno-strict-overflow, [RUBY_APPEND_OPTION(XCFLAGS, -fno-strict-overflow)]) 8 | 9 | - test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb3, [debugflags=-ggdb3])} 10 | - test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb, [debugflags=-ggdb])} 11 | + # test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb3, [debugflags=-ggdb3])} 12 | + # test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb, [debugflags=-ggdb])} 13 | test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-g3, [debugflags=-g3])} 14 | ]) 15 | test $ac_cv_prog_cc_g = yes && : ${debugflags=-g} 16 | -------------------------------------------------------------------------------- /old_patches/test/irb-test_locale.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/irb/test_locale.rb b/test/irb/test_locale.rb 2 | index 930a38834c..8a1f7030eb 100644 3 | --- a/test/irb/test_locale.rb 4 | +++ b/test/irb/test_locale.rb 5 | @@ -108,11 +108,13 @@ def test_load 6 | def test_find 7 | jp_local = IRB::Locale.new("ja_JP.UTF-8") 8 | path = jp_local.find("irb/error.rb") 9 | - assert_include(path, "/lib/irb/lc/ja/error.rb") 10 | + #assert_include(path, "/lib/irb/lc/ja/error.rb") 11 | + assert_include(path, "/irb/lc/ja/error.rb") 12 | 13 | en_local = IRB::Locale.new("en_US.UTF-8") 14 | path = en_local.find("irb/error.rb") 15 | - assert_include(path, "/lib/irb/lc/error.rb") 16 | + #assert_include(path, "/lib/irb/lc/error.rb") 17 | + assert_include(path, "/irb/lc/error.rb") 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /old_patches/spec/rl_ruby-optional-capi-thread_spec.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/spec/ruby/optional/capi/thread_spec.rb b/spec/ruby/optional/capi/thread_spec.rb 2 | index 8ff5b48536..dca2112397 100644 3 | --- a/spec/ruby/optional/capi/thread_spec.rb 4 | +++ b/spec/ruby/optional/capi/thread_spec.rb 5 | @@ -120,7 +120,7 @@ def call_capi_rb_thread_wakeup 6 | # Make sure it stopped and we got a proper value 7 | thr.value.should be_true 8 | end 9 | - 10 | +=begin 11 | it "runs a C function with the global lock unlocked and unlocks IO with the generic RUBY_UBF_IO" do 12 | thr = Thread.new do 13 | @t.rb_thread_call_without_gvl_with_ubf_io 14 | @@ -139,5 +139,6 @@ def call_capi_rb_thread_wakeup 15 | # Make sure it stopped and we got a proper value 16 | thr.value.should be_true 17 | end 18 | +=end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /patches_install_mswin/win32-setup.mak.patch: -------------------------------------------------------------------------------- 1 | diff --git a/win32/setup.mak b/win32/setup.mak 2 | index 275ccda3bb..738ac3cbcf 100644 3 | --- a/win32/setup.mak 4 | +++ b/win32/setup.mak 5 | @@ -22,7 +22,7 @@ MAKE = $(MAKE) -f $(MAKEFILE) 6 | MAKEFILE = Makefile 7 | !endif 8 | CPU = PROCESSOR_LEVEL 9 | -CC = $(CC) -nologo 10 | +CC = $(CC) -nologo $(XINCFLAGS) 11 | CPP = $(CC) -EP 12 | 13 | all: -prologue- -generic- -epilogue- 14 | @@ -188,7 +188,10 @@ echo TEENY = RUBY_VERSION_TEENY 15 | echo ABI_VERSION = RUBY_ABI_VERSION 16 | #endif 17 | set /a MSC_VER = _MSC_VER 18 | -#if _MSC_VER >= 1920 19 | +#if _MSC_VER >= 1940 20 | +set /a MSC_VER_LOWER = (MSC_VER-20)/20*20+0 21 | +set /a MSC_VER_UPPER = MSC_VER/20*20+19 22 | +#elif _MSC_VER >= 1920 23 | set /a MSC_VER_LOWER = MSC_VER/20*20+0 24 | set /a MSC_VER_UPPER = MSC_VER/20*20+19 25 | #elif _MSC_VER >= 1900 26 | -------------------------------------------------------------------------------- /local_use/msys2_mingw.ps1: -------------------------------------------------------------------------------- 1 | # Install/Update msys2 and mingw packages needed to build Ruby 2 | # must be run from the base MSYS2 folder, typically C:/msys64 3 | 4 | if (Test-Path -Path ./usr/bin/pacman.exe -PathType Leaf ) { 5 | $msys2_pkgs = 'autoconf-wrapper autogen automake-wrapper bison diffutils libtool m4 make patch re2c texinfo texinfo-tex compression' 6 | $gcc_depends = '__make __pkgconf __libmangle-git __tools-git __gcc __gmp __libffi __libyaml __openssl __ragel __readline' 7 | 8 | $pre = 'mingw-w64-x86_64-' 9 | 10 | ./usr/bin/pacman.exe -Syuu --needed --noprogressbar 11 | ./usr/bin/pacman.exe -S --noconfirm --needed --noprogressbar $msys2_pkgs.split(' ') 12 | ./usr/bin/pacman.exe -S --noconfirm --needed --noprogressbar $gcc_depends.replace('__', $pre).split(' ') 13 | } else { 14 | echo "`nMust start from MSYS2 install folder, typically C:/msys64`n" 15 | } 16 | -------------------------------------------------------------------------------- /old_patches/test/drb-test_drbobject.rb.patch: -------------------------------------------------------------------------------- 1 | # Added for conflict with ruby/test_gc_compact.rb 2 | # see https://bugs.ruby-lang.org/issues/15809 3 | diff --git a/test/drb/test_drbobject.rb b/test/drb/test_drbobject.rb 4 | index 16b252d3ce..2f8329d4c0 100644 5 | --- a/test/drb/test_drbobject.rb 6 | +++ b/test/drb/test_drbobject.rb 7 | @@ -31,6 +31,7 @@ def test_DRbObject_id_dereference 8 | end 9 | end 10 | 11 | +module DRbTests 12 | class TestDRbObject < Test::Unit::TestCase 13 | include DRbObjectTest 14 | 15 | @@ -43,7 +44,7 @@ class TestDRbObjectTimerIdConv < Test::Unit::TestCase 16 | include DRbObjectTest 17 | 18 | def setup 19 | - DRb.start_service(nil, nil, {:idconv => DRb::TimerIdConv.new}) 20 | + DRb.start_service(nil, nil, {:idconv => DRb::TimerIdConv.new(0.2)}) 21 | end 22 | end 23 | 24 | @@ -54,3 +55,4 @@ def setup 25 | DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new}) 26 | end 27 | end 28 | +end 29 | -------------------------------------------------------------------------------- /old_patches/test/ruby-test_native_fiber.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | native-fiber related? 3 | diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb 4 | index c56e280e06..1c161c006c 100644 5 | --- a/test/ruby/test_enum.rb 6 | +++ b/test/ruby/test_enum.rb 7 | @@ -612,6 +612,7 @@ def test_each_cons 8 | end 9 | 10 | def test_zip 11 | + skip "Windows MinGW native fiber 2018-11-20" if mingw? 12 | assert_equal([[1,1],[2,2],[3,3],[1,1],[2,2]], @obj.zip(@obj)) 13 | assert_equal([["a",1],["b",2],["c",3]], ["a", "b", "c"].zip(@obj)) 14 | 15 | diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb 16 | index 0839c2c3dd..892633a470 100644 17 | --- a/test/ruby/test_enumerator.rb 18 | +++ b/test/ruby/test_enumerator.rb 19 | @@ -258,6 +258,7 @@ def o.each 20 | end 21 | 22 | def test_peek_values 23 | + skip "Windows MinGW native fiber 2018-11-20" if mingw? 24 | o = Object.new 25 | def o.each 26 | yield 27 | -------------------------------------------------------------------------------- /patches_install_mswin/win32-configure.bat.patch: -------------------------------------------------------------------------------- 1 | diff --git a/win32/configure.bat b/win32/configure.bat 2 | index bad09cd3f5..1e37fc0859 100755 3 | --- a/win32/configure.bat 4 | +++ b/win32/configure.bat 5 | @@ -8,8 +8,8 @@ for %%I in (%0) do if /%%~dpI/ == /%CD%\/ ( 6 | exit /b 999 7 | ) 8 | 9 | -set XINCFLAGS= 10 | -set XLDFLAGS= 11 | +set XINCFLAGS=-I%CD:\=/%/include 12 | +set XLDFLAGS=-libpath:%CD:\=/%/lib 13 | 14 | set conf=%0 15 | set pathlist= 16 | @@ -246,13 +246,10 @@ goto :loop ; 17 | :gmp-dir 18 | :opt-dir 19 | set opt=%~2 20 | + set opt=%opt:\=/% 21 | for %%I in (%opt:;= %) do ( 22 | - set d=%%I 23 | - call pushd %%d:/=\%% && ( 24 | - call set XINCFLAGS=%%XINCFLAGS%% -I%%CD:\=/%%/include 25 | - call set XLDFLAGS=%%XLDFLAGS%% -libpath:%%CD:\=/%%/lib 26 | - popd 27 | - ) 28 | + set XINCFLAGS=%XINCFLAGS% -I%%I/include 29 | + set XLDFLAGS=%XLDFLAGS% -libpath:%%I/lib 30 | ) 31 | :witharg 32 | echo>>%confargs% %1=%2\ 33 | -------------------------------------------------------------------------------- /old_patches/test/resolv-test_dns.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | Skip Appveyor timeout failure 3 | diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb 4 | index 669d86bd83..1a3b06cf8a 100644 5 | --- a/test/resolv/test_dns.rb 6 | +++ b/test/resolv/test_dns.rb 7 | @@ -162,10 +162,14 @@ def test_no_server 8 | # A race condition here. 9 | # Another program may use the port. 10 | # But no way to prevent it. 11 | - Timeout.timeout(5) do 12 | - Resolv::DNS.open(:nameserver_port => [[host, port]]) {|dns| 13 | - assert_equal([], dns.getresources("test-no-server.example.org", Resolv::DNS::Resource::IN::A)) 14 | - } 15 | + begin 16 | + Timeout.timeout(5) do 17 | + Resolv::DNS.open(:nameserver_port => [[host, port]]) {|dns| 18 | + assert_equal([], dns.getresources("test-no-server.example.org", Resolv::DNS::Resource::IN::A)) 19 | + } 20 | + end 21 | + rescue Timeout::Error 22 | + skip 'Timeout Error on Appveyor' 23 | end 24 | end 25 | 26 | -------------------------------------------------------------------------------- /patches_test/ruby-test_default_gems.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | uses gemspecs in ruby under test, not srcdir 3 | diff --git a/test/ruby/test_default_gems.rb b/test/ruby/test_default_gems.rb 4 | index b9de33cc78..7b93d71585 100644 5 | --- a/test/ruby/test_default_gems.rb 6 | +++ b/test/ruby/test_default_gems.rb 7 | @@ -15,10 +15,16 @@ def self.load(file) 8 | end 9 | 10 | def test_validate_gemspec 11 | - srcdir = File.expand_path('../../..', __FILE__) 12 | + if File.exist?(srcdir = File.absolute_path(File.join Gem.default_specifications_dir, '..')) 13 | + glob = "**/*.gemspec" 14 | + else 15 | + srcdir = File.expand_path('../../..', __FILE__) 16 | + glob = "{lib,ext}/**/*.gemspec" 17 | + end 18 | + 19 | specs = 0 20 | Dir.chdir(srcdir) do 21 | - all_assertions_foreach(nil, *Dir["{lib,ext}/**/*.gemspec"]) do |src| 22 | + all_assertions_foreach(nil, *Dir[glob]) do |src| 23 | specs += 1 24 | assert_kind_of(Gem::Specification, self.class.load(src), "invalid spec in #{src}") 25 | end 26 | -------------------------------------------------------------------------------- /old_patches/gc.c.patch: -------------------------------------------------------------------------------- 1 | From c19d2faa43d947e44743d08e1bd49ca76de89eee Mon Sep 17 00:00:00 2001 2 | From: Aaron Patterson 3 | Date: Fri, 17 May 2019 17:16:02 +0300 4 | Subject: [PATCH] disable allocation during compaction 5 | Ruby PR 2192 https://github.com/ruby/ruby/pull/2192 6 | diff --git a/gc.c b/gc.c 7 | index bf495bab4e28..7fc8ed309cae 100644 8 | --- a/gc.c 9 | +++ b/gc.c 10 | @@ -8252,6 +8252,8 @@ gc_verify_compaction_references(int argc, VALUE *argv, VALUE mod) 11 | /* Ensure objects are pinned */ 12 | rb_gc(); 13 | 14 | + during_gc = TRUE; 15 | + 16 | if (kwvals[1]) { 17 | /* Double heap size */ 18 | heap_add_pages(objspace, heap_eden, heap_allocated_pages); 19 | @@ -8263,6 +8265,8 @@ gc_verify_compaction_references(int argc, VALUE *argv, VALUE mod) 20 | gc_update_references(objspace); 21 | gc_check_references_for_moved(mod); 22 | 23 | + during_gc = FALSE; 24 | + 25 | rb_clear_method_cache_by_class(rb_cObject); 26 | rb_clear_constant_cache(); 27 | heap_eden->free_pages = NULL; 28 | -------------------------------------------------------------------------------- /cli_test_bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | RUBY_BIN=$(dirname "$(which ruby)") 4 | 5 | PATH=${PATH/$RUBY_BIN:/} 6 | 7 | export PATH="${PWD}/${PRE}/bin:${PATH}" 8 | 9 | error=0 10 | 11 | printf "bundle version: " 12 | bundle version 13 | error=$((error + $?)) 14 | 15 | printf "gem --version: " 16 | gem --version 17 | error=$((error + $?)) 18 | 19 | printf "irb --version: " 20 | irb --version 21 | error=$((error + $?)) 22 | 23 | printf "racc --version: " 24 | racc --version 25 | error=$((error + $?)) 26 | 27 | printf "rake --version: " 28 | rake --version 29 | error=$((error + $?)) 30 | 31 | printf "rbs --version: " 32 | rbs --version 33 | error=$((error + $?)) 34 | 35 | printf "rdbg --version: " 36 | rdbg --version 37 | error=$((error + $?)) 38 | 39 | printf "rdoc --version: " 40 | rdoc --version 41 | error=$((error + $?)) 42 | 43 | printf "test-unit --version: " 44 | test-unit --version 45 | error=$((error + $?)) 46 | 47 | printf "typeprof --version: " 48 | typeprof --version 49 | error=$((error + $?)) 50 | 51 | ruby -v 52 | 53 | if [ "$error" != 0 ]; then exit 1; fi 54 | -------------------------------------------------------------------------------- /old_patches/_install_lib-rubygems.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | allows RubyGems tests to be run from install folder 3 | diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb 4 | index cf676854dc..0ebb87909d 100644 5 | --- a/lib/rubygems/installer.rb 6 | +++ b/lib/rubygems/installer.rb 7 | @@ -709,8 +709,6 @@ def check_that_user_bin_dir_is_in_path # :nodoc: 8 | return if self.class.path_warning 9 | 10 | user_bin_dir = @bin_dir || Gem.bindir(gem_home) 11 | - user_bin_dir = user_bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR) if 12 | - File::ALT_SEPARATOR 13 | 14 | path = ENV['PATH'] 15 | if Gem.win_platform? 16 | @@ -718,6 +716,11 @@ def check_that_user_bin_dir_is_in_path # :nodoc: 17 | user_bin_dir = user_bin_dir.downcase 18 | end 19 | 20 | + if File::ALT_SEPARATOR 21 | + user_bin_dir = user_bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR) 22 | + path = path.tr(File::SEPARATOR, File::ALT_SEPARATOR) 23 | + end 24 | + 25 | path = path.split(File::PATH_SEPARATOR) 26 | 27 | unless path.include? user_bin_dir 28 | -------------------------------------------------------------------------------- /patches_test/mkmf_from_install.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/mkmf/base.rb b/test/mkmf/base.rb 2 | index ec42bca100..b0702aeb9c 100644 3 | --- a/test/mkmf/base.rb 4 | +++ b/test/mkmf/base.rb 5 | @@ -1,24 +1,16 @@ 6 | # frozen_string_literal: false 7 | -$extmk = true 8 | + 9 | require 'rbconfig' 10 | -RbConfig.fire_update!("top_srcdir", File.expand_path("../..", __dir__)) 11 | -File.foreach(RbConfig::CONFIG["topdir"]+"/Makefile") do |line| 12 | - if /^CC_WRAPPER\s*=\s*/ =~ line 13 | - RbConfig.fire_update!('CC_WRAPPER', $'.strip) 14 | - break 15 | - end 16 | + 17 | +begin 18 | + require 'devkit' 19 | +rescue LoadError 20 | end 21 | 22 | require 'test/unit' 23 | require 'mkmf' 24 | require 'tmpdir' 25 | 26 | -$extout = '$(topdir)/'+RbConfig::CONFIG["EXTOUT"] 27 | -RbConfig::CONFIG['topdir'] = CONFIG['topdir'] = File.expand_path(CONFIG['topdir']) 28 | -RbConfig::CONFIG["extout"] = CONFIG["extout"] = $extout 29 | -$INCFLAGS << " -I." 30 | -$extout_prefix = "$(extout)$(target_prefix)/" 31 | - 32 | class TestMkmf < Test::Unit::TestCase 33 | module Base 34 | MKMFLOG = proc {File.read("mkmf.log") rescue ""} 35 | -------------------------------------------------------------------------------- /old_patches/spec/ruby-core-main-using_spec.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/spec/ruby/core/main/using_spec.rb b/spec/ruby/core/main/using_spec.rb 2 | index b8e6eebc1b..1fb812f5cc 100644 3 | --- a/spec/ruby/core/main/using_spec.rb 4 | +++ b/spec/ruby/core/main/using_spec.rb 5 | @@ -2,16 +2,14 @@ 6 | require_relative 'fixtures/classes' 7 | 8 | describe "main.using" do 9 | - platform_is_not :mingw do # This is broken after TracePoint target [Feature #15289], and ko1 is fixing this 10 | - it "requires one Module argument" do 11 | - lambda do 12 | - eval('using', TOPLEVEL_BINDING) 13 | - end.should raise_error(ArgumentError) 14 | + it "requires one Module argument" do 15 | + lambda do 16 | + eval('using', TOPLEVEL_BINDING) 17 | + end.should raise_error(ArgumentError) 18 | 19 | - lambda do 20 | - eval('using "foo"', TOPLEVEL_BINDING) 21 | - end.should raise_error(TypeError) 22 | - end 23 | + lambda do 24 | + eval('using "foo"', TOPLEVEL_BINDING) 25 | + end.should raise_error(TypeError) 26 | end 27 | 28 | it "uses refinements from the given module only in the target file" do 29 | -------------------------------------------------------------------------------- /old_patches/__readline_warnings.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/rbreadline.rb b/lib/rbreadline.rb 2 | index e27e80b..8af63b7 100644 3 | --- a/lib/rbreadline.rb 4 | +++ b/lib/rbreadline.rb 5 | @@ -10,10 +10,6 @@ 6 | 7 | require "rbreadline/version" 8 | 9 | -class Integer 10 | - def ord; self; end 11 | -end 12 | - 13 | module RbReadline 14 | require 'etc' 15 | 16 | @@ -3482,7 +3478,7 @@ module RbReadline 17 | if (!@rl_byte_oriented) 18 | _rl_wrapped_multicolumn = 0 19 | if (@_rl_screenwidth < lpos + wc_width) 20 | - for i in lpos ... @_rl_screenwidth 21 | + (lpos...@_rl_screenwidth).each do |_| 22 | # The space will be removed in update_line() 23 | line[out,1] = ' ' 24 | out += 1 25 | @@ -3501,7 +3497,7 @@ module RbReadline 26 | end 27 | line[out,wc_bytes] = @rl_line_buffer[_in,wc_bytes] 28 | out += wc_bytes 29 | - for i in 0 ... wc_width 30 | + (0...wc_width).each do |_| 31 | lpos+=1 32 | if (lpos >= @_rl_screenwidth) 33 | @inv_lbreaks[newlines+=1] = out 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2020 MSP-Greg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /local.ps1.sample: -------------------------------------------------------------------------------- 1 | $global:d_msys2 = "C:/msys64" 2 | $global:d_git = "$env:ProgramFiles/Git" 3 | $global:d_vcpkg = "C:/vcpkg" 4 | # below is used by GitHub Actions and locally 5 | $env:VCPKG_INSTALLATION_ROOT = "C:/vcpkg" 6 | $global:7z = "$env:ProgramFiles/7-Zip/7z.exe".replace('\', '/') 7 | 8 | # limits parallel jobs to no more than 6 9 | $global:jobs = (([int]$env:NUMBER_OF_PROCESSORS, 6) | Measure-Object -Minimum).Minimum 10 | 11 | $global:orig_path = $env:Path 12 | 13 | if ($build_sys -eq "msys2") { 14 | $global:base_path = ("$env:ProgramFiles/7-Zip;$d_git/cmd;" + ` 15 | "$env:SystemRoot/system32;$env:ProgramFiles;$env:SystemRoot").replace('\', '/') 16 | } else { 17 | # mswin 18 | $global:vcvars = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" 19 | 20 | if (!(Test-Path -Path $vcvars -PathType Leaf )) { 21 | echo "File:`n$vcvars`ndoes not exist, please fix" 22 | exit 1 23 | } 24 | Set-VCVars-Env 25 | $global:base_path = $env:Path.replace('\', '/') 26 | $global:no_ruby_path = $base_path -replace '[^;]+?(Chocolatey|CMake|OpenSSL|Ruby|Strawberry)[^;]*;', '' 27 | } 28 | 29 | -------------------------------------------------------------------------------- /set_vcvars_env.ps1: -------------------------------------------------------------------------------- 1 | <# Code by MSP-Greg 2 | Set env when using PowerShell 3 | May sure to set $vcvars to match you local system 4 | #> 5 | 6 | #————————————————————————————————————————————————————————————————— Set-VCVars_Env 7 | # Runs MSFT vcvars.bat and changes Powershell env 8 | function Set-VCVars-Env() { 9 | $vcvars = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" 10 | # $vcvars = "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat" 11 | 12 | $data = $(iex "cmd.exe /c '`"$vcvars`" && echo QWERTY && set'") 13 | 14 | # Output 'header', skip to ENV data 15 | $idx = 1 16 | foreach ($e in $data) { 17 | if ($e.trim() -eq 'QWERTY') { break } 18 | echo $e 19 | $idx += 1 20 | } 21 | 22 | # Replace current ENV data with changes from vcvars 23 | foreach ($e in $data[$idx .. ($data.count-1)]) { 24 | $key, $val = $e -split '=', 2 25 | $old_val = [Environment]::GetEnvironmentVariable($key) 26 | if ($old_val -ne $val) { 27 | [Environment]::SetEnvironmentVariable($key, $val) 28 | } 29 | } 30 | } 31 | 32 | Set-VCVars-Env 33 | $env:MAKE = 'nmake.exe' 34 | -------------------------------------------------------------------------------- /manifest_mingw.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /old_patches/spec/64855_ruby-core-encoding-converter-search_convpath_spec.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | without the '.to_s' call, '.search_convpath' causes a silent segv... 3 | diff --git a/spec/ruby/core/encoding/converter/search_convpath_spec.rb b/spec/ruby/core/encoding/converter/search_convpath_spec.rb 4 | index 9e924da023..4913681bbb 100644 5 | --- a/spec/ruby/core/encoding/converter/search_convpath_spec.rb 6 | +++ b/spec/ruby/core/encoding/converter/search_convpath_spec.rb 7 | @@ -26,15 +26,10 @@ 8 | end 9 | 10 | it "raises an Encoding::ConverterNotFoundError if no conversion path exists" do 11 | -# lambda do 12 | -# Encoding::Converter.search_convpath( 13 | -# Encoding::ASCII_8BIT, Encoding::Emacs_Mule) 14 | -# end.should raise_error(Encoding::ConverterNotFoundError) 15 | - begin 16 | - Encoding::Converter.search_convpath(Encoding::ASCII_8BIT, Encoding::Emacs_Mule) 17 | - rescue => e 18 | - e.class.should == Encoding::ConverterNotFoundError 19 | - end 20 | + lambda do 21 | + Encoding::Converter.search_convpath( 22 | + Encoding::ASCII_8BIT.to_s, Encoding::Emacs_Mule.to_s) 23 | + end.should raise_error(Encoding::ConverterNotFoundError) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /1_1_pre_build.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # encoding: UTF-8 3 | 4 | # Code by MSP-Greg 5 | # Reads version.h and adds message to Appveyor build, updates revision.h 6 | # writes new ruby/win32/ruby.manifest file 7 | 8 | module PreBuild 9 | 10 | class << self 11 | 12 | def run 13 | abi_version = revision[/\A\d+\.\d+/].delete('.') << '0' 14 | manifest = File.read('manifest_mingw.xml', mode: 'rb').dup 15 | so_name = case ENV['MSYSTEM'] 16 | when 'UCRT64' then "x64-ucrt-ruby#{abi_version}.dll" 17 | when 'MINGW64' then "x64-msvcrt-ruby#{abi_version}.dll" 18 | else 19 | raise "Unknown ENV['MSYSTEM'] #{ENV['MSYSTEM']}" 20 | end 21 | 22 | manifest.sub! 'LIBRUBY_SO', so_name 23 | File.write 'ruby/win32/ruby.manifest', manifest, mode: 'wb' 24 | end 25 | 26 | private 27 | 28 | # returns version 29 | def revision 30 | File.open('ruby/include/ruby/version.h', 'rb:utf-8') { |f| 31 | v_data = f.read 32 | v_data[/^#define RUBY_API_VERSION_MAJOR (\d+)/, 1] + '.' + 33 | v_data[/^#define RUBY_API_VERSION_MINOR (\d+)/, 1] + '.' + 34 | v_data[/^#define RUBY_API_VERSION_TEENY (\d+)/, 1] 35 | } 36 | end 37 | end 38 | end 39 | PreBuild.run 40 | -------------------------------------------------------------------------------- /mswin/ruby-exe.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | true 7 | UTF-8 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /old_patches/__operating_system.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/operating_system.rb b/operating_system.rb 2 | index 65bd1e9..50301b9 100644 3 | --- a/operating_system.rb 4 | +++ b/operating_system.rb 5 | @@ -10,6 +10,23 @@ Gem.pre_install do |gem_installer| 6 | ['msys2_mingw_dependencies', :install_mingw_packages]].each do |metakey, func| 7 | 8 | if deps=gem_installer.spec.metadata[metakey] 9 | + if metakey == 'msys2_mingw_dependencies' 10 | + pre = RubyInstaller::Runtime.msys2_installation.mingw_package_prefix 11 | + path = RubyInstaller::Runtime.msys2_installation.msys_bin_path.gsub("\\", "/") 12 | + dep_ary = deps.split(" ") 13 | + dep_ary.each { |d| 14 | + pkg, vers = d.split('>=') 15 | + current = `#{path}/pacman -Q #{pre}-#{pkg}` 16 | + if /\A#{pre}-#{pkg}/ =~ current 17 | + puts "Found current #{current}" 18 | + # need to check for version constraint 19 | + # below dummy to remove error message 20 | + current = vers 21 | + deps = deps.sub d, '' 22 | + end 23 | + } 24 | + end 25 | + next if deps.strip.empty? 26 | begin 27 | RubyInstaller::Runtime.msys2_installation.send(func, deps.split(" "), verbose: Gem.configuration.verbose) 28 | rescue RubyInstaller::Runtime::Msys2Installation::CommandError => err 29 | -------------------------------------------------------------------------------- /old_patches/spec/65098_ruby-core-array.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | diff --git a/spec/ruby/core/array/fixtures/classes.rb b/spec/ruby/core/array/fixtures/classes.rb 3 | index 4292554724..50decfd205 100644 4 | --- a/spec/ruby/core/array/fixtures/classes.rb 5 | +++ b/spec/ruby/core/array/fixtures/classes.rb 6 | @@ -13,15 +13,11 @@ module ArraySpecs 7 | SampleCount = 1000 8 | 9 | def self.frozen_array 10 | - frozen_array = [1,2,3] 11 | - frozen_array.freeze 12 | - frozen_array 13 | + [1,2,3].freeze 14 | end 15 | 16 | def self.empty_frozen_array 17 | - frozen_array = [] 18 | - frozen_array.freeze 19 | - frozen_array 20 | + [].freeze 21 | end 22 | 23 | def self.recursive_array 24 | diff --git a/spec/ruby/core/array/reject_spec.rb b/spec/ruby/core/array/reject_spec.rb 25 | index e6e5e851b6..cbff729553 100644 26 | --- a/spec/ruby/core/array/reject_spec.rb 27 | +++ b/spec/ruby/core/array/reject_spec.rb 28 | @@ -126,10 +126,13 @@ 29 | a = [1, 2, 3, 4] 30 | begin 31 | a.reject! do |x| 32 | - return true if x == 2 33 | - raise raise StandardError, 'Oops' if x == 3 34 | + case x 35 | + when 2 then true 36 | + when 3 then raise StandardError, 'Oops' 37 | + else false 38 | + end 39 | end 40 | - rescue 41 | + rescue StandardError 42 | end 43 | 44 | a.should == [1, 3, 4] 45 | -------------------------------------------------------------------------------- /old_patches/test/irb-test_command.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb 2 | index ec2d1f92df..fb8ca31b8a 100644 3 | --- a/test/irb/test_command.rb 4 | +++ b/test/irb/test_command.rb 5 | @@ -817,6 +817,10 @@ def test_show_doc_without_rdoc 6 | end 7 | 8 | class EditTest < CommandTestCase 9 | + 10 | + # used for running tests from install folder 11 | + LIB_PATH = RbConfig::CONFIG['rubylibdir'] 12 | + 13 | def setup 14 | @original_visual = ENV["VISUAL"] 15 | @original_editor = ENV["EDITOR"] 16 | @@ -876,7 +880,7 @@ def test_edit_with_constant 17 | ) 18 | 19 | assert_empty err 20 | - assert_match(/path: .*\/lib\/irb\.rb/, out) 21 | + assert_include out, "path: #{LIB_PATH}/irb.rb" 22 | assert_match("command: ': code'", out) 23 | end 24 | 25 | @@ -886,7 +890,7 @@ def test_edit_with_class_method 26 | ) 27 | 28 | assert_empty err 29 | - assert_match(/path: .*\/lib\/irb\.rb/, out) 30 | + assert_include out, "path: #{LIB_PATH}/irb.rb" 31 | assert_match("command: ': code'", out) 32 | end 33 | 34 | @@ -896,7 +900,7 @@ def test_edit_with_instance_method 35 | ) 36 | 37 | assert_empty err 38 | - assert_match(/path: .*\/lib\/irb\.rb/, out) 39 | + assert_include out, "path: #{LIB_PATH}/irb.rb" 40 | assert_match("command: ': code'", out) 41 | end 42 | 43 | -------------------------------------------------------------------------------- /old_patches/test/irb-test-command.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/irb/command/test_custom_command.rb b/test/irb/command/test_custom_command.rb 2 | index 13f412c210..671b27a686 100644 3 | --- a/test/irb/command/test_custom_command.rb 4 | +++ b/test/irb/command/test_custom_command.rb 5 | @@ -1,5 +1,5 @@ 6 | # frozen_string_literal: true 7 | -require "irb" 8 | +# require "irb" 9 | 10 | require_relative "../helper" 11 | 12 | diff --git a/test/irb/command/test_disable_irb.rb b/test/irb/command/test_disable_irb.rb 13 | index 14a20043d5..1a3f3a3cab 100644 14 | --- a/test/irb/command/test_disable_irb.rb 15 | +++ b/test/irb/command/test_disable_irb.rb 16 | @@ -1,5 +1,5 @@ 17 | # frozen_string_literal: false 18 | -require 'irb' 19 | +# require 'irb' 20 | 21 | require_relative "../helper" 22 | 23 | diff --git a/test/irb/command/test_force_exit.rb b/test/irb/command/test_force_exit.rb 24 | index 191a786872..0f0a831337 100644 25 | --- a/test/irb/command/test_force_exit.rb 26 | +++ b/test/irb/command/test_force_exit.rb 27 | @@ -1,5 +1,5 @@ 28 | # frozen_string_literal: false 29 | -require 'irb' 30 | +# require 'irb' 31 | 32 | require_relative "../helper" 33 | 34 | diff --git a/test/irb/command/test_show_source.rb b/test/irb/command/test_show_source.rb 35 | index a4227231e4..1ae6c1250f 100644 36 | --- a/test/irb/command/test_show_source.rb 37 | +++ b/test/irb/command/test_show_source.rb 38 | @@ -1,5 +1,5 @@ 39 | # frozen_string_literal: false 40 | -require 'irb' 41 | +# require 'irb' 42 | 43 | require_relative "../helper" 44 | 45 | -------------------------------------------------------------------------------- /old_patches/ssl_1.1.1e_eol.patch: -------------------------------------------------------------------------------- 1 | diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c 2 | index 34bb636ead..8af58e33c6 100644 3 | --- a/ext/openssl/ossl_ssl.c 4 | +++ b/ext/openssl/ossl_ssl.c 5 | @@ -1896,7 +1896,17 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) 6 | rb_eof_error(); 7 | } 8 | } 9 | - /* fall through */ 10 | + /* fall through */ 11 | +#ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING 12 | + case SSL_ERROR_SSL: 13 | + /* defined for OpenSSL versions 1.1.1e and later */ 14 | + if (OpenSSL_version_num() >= 0x1010105fL && 15 | + ERR_GET_REASON(ERR_peek_last_error()) == SSL_R_UNEXPECTED_EOF_WHILE_READING) { 16 | + rb_eof_error(); 17 | + continue; 18 | + } 19 | + /* fall through */ 20 | +#endif 21 | default: 22 | ossl_raise(eSSLError, "SSL_read"); 23 | } 24 | diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb 25 | index 4598927a17..ce899ba085 100644 26 | --- a/test/openssl/test_ssl.rb 27 | +++ b/test/openssl/test_ssl.rb 28 | @@ -1398,13 +1398,8 @@ def test_npn_selected_protocol_too_long 29 | } 30 | end 31 | 32 | - def readwrite_loop_safe(ctx, ssl) 33 | - readwrite_loop(ctx, ssl) 34 | - rescue OpenSSL::SSL::SSLError 35 | - end 36 | - 37 | def test_close_after_socket_close 38 | - start_server(server_proc: method(:readwrite_loop_safe)) { |port| 39 | + start_server { |port| 40 | sock = TCPSocket.new("127.0.0.1", port) 41 | ssl = OpenSSL::SSL::SSLSocket.new(sock) 42 | ssl.connect 43 | -------------------------------------------------------------------------------- /patches_install_msys2/_install_win32-ruby.manifest.patch: -------------------------------------------------------------------------------- 1 | diff --git a/win32/ruby.manifest b/win32/ruby.manifest 2 | index 2bd495979b..b880e4ac2a 100644 3 | --- a/win32/ruby.manifest 4 | +++ b/win32/ruby.manifest 5 | @@ -1,8 +1,29 @@ 6 | 7 | - 8 | - 9 | + 10 | + 11 | 12 | true 13 | 14 | 15 | + 16 | + 17 | + 18 | + 19 | + 20 | + 21 | + 22 | + 23 | + 24 | + 25 | + 26 | + 27 | + 28 | + 29 | + 30 | + 31 | + 32 | + 33 | + 34 | + 35 | + 36 | 37 | -------------------------------------------------------------------------------- /patches_test/ruby-test_ast.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb 2 | index c7a946dec8..ce801cc334 100644 3 | --- a/test/ruby/test_ast.rb 4 | +++ b/test/ruby/test_ast.rb 5 | @@ -116,24 +116,26 @@ def validate_not_cared0(node) 6 | SRCDIR = File.expand_path("../../..", __FILE__) 7 | 8 | Dir.glob("test/**/*.rb", base: SRCDIR).each do |path| 9 | + next if path.start_with? 'test/tmp/' 10 | + 11 | define_method("test_ranges:#{path}") do 12 | helper = Helper.new("#{SRCDIR}/#{path}") 13 | helper.validate_range 14 | 15 | assert_equal([], helper.errors) 16 | + helper.instance_variable_set(:@ast, nil) 17 | + helper = nil 18 | end 19 | - end 20 | 21 | - Dir.glob("test/**/*.rb", base: SRCDIR).each do |path| 22 | define_method("test_not_cared:#{path}") do 23 | helper = Helper.new("#{SRCDIR}/#{path}") 24 | helper.validate_not_cared 25 | 26 | assert_equal([], helper.errors) 27 | + helper.instance_variable_set(:@ast, nil) 28 | + helper = nil 29 | end 30 | - end 31 | 32 | - Dir.glob("test/**/*.rb", base: SRCDIR).each do |path| 33 | define_method("test_all_tokens:#{path}") do 34 | node = EnvUtil.suppress_warning { RubyVM::AbstractSyntaxTree.parse_file("#{SRCDIR}/#{path}", keep_tokens: true) } 35 | tokens = node.all_tokens.sort_by { [_1.last[0], _1.last[1]] } 36 | @@ -158,6 +160,7 @@ def validate_not_cared0(node) 37 | assert_equal(0, beg_pos[1], "#{token_0}. #{token_1}") 38 | end 39 | end 40 | + node = nil 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /1_4_post_install_bin_files.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'fileutils' 4 | 5 | # run from build/installed Ruby 6 | module CopyBashScripts 7 | BIN_DIR = "#{RbConfig::TOPDIR}/bin" 8 | 9 | class << self 10 | 11 | def run 12 | # clean empty gem folders, needed as of 2019-10-20 13 | ary = Dir["#{Gem.dir}/gems/*"] 14 | ary.each { |d| Dir.rmdir(d) if Dir.empty?(d) } 15 | 16 | windows_script = <<~BAT 17 | @ECHO OFF 18 | @"%~dp0ruby.exe" -x "%~dpn0" %* 19 | BAT 20 | 21 | # all files in bin folder 22 | bins = Dir["#{BIN_DIR}/*"].select { |fn| File.file? fn } 23 | .reject { |fn| File.basename(fn, ".*") == 'ridk' } 24 | 25 | bash_bins = bins.select { |fn| File.extname(fn).empty? } 26 | 27 | # file permissions may not work on Windows, especially execute 28 | bash_bins.each do |fn| 29 | str = File.read(fn, mode: 'rb:UTF-8').sub(/^#![^\n]+ruby/, '#!/usr/bin/env ruby') 30 | File.write fn, str, mode: 'wb:UTF-8' 31 | end 32 | 33 | windows_bins = bins.select { |fn| File.extname(fn).match?(/\A\.bat|\A\.cmd/) } 34 | 35 | windows_bins.each do |fn| 36 | # 'gem' bash script doesn't exist 37 | bash_bin = "#{BIN_DIR}/#{File.basename fn, '.*'}" 38 | unless File.exist? bash_bin 39 | str = File.read(fn, mode: 'rb:UTF-8').sub(/^#![^\n]+ruby/, '#!/usr/bin/env ruby') 40 | File.write bash_bin, str, mode: 'wb:UTF-8' 41 | end 42 | 43 | File.write fn, windows_script, mode: 'wb:UTF-8' 44 | end 45 | end 46 | end 47 | end 48 | CopyBashScripts.run 49 | -------------------------------------------------------------------------------- /patches_test/ruby-test_process.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb 2 | index 857ceab676..6442a8b052 100644 3 | --- a/test/ruby/test_process.rb 4 | +++ b/test/ruby/test_process.rb 5 | @@ -23,6 +23,10 @@ def self.windows? 6 | return /mswin|mingw|bccwin/ =~ RUBY_PLATFORM 7 | end 8 | 9 | + def mswin? 10 | + return RUBY_PLATFORM.include?("mswin") 11 | + end 12 | + 13 | def with_tmpchdir 14 | Dir.mktmpdir {|d| 15 | d = File.realpath(d) 16 | @@ -331,7 +335,11 @@ def test_execopts_env 17 | end 18 | cmd << '-e' << 'puts ENV.keys.map{|e|e.upcase}' 19 | IO.popen(cmd) {|io| 20 | - assert_equal("PATH\n", io.read) 21 | + if mswin? 22 | + assert_includes(io.read, "PATH\n") 23 | + else 24 | + assert_equal("PATH\n", io.read) 25 | + end 26 | } 27 | 28 | IO.popen([{"FOO"=>"BAR"}, *ENVCOMMAND]) {|io| 29 | @@ -451,10 +459,19 @@ def test_execopts_unsetenv_others 30 | h = {} 31 | MANDATORY_ENVS.each {|k| e = ENV[k] and h[k] = e} 32 | IO.popen([h, *ENVCOMMAND, :unsetenv_others=>true]) {|io| 33 | - assert_equal("", io.read) 34 | + if mswin? 35 | + str = io.read.lines.reject { |l| l.include? "SSL_"}.join('').strip 36 | + assert_equal("", str) 37 | + else 38 | + assert_equal("", io.read) 39 | + end 40 | } 41 | IO.popen([h.merge("A"=>"B"), *ENVCOMMAND, :unsetenv_others=>true]) {|io| 42 | - assert_equal("A=B\n", io.read) 43 | + if mswin? 44 | + assert_includes(io.read, "A=B\n") 45 | + else 46 | + assert_equal("A=B\n", io.read) 47 | + end 48 | } 49 | end 50 | 51 | -------------------------------------------------------------------------------- /old_patches/spec/ruby-library-socket-socket-getnameinfo_spec.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | Issue errors on Appveyor intermittently, never locally... 3 | diff --git a/spec/ruby/library/socket/socket/getnameinfo_spec.rb b/spec/ruby/library/socket/socket/getnameinfo_spec.rb 4 | index fbbbcb53c5..90dba1c5c5 100644 5 | --- a/spec/ruby/library/socket/socket/getnameinfo_spec.rb 6 | +++ b/spec/ruby/library/socket/socket/getnameinfo_spec.rb 7 | @@ -96,7 +96,7 @@ def should_be_valid_dns_name(name) 8 | @hostname = SocketSpecs.hostname_reverse_lookup(ip_address) 9 | end 10 | 11 | - describe 'using a 3 element Array as the first argument' do 12 | + describe "using a #{[family_name, 21, @hostname].inspect} as the first argument" do 13 | before do 14 | @addr = [family_name, 21, @hostname] 15 | end 16 | @@ -121,10 +121,14 @@ def should_be_valid_dns_name(name) 17 | 18 | describe 'without custom flags' do 19 | it 'returns an Array containing the hostname and service name' do 20 | - array = Socket.getnameinfo(@addr) 21 | - array.should be_an_instance_of(Array) 22 | - array[0].should == @hostname 23 | - array[1].should == 'ftp' 24 | + begin 25 | + array = Socket.getnameinfo(@addr) 26 | + array.should be_an_instance_of(Array) 27 | + array[0].should include(@hostname) 28 | + array[1].should == 'ftp' 29 | + rescue SocketError => e 30 | + e.message.should =~ /sockaddr resolved to multiple nodename/ 31 | + end 32 | end 33 | 34 | it 'uses the 3rd value as the hostname if the 4th is not present' do 35 | -------------------------------------------------------------------------------- /patches_basic_boot/bootstraptest.patch: -------------------------------------------------------------------------------- 1 | diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb 2 | index a8e67f3496..99cf989f2d 100755 3 | --- a/bootstraptest/runner.rb 4 | +++ b/bootstraptest/runner.rb 5 | @@ -795,9 +795,15 @@ def assert_finish(timeout_seconds, testsrc, message = '') 6 | end 7 | if io.respond_to?(:read_nonblock) 8 | if IO.select([io], nil, nil, diff) 9 | + tries = 0 10 | begin 11 | io.read_nonblock(1024) 12 | - rescue Errno::EAGAIN, IO::WaitReadable, EOFError 13 | + rescue IO::WaitReadable 14 | + IO.select([io]) 15 | + tries += 1 16 | + break if tries > 3 17 | + retry 18 | + rescue Errno::EAGAIN, EOFError 19 | break 20 | end while true 21 | end 22 | diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb 23 | index 4e5d6d59c9..547dbc2305 100644 24 | --- a/bootstraptest/test_io.rb 25 | +++ b/bootstraptest/test_io.rb 26 | @@ -1,5 +1,5 @@ 27 | /freebsd/ =~ RUBY_PLATFORM or 28 | -assert_finish 5, %q{ 29 | +assert_finish 6, %q{ 30 | r, w = IO.pipe 31 | t1 = Thread.new { r.sysread(1) } 32 | t2 = Thread.new { r.sysread(1) } 33 | diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb 34 | index 7ff5bb4a38..801289ef6e 100644 35 | --- a/bootstraptest/test_thread.rb 36 | +++ b/bootstraptest/test_thread.rb 37 | @@ -347,7 +347,7 @@ def m 38 | 39 | assert_normal_exit %q{ 40 | Thread.new("foo", &Object.method(:class_eval)).join 41 | -}, '[ruby-dev:34128]' 42 | +}, '[ruby-dev:34128]', 'SIGSEGV' 43 | 44 | assert_equal 'ok', %q{ 45 | begin 46 | -------------------------------------------------------------------------------- /old_patches/test/net-http-test_https.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb 2 | index 6b3171d265..0c07c15d05 100644 3 | --- a/test/net/http/test_https.rb 4 | +++ b/test/net/http/test_https.rb 5 | @@ -164,21 +164,46 @@ def test_session_reuse 6 | http.finish 7 | end 8 | 9 | - def test_session_reuse_but_expire 10 | + def test_session_reuse_with_timeout 11 | # FIXME: The new_session_cb is known broken for clients in OpenSSL 1.1.0h. 12 | omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 1.1.0h') 13 | - omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 3.2.') 14 | - omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 3.3.') 15 | 16 | http = Net::HTTP.new(HOST, config("port")) 17 | http.use_ssl = true 18 | http.cert_store = TEST_STORE 19 | 20 | - http.ssl_timeout = -1 21 | + http.ssl_timeout = 2 22 | http.start 23 | http.get("/") 24 | http.finish 25 | 26 | + sleep 1 27 | + 28 | + http.start 29 | + http.get("/") 30 | + 31 | + socket = http.instance_variable_get(:@socket).io 32 | + assert_equal true, socket.session_reused? 33 | + 34 | + http.finish 35 | + end 36 | + 37 | + def test_session_reuse_with_expired_timeout 38 | + # FIXME: The new_session_cb is known broken for clients in OpenSSL 1.1.0h. 39 | + omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 1.1.0h') 40 | + 41 | + http = Net::HTTP.new(HOST, config("port")) 42 | + http.use_ssl = true 43 | + http.cert_store = TEST_STORE 44 | + 45 | + http.ssl_timeout = 1 46 | + http.start 47 | + http.get("/") 48 | + http.finish 49 | + 50 | + sleep 1.5 51 | + 52 | http.start 53 | http.get("/") 54 | 55 | -------------------------------------------------------------------------------- /old_patches/test/win32ole-test_win32ole.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/win32ole/test_win32ole.rb b/test/win32ole/test_win32ole.rb 2 | index 594830b8fa..59399244ab 100644 3 | --- a/test/win32ole/test_win32ole.rb 4 | +++ b/test/win32ole/test_win32ole.rb 5 | @@ -375,25 +375,27 @@ def test_s_codepage_changed 6 | } 7 | assert_equal(test_str.force_encoding("ascii-8bit"), str) 8 | 9 | - # This test fail if codepage 20932 (euc) is not installed. 10 | - begin 11 | - WIN32OLE.codepage = 20932 12 | - rescue WIN32OLERuntimeError 13 | - end 14 | - if (WIN32OLE.codepage == 20932) 15 | - WIN32OLE.codepage = cp 16 | - file = fso.opentextfile(fname, 2, true) 17 | + # problems with failure, ???? 18 | + unless RUBY_PLATFORM.include? 'mswin' 19 | + # This test fail if codepage 20932 (euc) is not installed. 20 | begin 21 | - file.write [164, 162].pack("c*").force_encoding("UTF-16") 22 | - ensure 23 | - file.close 24 | + WIN32OLE.codepage = 20932 25 | + rescue WIN32OLERuntimeError 26 | + end 27 | + if (WIN32OLE.codepage == 20932) 28 | + WIN32OLE.codepage = cp 29 | + file = fso.opentextfile(fname, 2, true) 30 | + begin 31 | + file.write [164, 162].pack("c*").force_encoding("UTF-16") 32 | + ensure 33 | + file.close 34 | + end 35 | + open(fname, "r:ascii-8bit") {|ifs| 36 | + str = ifs.read 37 | + } 38 | + assert_equal("\244\242", str) 39 | end 40 | - open(fname, "r:ascii-8bit") {|ifs| 41 | - str = ifs.read 42 | - } 43 | - assert_equal("\244\242", str) 44 | end 45 | - 46 | ensure 47 | WIN32OLE.codepage = cp 48 | if (File.exist?(fname)) 49 | -------------------------------------------------------------------------------- /old_patches/65470_lib-rubygems-installer.rb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb 2 | index 298a7053..96d3fafd 100644 3 | --- a/lib/rubygems/installer.rb 4 | +++ b/lib/rubygems/installer.rb 5 | @@ -771,33 +771,38 @@ TEXT 6 | # return the stub script text used to launch the true Ruby script 7 | 8 | def windows_stub_script(bindir, bin_file_name) 9 | - rb_bindir = RbConfig::CONFIG["bindir"] 10 | - # All comparisons should be case insensitive 11 | - if bindir.downcase == rb_bindir.downcase 12 | + rb_config = RbConfig::CONFIG 13 | + rb_topdir = RbConfig::TOPDIR || File.dirname(rb_config["bindir"]) 14 | + 15 | + # get ruby executable file name from RbConfig 16 | + ruby_exe = "#{rb_config['RUBY_INSTALL_NAME']}#{rb_config['EXEEXT']}" 17 | + ruby_exe = "ruby.exe" if ruby_exe.empty? 18 | + 19 | + if File.exist?(File.join bindir, ruby_exe) 20 | # stub & ruby.exe withing same folder. Portable 21 | <<-TEXT 22 | @ECHO OFF 23 | @"%~dp0ruby.exe" "%~dpn0" %* 24 | TEXT 25 | - elsif bindir.downcase.start_with?((RbConfig::TOPDIR || File.dirname(rb_bindir)).downcase) 26 | - # stub within ruby folder, but not standard bin. Not portable 27 | + elsif bindir.downcase.start_with? rb_topdir.downcase 28 | + # stub within ruby folder, but not standard bin. Portable 29 | require 'pathname' 30 | from = Pathname.new bindir 31 | - to = Pathname.new rb_bindir 32 | + to = Pathname.new "#{rb_topdir}/bin" 33 | rel = to.relative_path_from from 34 | <<-TEXT 35 | @ECHO OFF 36 | @"%~dp0#{rel}/ruby.exe" "%~dpn0" %* 37 | TEXT 38 | else 39 | - # outside ruby folder, maybe -user-install or bundler. Portable 40 | + # outside ruby folder, maybe -user-install or bundler. Portable, but ruby 41 | + # is dependent on PATH 42 | <<-TEXT 43 | @ECHO OFF 44 | @ruby.exe "%~dpn0" %* 45 | TEXT 46 | end 47 | end 48 | - 49 | ## 50 | # Builds extensions. Valid types of extensions are extconf.rb files, 51 | # configure scripts and rakefiles or mkrf_conf files. 52 | -------------------------------------------------------------------------------- /apply_patches_only.ps1: -------------------------------------------------------------------------------- 1 | <# Code by MSP-Greg 2 | Applies all patches to ruby 3 | #> 4 | 5 | #————————————————————————————————————————————————————————————————— Apply-Patches 6 | # Applies patches 7 | function Apply-Patches($p_dir) { 8 | $patch_exe = "$d_msys2/usr/bin/patch.exe" 9 | Push-Location "$d_repo/$p_dir" 10 | [string[]]$patches = Get-ChildItem -Include *.patch -Path . -Recurse | 11 | select -expand name 12 | Pop-Location 13 | Push-Location "$d_ruby" 14 | foreach ($p in $patches) { 15 | if ($p.substring(0,2) -eq "__") { continue } 16 | Write-Host $($dash * 55) $p -ForegroundColor $fc 17 | & $patch_exe -p1 -N --no-backup-if-mismatch -i "$d_repo/$p_dir/$p" 18 | } 19 | Pop-Location 20 | Write-Host '' 21 | } 22 | 23 | #————————————————————————————————————————————————————————————————— Set-Variables 24 | # set base variables, including MSYS2 location and bit related varis 25 | function Set-Variables-Local { 26 | $script:ruby_path = $(ruby.exe -e "puts RbConfig::CONFIG['bindir']").trim().replace('\', '/') 27 | $script:time_info = '' 28 | $script:time_old = $null 29 | $script:time_start = $null 30 | } 31 | 32 | #——————————————————————————————————————————————————————————————————————— Set-Env 33 | # Set ENV, including gcc flags 34 | function Set-Env { 35 | $env:path = "$ruby_path;$d_mingw;$d_repo/git/cmd;$d_msys2/usr/bin;$base_path" 36 | 37 | # used in Ruby scripts 38 | $env:D_MSYS2 = $d_msys2 39 | 40 | $env:CFLAGS = "-march=$march -mtune=generic -O3 -pipe" 41 | $env:CXXFLAGS = "-march=$march -mtune=generic -O3 -pipe" 42 | $env:CPPFLAGS = "-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048" 43 | $env:LDFLAGS = "-pipe" 44 | } 45 | 46 | #——————————————————————————————————————————————————————————————————— start build 47 | # defaults to 64 bit 48 | $script:bits = if ($args.length -eq 1 -and $args[0] -eq 32) { 32 } else { 64 } 49 | 50 | cd $PSScriptRoot 51 | 52 | . ./0_common.ps1 53 | Set-Variables 54 | Set-Variables-Local 55 | Set-Env 56 | 57 | Apply-Patches "patches" 58 | 59 | # apply patches for testing 60 | Apply-Patches "patches_basic_boot" 61 | Apply-Patches "patches_spec" 62 | Apply-Patches "patches_test" 63 | -------------------------------------------------------------------------------- /patches_test/-ext--win32-test_dln.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | Allows test to find dlntest.dll when placed in install folder 3 | diff --git a/test/-ext-/win32/test_dln.rb b/test/-ext-/win32/test_dln.rb 4 | index e8f68ac4d4..53dc07184f 100644 5 | --- a/test/-ext-/win32/test_dln.rb 6 | +++ b/test/-ext-/win32/test_dln.rb 7 | @@ -8,20 +8,22 @@ module Win32 8 | class TestDln < Test::Unit::TestCase 9 | def test_check_imported 10 | bug = '[Bug #6303]' 11 | - so = ::File.expand_path("../ext/-test-/win32/dln/dlntest.dll", ::EnvUtil.rubybin) 12 | - assert_send([::File, :file?, so]) 13 | - path = ::ENV['PATH'] 14 | - path = ::File.dirname(so) + ::File::PATH_SEPARATOR + path 15 | + unless ::File.exist? (so = ::File.join(::RbConfig::CONFIG['archdir'], '-test-/win32/dln/dlntest.dll')) 16 | + so = ::File.expand_path("../ext/-test-/win32/dln/dlntest.dll", ::EnvUtil.rubybin) 17 | + end 18 | + assert ::File.exist? so 19 | + path = "#{::File.dirname so}#{::File::PATH_SEPARATOR}#{::ENV['PATH']}" 20 | assert_in_out_err([{'PATH'=>path}, '-r-test-/win32/dln', '-eexit'], '', [], [], bug, timeout: 10) 21 | end 22 | 23 | def test_nonascii_load 24 | bug9699 = '[ruby-core:61845] [Bug #9699]' 25 | - so = "-test-/dln/empty." + ::RbConfig::CONFIG["DLEXT"] 26 | + so = "-test-/dln/empty.#{::RbConfig::CONFIG['DLEXT']}" 27 | so = $:.find {|d| d = ::File.join(d, so); break d if ::File.exist?(d)} 28 | assert_not_nil(so) 29 | ::Dir.mkdir(dir = ::File.join(testdir = ::Dir.mktmpdir("test"), "\u{30c6 30b9 30c8}")) 30 | - ::File.copy_stream(so, ::File.join(dir, ::File.basename(so))) 31 | + new_so = ::File.join(dir, ::File.basename(so)) 32 | + ::File.copy_stream(so, new_so) 33 | assert_separately(['-', bug9699, testdir, ::File.basename(so)], <<-'end;') 34 | bug, dir, so = *ARGV 35 | assert_nothing_raised(LoadError, bug) do 36 | @@ -29,9 +31,9 @@ def test_nonascii_load 37 | end 38 | end; 39 | ensure 40 | - ::File.unlink(::File.join(dir, ::File.basename(so))) rescue nil 41 | - ::Dir.rmdir(dir) rescue nil 42 | - ::Dir.rmdir(testdir) rescue nil 43 | + ::File.unlink(new_so) rescue nil 44 | + ::Dir.rmdir(dir) rescue nil 45 | + ::Dir.rmdir(testdir) rescue nil 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /old_patches/pr_2028.patch: -------------------------------------------------------------------------------- 1 | diff --git a/appveyor.yml b/appveyor.yml 2 | index 542699ce0d..1f66ed486f 100644 3 | --- a/appveyor.yml 4 | +++ b/appveyor.yml 5 | @@ -90,6 +90,11 @@ for: 6 | - nmake install-nodoc 7 | - \usr\bin\ruby -v -e "p :locale => Encoding.find('locale'), :filesystem => Encoding.find('filesystem')" 8 | test_script: 9 | + - \usr\bin\bundle --version 10 | + - \usr\bin\gem --version 11 | + - \usr\bin\irb --version 12 | + - \usr\bin\rake --version 13 | + - \usr\bin\rdoc --version 14 | - set /a JOBS=%NUMBER_OF_PROCESSORS% 15 | - nmake -l "TESTOPTS=-v -q" btest 16 | - nmake -l "TESTOPTS=-v -q" test-basic 17 | @@ -135,6 +140,13 @@ for: 18 | - mingw32-make -j%JOBS% 19 | - mingw32-make DESTDIR=../install install-nodoc 20 | test_script: 21 | + - cd ..\install 22 | + - bin\bundle --version 23 | + - bin\gem --version 24 | + - bin\irb --version 25 | + - bin\rake --version 26 | + - bin\rdoc --version 27 | + - cd ..\build 28 | - mingw32-make test 29 | - mingw32-make test-all TESTOPTS="--retry --job-status=normal --show-skip --subprocess-timeout-scale=1.5 --excludes=../ruby/test/excludes/_appveyor -j %JOBS% --exclude win32ole --exclude test_open-uri" 30 | # separately execute tests without -j which may crash worker with -j. 31 | diff --git a/lib/bundler.gemspec b/lib/bundler.gemspec 32 | index 2b2bb412d5..2847c50697 100644 33 | --- a/lib/bundler.gemspec 34 | +++ b/lib/bundler.gemspec 35 | @@ -59,6 +59,6 @@ 36 | s.files += %w[bundler.gemspec] 37 | 38 | s.bindir = "exe" 39 | - s.executables = %w[bundle bundler] 40 | + s.executables = %w[bundle bundle_ruby bundler] 41 | s.require_paths = ["lib"] 42 | end 43 | diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb 44 | index 13a897cdc5..6c99b09c52 100755 45 | --- a/tool/rbinstall.rb 46 | +++ b/tool/rbinstall.rb 47 | @@ -780,10 +780,14 @@ def install_default_gem(dir, srcdir) 48 | bin_dir = File.join(gem_dir, 'gems', full_name, gemspec.bindir) 49 | makedirs(bin_dir) 50 | 51 | + orig_cmdtype = $cmdtype 52 | + $cmdtype = nil if RUBY_PLATFORM =~ /mswin|mingw|bccwin/ 53 | + 54 | gemspec.executables.map {|exec| 55 | $script_installer.install(File.join(srcdir, 'libexec', exec), 56 | File.join(bin_dir, exec)) 57 | } 58 | + $cmdtype = orig_cmdtype 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ruby-loco 2 | 3 | [![ucrt](https://github.com/MSP-Greg/ruby-loco/workflows/ucrt/badge.svg)](https://github.com/MSP-Greg/ruby-loco/actions?query=workflow%3Acucrt) 4 | [![mswin](https://github.com/MSP-Greg/ruby-loco/workflows/mswin/badge.svg)](https://github.com/MSP-Greg/ruby-loco/actions?query=workflow%3Amswin) 5 | [![mingw](https://github.com/MSP-Greg/ruby-loco/workflows/mingw/badge.svg)](https://github.com/MSP-Greg/ruby-loco/actions?query=workflow%3Amingw) 6 | 7 | ### General 8 | 9 | This repo creates self-contained Windows Ruby master builds (mingw, ucrt and mswin), and 10 | saves them to the one [release](https://github.com/MSP-Greg/ruby-loco/releases/tag/ruby-master) 11 | in the repo. This is done three times a day. 12 | 13 | 14 | The links for the build 7z files are: 15 | 16 | mingw: https://github.com/MSP-Greg/ruby-loco/releases/download/ruby-master/ruby-mingw.7z 17 | 18 | ucrt: https://github.com/MSP-Greg/ruby-loco/releases/download/ruby-master/ruby-ucrt.7z 19 | 20 | mswin: https://github.com/MSP-Greg/ruby-loco/releases/download/ruby-master/ruby-mswin.7z 21 | 22 | Note that if any of the Ruby test suites fail, the build will not be uploaded. 23 | Hence, the links will provide the most recent build that passed. 24 | 25 | The builds can be used in GitHub Actions CI by using the 26 | [ruby/setup-ruby](https://github.com/ruby/setup-ruby/blob/master/README.md) action or the 27 | [ruby/setup-ruby-pkgs](https://github.com/ruby/setup-ruby-pkgs/blob/master/README.md) action, 28 | which also helps with cross-platform package installation. 29 | 30 | The repo can be used to build Ruby locally. 31 | See (WIP) [Local Use](https://github.com/MSP-Greg/ruby-loco/blob/master/Local-Use.md). 32 | 33 | ### Differences from Ruby CI 34 | 35 | * Patches allow the test suites to run from the install folder, as opposed to the build folder. 'make' is not used to run any tests. 36 | 37 | * A simple CLI test is run on all bin files to verify they work. Both Windows & Bash 38 | shells are checked. 39 | 40 | ### Brief History 41 | 42 | I started working with building and testing MSYS2/MinGW Ruby in 2016, and what could be 43 | considered the start of ruby-loco happened in early 2017. 44 | 45 | At first, its main purpose was to run full testing on MinGW master builds, as at the time, 46 | that was not done in ruby/ruby. The code was updated to create a full binary build and moved 47 | to AppVeyor. 48 | 49 | Today, mingw, ucrt and mswin builds are done, and are available for use with GitHUb Actions. -------------------------------------------------------------------------------- /old_patches/14968_28.patch: -------------------------------------------------------------------------------- 1 | From mboxrd@z Thu Jan 1 00:00:00 1970 2 | Return-Path: 3 | X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net 4 | X-Spam-Level: 5 | X-Spam-ASN: AS63949 64.71.152.0/24 6 | X-Spam-Status: No, score=-2.2 required=3.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, 7 | RDNS_NONE,SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=no 8 | autolearn_force=no version=3.4.2 9 | Received: from 80x24.org (unknown [64.71.152.64]) 10 | by dcvr.yhbt.net (Postfix) with ESMTP id 75C041F87F 11 | for ; Thu, 22 Nov 2018 20:26:28 +0000 (UTC) 12 | From: Eric Wong 13 | To: spew@80x24.org 14 | Subject: [PATCH] ext/socket/init.c (wait_connectable): check socket exceptions 15 | Date: Thu, 22 Nov 2018 20:26:28 +0000 16 | Message-Id: <20181122202628.2468-1-e@80x24.org> 17 | MIME-Version: 1.0 18 | Content-Transfer-Encoding: 8bit 19 | List-Id: 20 | Archived-At: 21 | List-Archive: 22 | List-Post: 23 | 24 | Based on reading , 25 | using the socket exception list for select() may be the correct 26 | way to detect connect() success/failure on Win32. 27 | --- 28 | ext/socket/init.c | 8 ++++++-- 29 | 1 file changed, 6 insertions(+), 2 deletions(-) 30 | 31 | diff --git a/ext/socket/init.c b/ext/socket/init.c 32 | index 9742dddec2..cbf855928f 100644 33 | --- a/ext/socket/init.c 34 | +++ b/ext/socket/init.c 35 | @@ -511,7 +511,7 @@ rsock_socket(int domain, int type, int proto) 36 | static int 37 | wait_connectable(int fd) 38 | { 39 | - int sockerr, revents; 40 | + int sockerr, revents, events; 41 | socklen_t sockerrlen; 42 | 43 | sockerrlen = (socklen_t)sizeof(sockerr); 44 | @@ -544,9 +544,13 @@ wait_connectable(int fd) 45 | * So it's enough to wait only RB_WAITFD_OUT and check the pending error 46 | * by getsockopt(). 47 | * 48 | + * RB_WAITFD_PRI may be needed for win32 (and harmless otherwise): 49 | + * http://itamarst.org/writings/win32sockets.html 50 | + * 51 | * Note: rb_wait_for_single_fd already retries on EINTR/ERESTART 52 | */ 53 | - revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, NULL); 54 | + events = RB_WAITFD_IN|RB_WAITFD_OUT|RB_WAITFD_PRI; 55 | + revents = rb_wait_for_single_fd(fd, events, NULL); 56 | 57 | if (revents < 0) 58 | return -1; 59 | -- 60 | EW 61 | 62 | 63 | -------------------------------------------------------------------------------- /old_patches/pr_1878.patch: -------------------------------------------------------------------------------- 1 | From 3835e9191fa010e80b70afbbd2667f873e31c786 Mon Sep 17 00:00:00 2001 2 | From: Samuel Williams 3 | Date: Wed, 21 Nov 2018 09:52:08 +1300 4 | Subject: [PATCH 1/2] Enable msys2 to check build status. 5 | 6 | --- 7 | configure.ac | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | 10 | diff --git a/configure.ac b/configure.ac 11 | index b5a2ef86b295..01e2e0860a55 100644 12 | --- a/configure.ac 13 | +++ b/configure.ac 14 | @@ -963,7 +963,7 @@ main() 15 | AS_IF([test "$target_cpu" = x64], [ 16 | ac_cv_func___builtin_setjmp=no 17 | ac_cv_func_round=no 18 | - rb_cv_fiber_coroutine=no # TODO: Enable this after AppVeyor msys2 build succeeds 19 | + rb_cv_fiber_coroutine=yes 20 | ]) 21 | ac_cv_func_tgamma=no 22 | rb_cv_negative_time_t=yes 23 | 24 | From b5813f539849f9d69b33b49b2ff0436980609c6b Mon Sep 17 00:00:00 2001 25 | From: Samuel Williams 26 | Date: Sat, 24 Nov 2018 00:30:45 +1300 27 | Subject: [PATCH 2/2] Fix argument order. 28 | 29 | --- 30 | coroutine/win64/Context.s | 34 +++++++++++++++++----------------- 31 | 1 file changed, 17 insertions(+), 17 deletions(-) 32 | 33 | diff --git a/coroutine/win64/Context.s b/coroutine/win64/Context.s 34 | index 04d97d1aaff6..4b16e0ce8c03 100644 35 | --- a/coroutine/win64/Context.s 36 | +++ b/coroutine/win64/Context.s 37 | @@ -23,23 +23,6 @@ coroutine_transfer: 38 | pushq %r14 39 | pushq %r15 40 | 41 | - movaps -24(%rsp), %xmm6 42 | - movaps -40(%rsp), %xmm7 43 | - movaps -56(%rsp), %xmm8 44 | - movaps -72(%rsp), %xmm9 45 | - movaps -88(%rsp), %xmm10 46 | - movaps -104(%rsp), %xmm11 47 | - movaps -120(%rsp), %xmm12 48 | - movaps -136(%rsp), %xmm13 49 | - movaps -152(%rsp), %xmm14 50 | - movaps -168(%rsp), %xmm15 51 | - 52 | - # Save caller stack pointer: 53 | - mov %rsp, (%rcx) 54 | - 55 | - # Restore callee stack pointer: 56 | - mov (%rdx), %rsp 57 | - 58 | movaps %xmm15, -168(%rsp) 59 | movaps %xmm14, -152(%rsp) 60 | movaps %xmm13, -136(%rsp) 61 | @@ -51,6 +34,23 @@ coroutine_transfer: 62 | movaps %xmm7, -40(%rsp) 63 | movaps %xmm6, -24(%rsp) 64 | 65 | + # Save caller stack pointer: 66 | + mov %rsp, (%rcx) 67 | + 68 | + # Restore callee stack pointer: 69 | + mov (%rdx), %rsp 70 | + 71 | + movaps -24(%rsp), %xmm6 72 | + movaps -40(%rsp), %xmm7 73 | + movaps -56(%rsp), %xmm8 74 | + movaps -72(%rsp), %xmm9 75 | + movaps -88(%rsp), %xmm10 76 | + movaps -104(%rsp), %xmm11 77 | + movaps -120(%rsp), %xmm12 78 | + movaps -136(%rsp), %xmm13 79 | + movaps -152(%rsp), %xmm14 80 | + movaps -168(%rsp), %xmm15 81 | + 82 | # Restore callee stack: 83 | popq %r15 84 | popq %r14 85 | -------------------------------------------------------------------------------- /old_patches/r65962_14968_32.patch: -------------------------------------------------------------------------------- 1 | From mboxrd@z Thu Jan 1 00:00:00 1970 2 | Return-Path: 3 | X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net 4 | X-Spam-Level: 5 | X-Spam-ASN: 6 | X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 7 | shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 8 | Received: from localhost (dcvr.yhbt.net [127.0.0.1]) 9 | by dcvr.yhbt.net (Postfix) with ESMTP id B9D691F97E 10 | for ; Sat, 24 Nov 2018 08:37:00 +0000 (UTC) 11 | From: Eric Wong 12 | To: spew@80x24.org 13 | Subject: [PATCH] io.c: disable nonblocking-by-default on win32 14 | Date: Sat, 24 Nov 2018 08:37:00 +0000 15 | Message-Id: <20181124083700.25685-1-e@80x24.org> 16 | List-Id: 17 | Archived-At: 18 | List-Archive: 19 | List-Post: 20 | 21 | Lets admit Windows will always be too different from POSIX-like 22 | platforms and non-blocking may never work as well or consistently. 23 | 24 | [ruby-core:89973] [ruby-core:89976] [ruby-core:89977] [Bug #14968] 25 | --- 26 | io.c | 16 +++++++++++++--- 27 | 1 file changed, 13 insertions(+), 3 deletions(-) 28 | 29 | diff --git a/io.c b/io.c 30 | index da3fcfc5667..4a3f1524096 100644 31 | --- a/io.c 32 | +++ b/io.c 33 | @@ -135,6 +135,14 @@ off_t __syscall(quad_t number, ...); 34 | #define rename(f, t) rb_w32_urename((f), (t)) 35 | #endif 36 | 37 | +#if defined(_WIN32) 38 | +# define RUBY_PIPE_NONBLOCK_DEFAULT (0) 39 | +#elif defined(O_NONBLOCK) 40 | +# define RUBY_PIPE_NONBLOCK_DEFAULT (O_NONBLOCK) 41 | +#else /* any platforms where O_NONBLOCK does not exist? */ 42 | +# define RUBY_PIPE_NONBLOCK_DEFAULT (0) 43 | +#endif 44 | + 45 | VALUE rb_cIO; 46 | VALUE rb_eEOFError; 47 | VALUE rb_eIOError; 48 | @@ -345,7 +353,7 @@ rb_cloexec_pipe(int fildes[2]) 49 | #if defined(HAVE_PIPE2) 50 | static int try_pipe2 = 1; 51 | if (try_pipe2) { 52 | - ret = pipe2(fildes, O_CLOEXEC | O_NONBLOCK); 53 | + ret = pipe2(fildes, O_CLOEXEC | RUBY_PIPE_NONBLOCK_DEFAULT); 54 | if (ret != -1) 55 | return ret; 56 | /* pipe2 is available since Linux 2.6.27, glibc 2.9. */ 57 | @@ -371,8 +379,10 @@ rb_cloexec_pipe(int fildes[2]) 58 | #endif 59 | rb_maygvl_fd_fix_cloexec(fildes[0]); 60 | rb_maygvl_fd_fix_cloexec(fildes[1]); 61 | - rb_fd_set_nonblock(fildes[0]); 62 | - rb_fd_set_nonblock(fildes[1]); 63 | + if (RUBY_PIPE_NONBLOCK_DEFAULT) { 64 | + rb_fd_set_nonblock(fildes[0]); 65 | + rb_fd_set_nonblock(fildes[1]); 66 | + } 67 | return ret; 68 | } 69 | 70 | -- 71 | EW 72 | 73 | 74 | -------------------------------------------------------------------------------- /old_patches/tool-transcode-tblgen.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | changes STDERR output to STDOUT, keeps Powershell happy 3 | diff --git a/tool/transcode-tblgen.rb b/tool/transcode-tblgen.rb 4 | index 156b2de197..7f87fce661 100644 5 | --- a/tool/transcode-tblgen.rb 6 | +++ b/tool/transcode-tblgen.rb 7 | @@ -724,7 +724,7 @@ def citrus_decode_mapsrc(ces, csid, mapsrcs) 8 | path = File.join(*path) 9 | path << ".src" 10 | path[path.rindex('/')] = '%' 11 | - STDERR.puts 'load mapsrc %s' % path if VERBOSE_MODE 12 | + STDOUT.puts 'load mapsrc %s' % path if VERBOSE_MODE 13 | open(path, 'rb') do |f| 14 | f.each_line do |l| 15 | break if /^BEGIN_MAP/ =~ l 16 | @@ -824,9 +824,9 @@ def transcode_compile_tree(name, from, map, valid_encoding) 17 | def transcode_tbl_only(from, to, map, valid_encoding=UnspecifiedValidEncoding) 18 | if VERBOSE_MODE 19 | if from.empty? || to.empty? 20 | - STDERR.puts "converter for #{from.empty? ? to : from}" 21 | + STDOUT.puts "converter for #{from.empty? ? to : from}" 22 | else 23 | - STDERR.puts "converter from #{from} to #{to}" 24 | + STDOUT.puts "converter from #{from} to #{to}" 25 | end 26 | end 27 | id_from = from.tr('^0-9A-Za-z', '_') 28 | @@ -905,7 +905,7 @@ def transcode_tblgen(from, to, map, valid_encoding=UnspecifiedValidEncoding, 29 | end 30 | 31 | def transcode_generate_node(am, name_hint=nil) 32 | - STDERR.puts "converter for #{name_hint}" if VERBOSE_MODE 33 | + STDOUT.puts "converter for #{name_hint}" if VERBOSE_MODE 34 | am.gennode(TRANSCODE_GENERATED_BYTES_CODE, TRANSCODE_GENERATED_WORDS_CODE, name_hint) 35 | '' 36 | end 37 | @@ -1066,14 +1066,14 @@ def make_signature(filename, src) 38 | if old_signature == chk_signature 39 | now = Time.now 40 | File.utime(now, now, output_filename) 41 | - STDERR.puts "already up-to-date: #{output_filename}" if VERBOSE_MODE 42 | + STDOUT.puts "already up-to-date: #{output_filename}" if VERBOSE_MODE 43 | exit 44 | end 45 | end 46 | 47 | if VERBOSE_MODE 48 | if output_filename 49 | - STDERR.puts "generating #{output_filename} ..." 50 | + STDOUT.puts "generating #{output_filename} ..." 51 | end 52 | end 53 | 54 | @@ -1111,7 +1111,7 @@ def make_signature(filename, src) 55 | File.rename(new_filename, output_filename) 56 | tms = Process.times 57 | elapsed = Time.now - start_time 58 | - STDERR.puts "done. (#{'%.2f' % tms.utime}user #{'%.2f' % tms.stime}system #{'%.2f' % elapsed}elapsed)" if VERBOSE_MODE 59 | + STDOUT.puts "done. (#{'%.2f' % tms.utime}user #{'%.2f' % tms.stime}system #{'%.2f' % elapsed}elapsed)" if VERBOSE_MODE 60 | else 61 | print result 62 | end 63 | -------------------------------------------------------------------------------- /.github/workflows/ucrt.yml: -------------------------------------------------------------------------------- 1 | name: ucrt 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | schedule: 7 | - cron: '55 1,8,15 * * *' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | ucrt: 12 | strategy: 13 | fail-fast: false 14 | runs-on: windows-2022 15 | env: 16 | PRE: ruby-ucrt 17 | RUST_TC: x86_64-pc-windows-gnu 18 | 19 | steps: 20 | - name: git config 21 | run: | 22 | git config --system core.autocrlf false 23 | git config --system core.eol lf 24 | 25 | - name: Remove Strawberry Perl pkg-config 26 | # `pkg-config.bat` included in Strawberry Perl is written in 27 | # Perl and doesn't work when another msys2 `perl` precede its 28 | # own `perl`. 29 | # 30 | # ``` 31 | # Can't find C:\Strawberry\perl\bin\pkg-config.bat on PATH, '.' not in PATH. 32 | # ``` 33 | run: | 34 | Get-Command pkg-config.bat | % { ren $_.path ($_.path + "~") } 35 | 36 | - name: Checkout ruby-loco 37 | uses: actions/checkout@v6 38 | 39 | - name: Set up Ruby & MSYS2 40 | timeout-minutes: 8 41 | uses: ruby/setup-ruby-pkgs@v1 42 | with: 43 | ruby-version: ucrt 44 | mingw: rust 45 | 46 | - name: Get Ruby and RubyInstaller2 repos 47 | timeout-minutes: 5 48 | run: | 49 | $gh = 'https://github.com' 50 | git clone -q --depth=1 --no-tags --branch=master $gh/oneclick/rubyinstaller2.git ./rubyinstaller2 51 | git clone -q --depth=1 --no-tags --branch=master $gh/ruby/ruby.git ./ruby 52 | cd ruby 53 | ruby ../git_log_utc.rb 54 | 55 | - name: Cache - .downloaded-cache 56 | uses: actions/cache@v4 57 | with: 58 | path: .downloaded-cache 59 | key: dl-cache-win-ucrt-${{ hashFiles('ruby/gems/bundled_gems') }} 60 | restore-keys: dl-cache-win-ucrt- 61 | 62 | - name: build & install 63 | timeout-minutes: 30 64 | run: ./1_0_build_install_msys2_64.ps1 ucrt 65 | 66 | - name: test 67 | timeout-minutes: 70 68 | run: ./2_0_test.ps1 ucrt 69 | 70 | - name: CLI Check Bash 71 | shell: bash 72 | run: ./cli_test_bash 73 | 74 | - name: upload asset 75 | timeout-minutes: 5 76 | uses: ./.github/actions/upload-binary 77 | env: 78 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | with: 80 | ruby_path: ./${{ env.PRE }} 81 | 82 | - name: save log artifact 83 | if: success() || failure() 84 | uses: actions/upload-artifact@v4 85 | with: 86 | name: ${{ env.TEST_LOGS }} 87 | path: ./logs 88 | -------------------------------------------------------------------------------- /.github/workflows/mingw.yml_: -------------------------------------------------------------------------------- 1 | name: mingw 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | schedule: 7 | - cron: '45 1,8,15 * * *' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | mingw: 12 | strategy: 13 | fail-fast: false 14 | runs-on: windows-2022 15 | env: 16 | PRE: ruby-mingw 17 | RUST_TC: x86_64-pc-windows-gnu 18 | 19 | steps: 20 | - name: git config 21 | run: | 22 | git config --system core.autocrlf false 23 | git config --system core.eol lf 24 | 25 | - name: Remove Strawberry Perl pkg-config 26 | # `pkg-config.bat` included in Strawberry Perl is written in 27 | # Perl and doesn't work when another msys2 `perl` precede its 28 | # own `perl`. 29 | # 30 | # ``` 31 | # Can't find C:\Strawberry\perl\bin\pkg-config.bat on PATH, '.' not in PATH. 32 | # ``` 33 | run: | 34 | Get-Command pkg-config.bat | % { ren $_.path ($_.path + "~") } 35 | 36 | - name: Checkout ruby-loco 37 | uses: actions/checkout@v6 38 | 39 | - name: Set up Ruby & MSYS2 40 | timeout-minutes: 8 41 | uses: ruby/setup-ruby-pkgs@v1 42 | with: 43 | ruby-version: mingw 44 | mingw: rust 45 | 46 | - name: Get Ruby and RubyInstaller2 repos 47 | timeout-minutes: 5 48 | run: | 49 | $gh = 'https://github.com' 50 | git clone -q --depth=1 --no-tags --branch=master $gh/oneclick/rubyinstaller2.git ./rubyinstaller2 51 | git clone -q --depth=1 --no-tags --branch=master $gh/ruby/ruby.git ./ruby 52 | cd ruby 53 | ruby ../git_log_utc.rb 54 | 55 | - name: Cache - .downloaded-cache 56 | uses: actions/cache@v4 57 | with: 58 | path: .downloaded-cache 59 | key: dl-cache-win-mingw-${{ hashFiles('ruby/gems/bundled_gems') }} 60 | restore-keys: dl-cache-win-mingw- 61 | 62 | - name: build & install 63 | timeout-minutes: 30 64 | run: ./1_0_build_install_msys2_64.ps1 mingw 65 | 66 | - name: test 67 | timeout-minutes: 70 68 | run: ./2_0_test.ps1 mingw 69 | 70 | - name: CLI Check Bash 71 | shell: bash 72 | run: ./cli_test_bash 73 | 74 | - name: upload asset 75 | timeout-minutes: 5 76 | uses: ./.github/actions/upload-binary 77 | env: 78 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | with: 80 | ruby_path: ./${{ env.PRE }} 81 | 82 | - name: save log artifact 83 | if: success() || failure() 84 | uses: actions/upload-artifact@v4 85 | with: 86 | name: ${{ env.TEST_LOGS }} 87 | path: ./logs 88 | -------------------------------------------------------------------------------- /1_2_post_install_common.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # code by MSP-Greg 3 | 4 | require 'open3' 5 | require 'fileutils' 6 | 7 | module PostInstall2Common 8 | if ENV['MAKE'].start_with? 'nmake' 9 | D_INSTALL = File.join __dir__, 'ruby-mswin' 10 | D_SSL_CNF = File.join ENV['VCPKG_INSTALLATION_ROOT'], "packages/openssl_x64-windows" 11 | else 12 | case ENV['MSYSTEM'] 13 | when 'UCRT64' 14 | D_INSTALL = File.join __dir__, 'ruby-ucrt' 15 | when 'MINGW32' 16 | D_INSTALL = File.join __dir__, 'ruby-mingw32' 17 | else 18 | D_INSTALL = File.join __dir__, 'ruby-mingw' 19 | end 20 | D_MSYS2 = ENV['D_MSYS2'] 21 | D_SSL_CNF = "#{D_MSYS2}#{ENV['MINGW_PREFIX']}/etc/ssl" 22 | end 23 | 24 | D_RI2 = File.join __dir__, 'rubyinstaller2' 25 | D_RUBY = File.join __dir__, 'ruby' 26 | 27 | COL_WID = 36 28 | COL_SPACE = ' ' * COL_WID 29 | 30 | class << self 31 | 32 | def run 33 | copy_ssl_files 34 | add_licenses 35 | end 36 | 37 | private 38 | 39 | def copy_ssl_files 40 | Dir.chdir(D_RI2) { |d| 41 | require_relative "rubyinstaller2/lib/ruby_installer/build/ca_cert_file.rb" 42 | require_relative "rubyinstaller2/lib/ruby_installer/build/gem_version.rb" 43 | ca_file = RubyInstaller::Build::CaCertFile.new 44 | File.binwrite("resources/ssl/cacert.pem", ca_file.content) 45 | Dir.mkdir "#{D_INSTALL}/bin/etc" unless Dir.exist? "#{D_INSTALL}/bin/etc" 46 | Dir.mkdir "#{D_INSTALL}/bin/etc/ssl" unless Dir.exist? "#{D_INSTALL}/bin/etc/ssl" 47 | Dir.mkdir "#{D_INSTALL}/bin/etc/ssl/certs" unless Dir.exist? "#{D_INSTALL}/bin/etc/ssl/certs" 48 | cp "./resources/ssl/cacert.pem", "#{D_INSTALL}/bin/etc/ssl/cert.pem" 49 | puts "#{'installing ssl files:'.ljust(COL_WID)}cert.pem" 50 | 51 | src = File.join D_SSL_CNF, "openssl.cnf" 52 | if File.exist?(src) 53 | cp src, "#{D_INSTALL}/bin/etc/ssl/openssl.cnf" 54 | puts "#{COL_SPACE}openssl.cnf" 55 | end 56 | 57 | cp "./resources/ssl/README-SSL.md", "#{D_INSTALL}/bin/etc/ssl/README-SSL.md" 58 | puts "#{COL_SPACE}README-SSL.md" 59 | cp "./resources/ssl/c_rehash.rb", "#{D_INSTALL}/bin/etc/ssl/c_rehash.rb" 60 | puts "#{COL_SPACE}certs\\c_rehash.rb" 61 | } 62 | end 63 | 64 | def cp(src, dest) 65 | unless Dir.exist? (dest_dir = File.dirname dest) 66 | FileUtils.mkdir_p dest_dir 67 | end 68 | FileUtils.copy_file(src, dest, preserve: true) 69 | end 70 | 71 | def add_licenses 72 | cp "#{D_RUBY}/BSDL" , "#{D_INSTALL}/BSDL" 73 | cp "#{D_RUBY}/COPYING" , "#{D_INSTALL}/COPYING Ruby" 74 | cp "#{D_RUBY}/LEGAL" , "#{D_INSTALL}/LEGAL Ruby" 75 | cp "#{D_RI2}/LICENSE.txt", "#{D_INSTALL}/LICENSE Ruby Installer.txt" 76 | end 77 | 78 | end 79 | end 80 | 81 | if ARGV[0] == 'run' 82 | PostInstall2Common.run 83 | end 84 | 85 | -------------------------------------------------------------------------------- /.github/workflows/mswin.yml: -------------------------------------------------------------------------------- 1 | name: mswin 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | schedule: 7 | - cron: '35 1,8,15 * * *' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | mswin: 12 | strategy: 13 | matrix: 14 | os: [2025] 15 | fail-fast: false 16 | runs-on: windows-${{ matrix.os }} 17 | env: 18 | PRE: ruby-mswin 19 | 20 | steps: 21 | - name: git config 22 | run: | 23 | git config --system core.autocrlf false 24 | git config --system core.eol lf 25 | 26 | - name: repo checkout 27 | uses: actions/checkout@v6 28 | 29 | - name: load ruby 30 | timeout-minutes: 12 31 | uses: ruby/setup-ruby@v1 32 | with: 33 | ruby-version: mswin 34 | 35 | # cert file is created with RubyInstaller2 36 | - name: Get Ruby and RubyInstaller2 repos 37 | timeout-minutes: 5 38 | run: | 39 | $gh = 'https://github.com' 40 | git clone -q --depth=1 --no-tags --branch=master $gh/oneclick/rubyinstaller2.git ./rubyinstaller2 41 | git clone -q --depth=1 --no-tags --branch=master $gh/ruby/ruby.git ./ruby 42 | cd ruby 43 | ruby ../git_log_utc.rb 44 | 45 | - name: Install/Update Rust 46 | uses: dtolnay/rust-toolchain@stable 47 | with: 48 | toolchain: stable-x86_64-pc-windows-msvc 49 | components: rustfmt 50 | 51 | #- name: Configure bindgen 52 | # run: | 53 | # echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV 54 | # echo "BINDGEN_EXTRA_CLANG_ARGS=$((gcm clang).source -replace "bin\clang.exe","include")" >> $env:GITHUB_ENV 55 | # echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" 56 | # echo "BINDGEN_EXTRA_CLANG_ARGS=$((gcm clang).source -replace "bin\clang.exe","include")" 57 | 58 | - name: Cache - .downloaded-cache 59 | uses: actions/cache@v4 60 | with: 61 | path: .downloaded-cache 62 | key: dl-cache-win-mswin-${{ hashFiles('ruby/gems/bundled_gems') }} 63 | 64 | - name: build & install 65 | timeout-minutes: 30 66 | run: ./1_0_build_install_mswin.ps1 67 | 68 | - name: test 69 | timeout-minutes: 70 70 | run: ./2_0_test.ps1 mswin 71 | env: 72 | APPVEYOR: 'True' 73 | 74 | - name: CLI Check Bash 75 | shell: bash 76 | run: ./cli_test_bash 77 | 78 | - name: upload asset 79 | timeout-minutes: 5 80 | uses: ./.github/actions/upload-binary 81 | env: 82 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 83 | with: 84 | ruby_path: ./${{ env.PRE }} 85 | 86 | - name: save log artifact 87 | if: success() || failure() 88 | uses: actions/upload-artifact@v4 89 | with: 90 | name: ${{ env.TEST_LOGS }} 91 | path: ./logs 92 | -------------------------------------------------------------------------------- /old_patches/14968_28._revert_65929.patch: -------------------------------------------------------------------------------- 1 | diff --git a/ext/socket/init.c b/ext/socket/init.c 2 | index 9742dddec2..ba4b084837 100644 3 | --- a/ext/socket/init.c 4 | +++ b/ext/socket/init.c 5 | @@ -466,9 +466,7 @@ rsock_socket0(int domain, int type, int proto) 6 | return -1; 7 | fix_cloexec: 8 | rb_maygvl_fd_fix_cloexec(ret); 9 | - if (RSOCK_NONBLOCK_DEFAULT) { 10 | - rsock_make_fd_nonblock(ret); 11 | - } 12 | + rsock_make_fd_nonblock(ret); 13 | update_max_fd: 14 | rb_update_max_fd(ret); 15 | 16 | @@ -483,9 +481,7 @@ rsock_socket0(int domain, int type, int proto) 17 | if (ret == -1) 18 | return -1; 19 | rb_fd_fix_cloexec(ret); 20 | - if (RSOCK_NONBLOCK_DEFAULT) { 21 | - rsock_make_fd_nonblock(ret); 22 | - } 23 | + rsock_make_fd_nonblock(ret); 24 | 25 | return ret; 26 | } 27 | @@ -665,9 +661,7 @@ cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len, 28 | #ifdef HAVE_ACCEPT4 29 | static int try_accept4 = 1; 30 | #endif 31 | - if (RSOCK_NONBLOCK_DEFAULT) { 32 | - nonblock = 1; 33 | - } 34 | + nonblock = 1; /* TODO remove parameter */ 35 | if (address_len) len0 = *address_len; 36 | #ifdef HAVE_ACCEPT4 37 | if (try_accept4) { 38 | diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h 39 | index 723f09a17c..bccea8732f 100644 40 | --- a/ext/socket/rubysocket.h 41 | +++ b/ext/socket/rubysocket.h 42 | @@ -26,13 +26,7 @@ 43 | # if defined(_MSC_VER) 44 | # undef HAVE_TYPE_STRUCT_SOCKADDR_DL 45 | # endif 46 | -/* 47 | - * FIXME: failures if we make nonblocking the default 48 | - * [ruby-core:89973] [ruby-core:89976] [ruby-core:89977] [Bug #14968] 49 | - */ 50 | -# define RSOCK_NONBLOCK_DEFAULT (0) 51 | #else 52 | -# define RSOCK_NONBLOCK_DEFAULT (1) 53 | # include 54 | # include 55 | # ifdef HAVE_NETINET_IN_SYSTM_H 56 | diff --git a/ext/socket/socket.c b/ext/socket/socket.c 57 | index b6bda8fee8..ad2ca5fc67 100644 58 | --- a/ext/socket/socket.c 59 | +++ b/ext/socket/socket.c 60 | @@ -213,10 +213,8 @@ rsock_socketpair0(int domain, int type, int protocol, int sv[2]) 61 | fix_cloexec: 62 | rb_maygvl_fd_fix_cloexec(sv[0]); 63 | rb_maygvl_fd_fix_cloexec(sv[1]); 64 | - if (RSOCK_NONBLOCK_DEFAULT) { 65 | - rsock_make_fd_nonblock(sv[0]); 66 | - rsock_make_fd_nonblock(sv[1]); 67 | - } 68 | + rsock_make_fd_nonblock(sv[0]); 69 | + rsock_make_fd_nonblock(sv[1]); 70 | 71 | update_max_fd: 72 | rb_update_max_fd(sv[0]); 73 | @@ -235,10 +233,8 @@ rsock_socketpair0(int domain, int type, int protocol, int sv[2]) 74 | 75 | rb_fd_fix_cloexec(sv[0]); 76 | rb_fd_fix_cloexec(sv[1]); 77 | - if (RSOCK_NONBLOCK_DEFAULT) { 78 | - rsock_make_fd_nonblock(sv[0]); 79 | - rsock_make_fd_nonblock(sv[1]); 80 | - } 81 | + rsock_make_fd_nonblock(sv[0]); 82 | + rsock_make_fd_nonblock(sv[1]); 83 | return ret; 84 | } 85 | #endif /* !SOCK_CLOEXEC */ 86 | -------------------------------------------------------------------------------- /patches_install_msys2/0001-Add-C-ext-win32-dll_directory-as-an-alternative-to-f.patch: -------------------------------------------------------------------------------- 1 | From fd61aba54664f3374e950e260876a64369b5c839 Mon Sep 17 00:00:00 2001 2 | From: Lars Kanis 3 | Date: Tue, 28 Dec 2021 11:11:42 +0100 4 | Subject: [PATCH] Add C-ext "win32/dll_directory" as an alternative to fiddle 5 | 6 | --- 7 | ext/win32/dll_directory/depend | 2 ++ 8 | ext/win32/dll_directory/dll_directory.c | 42 +++++++++++++++++++++++++ 9 | ext/win32/dll_directory/extconf.rb | 3 ++ 10 | 3 files changed, 47 insertions(+) 11 | create mode 100644 ext/win32/dll_directory/depend 12 | create mode 100644 ext/win32/dll_directory/dll_directory.c 13 | create mode 100644 ext/win32/dll_directory/extconf.rb 14 | 15 | diff --git a/ext/win32/dll_directory/depend b/ext/win32/dll_directory/depend 16 | new file mode 100644 17 | index 0000000000..0301ce074c 18 | --- /dev/null 19 | +++ b/ext/win32/dll_directory/depend 20 | @@ -0,0 +1,2 @@ 21 | +# AUTOGENERATED DEPENDENCIES START 22 | +# AUTOGENERATED DEPENDENCIES END 23 | diff --git a/ext/win32/dll_directory/dll_directory.c b/ext/win32/dll_directory/dll_directory.c 24 | new file mode 100644 25 | index 0000000000..d44b8f2cb3 26 | --- /dev/null 27 | +++ b/ext/win32/dll_directory/dll_directory.c 28 | @@ -0,0 +1,42 @@ 29 | +#include 30 | +#include 31 | +#include 32 | +#include 33 | + 34 | +#define PTR2NUM(x) (ULL2NUM((LONG_LONG)(x))) 35 | +#define NUM2PTR(x) ((void*)(NUM2ULL(x))) 36 | + 37 | +static VALUE 38 | +s_SetDefaultDllDirectories(VALUE self, VALUE flags) 39 | +{ 40 | + int ret = SetDefaultDllDirectories(RB_NUM2LONG(flags)); 41 | + return RB_INT2NUM(ret); 42 | +} 43 | + 44 | +static VALUE 45 | +s_AddDllDirectory(VALUE self, VALUE dir) 46 | +{ 47 | + void *handle; 48 | + int encidx = rb_enc_find_index("utf-16le"); 49 | + StringValueCStr(dir); 50 | + dir = rb_str_export_to_enc(dir, rb_enc_from_index(encidx)); 51 | + handle = AddDllDirectory((PCWSTR)RSTRING_PTR(dir)); 52 | + return PTR2NUM(handle); 53 | +} 54 | + 55 | +static VALUE 56 | +s_RemoveDllDirectory(VALUE self, VALUE handle) 57 | +{ 58 | + int ret = RemoveDllDirectory(NUM2PTR(handle)); 59 | + return RB_INT2NUM(ret); 60 | +} 61 | + 62 | +void 63 | +Init_dll_directory(void) 64 | +{ 65 | + VALUE mWin32 = rb_define_module("Win32"); 66 | + VALUE mDD = rb_define_module_under(mWin32, "DllDirectory"); 67 | + rb_define_singleton_method(mDD, "SetDefaultDllDirectories", s_SetDefaultDllDirectories, 1); 68 | + rb_define_singleton_method(mDD, "AddDllDirectory", s_AddDllDirectory, 1); 69 | + rb_define_singleton_method(mDD, "RemoveDllDirectory", s_RemoveDllDirectory, 1); 70 | +} 71 | diff --git a/ext/win32/dll_directory/extconf.rb b/ext/win32/dll_directory/extconf.rb 72 | new file mode 100644 73 | index 0000000000..cfdeafacaf 74 | --- /dev/null 75 | +++ b/ext/win32/dll_directory/extconf.rb 76 | @@ -0,0 +1,3 @@ 77 | +if have_library('kernel32', 'AddDllDirectory') 78 | + create_makefile('win32/dll_directory') 79 | +end 80 | -- 81 | 2.30.0.windows.1 82 | 83 | -------------------------------------------------------------------------------- /old_patches/test/rdoc_all.patch: -------------------------------------------------------------------------------- 1 | # without this, intermittent failures in CI 2 | diff --git a/test/rdoc/support/test_case.rb b/test/rdoc/support/test_case.rb 3 | index d98dbe0d7b..6cdde617e9 100644 4 | --- a/test/rdoc/support/test_case.rb 5 | +++ b/test/rdoc/support/test_case.rb 6 | @@ -13,7 +13,7 @@ 7 | require 'tmpdir' 8 | require 'stringio' 9 | 10 | -require_relative '../../../lib/rdoc' 11 | +require 'rdoc' 12 | 13 | ## 14 | # RDoc::TestCase is an abstract TestCase to provide common setup and teardown 15 | diff --git a/test/rdoc/test_rdoc_generator_json_index.rb b/test/rdoc/test_rdoc_generator_json_index.rb 16 | index 62d1ccec95..58925a8424 100644 17 | --- a/test/rdoc/test_rdoc_generator_json_index.rb 18 | +++ b/test/rdoc/test_rdoc_generator_json_index.rb 19 | @@ -95,7 +95,8 @@ def test_generate 20 | assert_file 'js/navigation.js' 21 | assert_file 'js/search_index.js' 22 | 23 | - srcdir = File.expand_path('lib/rdoc', @pwd) 24 | + #srcdir = File.expand_path('lib/rdoc', @pwd) 25 | + srcdir = "#{RbConfig::CONFIG['rubylibdir']}/rdoc" 26 | if !File.directory? srcdir 27 | # for Ruby core repository 28 | srcdir = File.expand_path("../../../lib/rdoc", __FILE__) 29 | diff --git a/test/rdoc/test_rdoc_markdown.rb b/test/rdoc/test_rdoc_markdown.rb 30 | index 72587caf46..ff508e57ee 100644 31 | --- a/test/rdoc/test_rdoc_markdown.rb 32 | +++ b/test/rdoc/test_rdoc_markdown.rb 33 | @@ -2,8 +2,8 @@ 34 | # frozen_string_literal: true 35 | 36 | require_relative 'helper' 37 | -require_relative '../../lib/rdoc/markup/block_quote' 38 | -require_relative '../../lib/rdoc/markdown' 39 | +require 'rdoc/markup/block_quote' 40 | +require 'rdoc/markdown' 41 | 42 | class TestRDocMarkdown < RDoc::TestCase 43 | 44 | diff --git a/test/rdoc/test_rdoc_markdown_test.rb b/test/rdoc/test_rdoc_markdown_test.rb 45 | index 193d648253..4def1a101f 100644 46 | --- a/test/rdoc/test_rdoc_markdown_test.rb 47 | +++ b/test/rdoc/test_rdoc_markdown_test.rb 48 | @@ -2,8 +2,8 @@ 49 | require_relative 'helper' 50 | require 'pp' 51 | 52 | -require_relative '../../lib/rdoc' 53 | -require_relative '../../lib/rdoc/markdown' 54 | +require 'rdoc' 55 | +require 'rdoc/markdown' 56 | 57 | class TestRDocMarkdownTest < RDoc::TestCase 58 | 59 | diff --git a/test/rdoc/test_rdoc_rubygems_hook.rb b/test/rdoc/test_rdoc_rubygems_hook.rb 60 | index 59a7ed0f89..9591ec42ef 100644 61 | --- a/test/rdoc/test_rdoc_rubygems_hook.rb 62 | +++ b/test/rdoc/test_rdoc_rubygems_hook.rb 63 | @@ -2,7 +2,7 @@ 64 | require 'rubygems' 65 | require 'fileutils' 66 | require 'tmpdir' 67 | -require_relative '../../lib/rdoc/rubygems_hook' 68 | +require 'rdoc/rubygems_hook' 69 | require 'test/unit' 70 | 71 | class TestRDocRubygemsHook < Test::Unit::TestCase 72 | diff --git a/test/rdoc/test_rdoc_servlet.rb b/test/rdoc/test_rdoc_servlet.rb 73 | index 7a5b15a6eb..965912c9d5 100644 74 | --- a/test/rdoc/test_rdoc_servlet.rb 75 | +++ b/test/rdoc/test_rdoc_servlet.rb 76 | @@ -5,6 +5,9 @@ 77 | rescue LoadError 78 | end 79 | 80 | +require 'tsort' rescue nil 81 | +require 'json' rescue nil 82 | + 83 | class TestRDocServlet < RDoc::TestCase 84 | 85 | def setup 86 | -------------------------------------------------------------------------------- /Local-Use.md: -------------------------------------------------------------------------------- 1 | ## Local Building Instructions 2 | 3 | **Important Note:** ruby-loco is designed to build from the [ruby/ruby repo](https://github.com/ruby/ruby), not from 4 | tarballs downloaded from https://www.ruby-lang.org/en/downloads/. 5 | 6 | ### Prerequisites 7 | 8 | 1. Clone or fork of this repo 9 | 10 | 2. A stand-alone Ruby in your path. 11 | 12 | 3. Git for Windows. 13 | 14 | 3. At the root of the repo, a symlink of 'ruby' to the [Ruby repo](https://github.com/ruby/ruby) 15 | you want to use for source. 16 | 17 | 4. At the root of the repo, a symlink of 'rubyinstaller2' to the 18 | [RubyInstaller2 repo](https://github.com/oneclick/rubyinstaller2) you want to use for 19 | source. This provides the 'ridk' runtime files and command for mingw & ucrt builds, 20 | and provides the code to generate the SSL cert file used in all builds. 21 | 22 | 5. Current MSYS2 installation. Normally, this would be installed at `C:/msys64`. The mingw 23 | & ucrt builds compile using the MSYS2 compiler. The mswin build uses `bison`, which is 24 | a 'MSYS2' package. Builds may also use `ragel`, which is a mingw or ucrt package. 25 | 26 | 6. **mswin only** - A Microsoft Visual Studio installation. The path to `vcvars64.bat` should 27 | be added to your `local.ps1` file mentioned below. 28 | 29 | 7. **mswin only** - mswin build uses the [Microsoft/vcpkg](https://github.com/Microsoft/vcpkg) 30 | system for dependency dll's. Normally a fork/clone of the repository. Standard location 31 | is `C:/vcpkg`. 32 | 33 | ### Setup 34 | 35 | Copy the file `local.ps1.sample`, remove `.sample`, then update its contents to match your system. 36 | 37 | MSYS2 installation info is at https://www.msys2.org/ 38 | 39 | The 'local_use' folder of this repo contains PowerShell scripts to install MSYS2 40 | (mingw & ucrt) packages and vcpkg packages needed to build Ruby. All must be started from 41 | the root folder of their respective system, ie, `C:/msys64` or `C:/vcpkg`. 42 | 43 | ### Build & Test 44 | 45 | Once the setup is done, just two simple commands from the repo root: 46 | 47 | The below commands run make and make install, along with installing dll's, etc. The self-contained 48 | build is contained one of three folders: `ruby-ucrt`, `ruby-mswin`, or `ruby-mingw`, 49 | depending on the build selected. 50 | ``` 51 | mingw or ucrt (defaults to ucrt) 52 | ./1_0_build_install_64.ps1 53 | 54 | mswin 55 | ./1_0_build_install_mswin.ps1 56 | ``` 57 | 58 | The below command runs all test suites: 59 | ``` 60 | ./2_0_test.ps1 61 | ``` 62 | 63 | ### Notes - General 64 | 65 | Patches are used in both the build/install step and the test step. When working with the 66 | ruby/ruby repo, these should be 'cleaned' from the repo. The patches are mainly used to 67 | allow testing from the install folder, and some are needed in ruby lib files for testing. 68 | 69 | Note that the patches are meant to work with ruby/ruby master, so they may not work with 70 | older Ruby versions. 71 | 72 | The msys2 OpenSSL package is patched to reference the cert file relative to the exe file 73 | using it. That is not the case for the vcpkg OpenSSL package. Hence, the mswin build is 74 | patched to set the related OpenSSL env variables in the build. If you have code that 75 | changes the env values, the original values should be restored, otherwise ssl connections 76 | cannot be verified. 77 | -------------------------------------------------------------------------------- /old_patches/65470_lib-rubygems.patch: -------------------------------------------------------------------------------- 1 | Patch by MP-Greg 2 | installer.rb - Windows allows paths to use '/' for a path separator, adjust code 3 | to allow for it 4 | test_case.rb - code so it can find test directory from $LOAD_PATH 5 | diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb 6 | index 8cb89e2e40..2e803be182 100644 7 | --- a/lib/rubygems/installer.rb 8 | +++ b/lib/rubygems/installer.rb 9 | @@ -698,10 +698,12 @@ def process_options # :nodoc: 10 | 11 | def check_that_user_bin_dir_is_in_path # :nodoc: 12 | user_bin_dir = @bin_dir || Gem.bindir(gem_home) 13 | - user_bin_dir = user_bin_dir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if 14 | - File::ALT_SEPARATOR 15 | - 16 | path = ENV['PATH'] 17 | + if File::ALT_SEPARATOR 18 | + user_bin_dir = user_bin_dir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) 19 | + path = path.gsub(File::SEPARATOR, File::ALT_SEPARATOR) 20 | + end 21 | + 22 | if Gem.win_platform? then 23 | path = path.downcase 24 | user_bin_dir = user_bin_dir.downcase 25 | diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb 26 | index ced33c4d11..1f28a1666b 100644 27 | --- a/lib/rubygems/test_case.rb 28 | +++ b/lib/rubygems/test_case.rb 29 | @@ -1320,8 +1320,6 @@ def self.rubybin 30 | end 31 | 32 | @@ruby = rubybin 33 | - @@good_rake = "#{rubybin} \"#{File.expand_path('../../../test/rubygems/good_rake.rb', __FILE__)}\"" 34 | - @@bad_rake = "#{rubybin} \"#{File.expand_path('../../../test/rubygems/bad_rake.rb', __FILE__)}\"" 35 | 36 | ## 37 | # Construct a new Gem::Dependency. 38 | @@ -1509,14 +1507,10 @@ def self.load_cert cert_name 39 | 40 | def self.cert_path cert_name 41 | if 32 == (Time.at(2**32) rescue 32) then 42 | - cert_file = 43 | - File.expand_path "../../../test/rubygems/#{cert_name}_cert_32.pem", 44 | - __FILE__ 45 | - 46 | + cert_file = File.join test_path, "#{cert_name}_cert_32.pem" 47 | return cert_file if File.exist? cert_file 48 | end 49 | - 50 | - File.expand_path "../../../test/rubygems/#{cert_name}_cert.pem", __FILE__ 51 | + File.join test_path, "#{cert_name}_cert.pem" 52 | end 53 | 54 | ## 55 | @@ -1534,7 +1528,23 @@ def self.load_key key_name, passphrase = nil 56 | # Returns the path to the key named +key_name+ from test/rubygems 57 | 58 | def self.key_path key_name 59 | - File.expand_path "../../../test/rubygems/#{key_name}_key.pem", __FILE__ 60 | + File.join test_path, "#{key_name}_key.pem" 61 | + end 62 | + 63 | + def self.test_path 64 | + @@test_path ||= begin 65 | + temp = $LOAD_PATH.reverse.find { |p| /test\/(lib|rubygems|-ext-)\z/ =~ p } || '' 66 | + if temp.empty? 67 | + temp = File.expand_path('../../../test/rubygems', __FILE__) 68 | + else 69 | + temp = File.join File.dirname(temp), 'rubygems' 70 | + temp = '' unless File.exist? File.join(temp, 'test_gem.rb') 71 | + end 72 | + r_bin = Gem::TestCase.rubybin 73 | + @@good_rake ||= "#{r_bin} \"#{File.join temp, 'good_rake.rb'}\"" 74 | + @@bad_rake ||= "#{r_bin} \"#{File.join temp, 'bad_rake.rb'}\"" 75 | + temp 76 | + end 77 | end 78 | 79 | # :stopdoc: 80 | @@ -1596,3 +1606,5 @@ def self.key_path key_name 81 | END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid} 82 | Gem.clear_paths 83 | Gem.loaded_specs.clear 84 | +# $LOAD_PATH has path to tests loaded 85 | +Gem::TestCase.test_path 86 | -------------------------------------------------------------------------------- /patches_ri2/msys2_installation.rb.patch_: -------------------------------------------------------------------------------- 1 | diff --git a/lib/ruby_installer/build/msys2_installation.rb b/lib/ruby_installer/build/msys2_installation.rb 2 | index 19438ca..7077e73 100644 3 | --- a/lib/ruby_installer/build/msys2_installation.rb 4 | +++ b/lib/ruby_installer/build/msys2_installation.rb 5 | @@ -23,18 +23,18 @@ module Build # Use for: Build, Runtime 6 | @mingwdir = nil 7 | @mingwarch = mingwarch || ( 8 | case RUBY_PLATFORM 9 | - when /x64.*ucrt/ then 'ucrt64' 10 | - when /x64.*mingw32/ then 'mingw64' 11 | - when /i386.*mingw32/ then 'mingw32' 12 | - else raise "unsupported ruby platform #{RUBY_PLATFORM.inspect}" 13 | + when /x64.*ucrt/ then 'ucrt64' 14 | + when /x64.*mingw32/ then 'mingw64' 15 | + when /i386.*mingw32/ then 'mingw32' 16 | + else raise "unsupported ruby platform #{RUBY_PLATFORM.inspect}" 17 | end 18 | ) 19 | @mingw_package_prefix = mingw_package_prefix || begin 20 | case @mingwarch 21 | - when 'mingw32' then "mingw-w64-i686" 22 | - when 'mingw64' then "mingw-w64-x86_64" 23 | - when 'ucrt64' then "mingw-w64-ucrt-x86_64" 24 | - else raise "unknown mingwarch #{@mingwarch.inspect}" 25 | + when 'mingw32' then "mingw-w64-i686" 26 | + when 'mingw64' then "mingw-w64-x86_64" 27 | + when 'ucrt64' then "mingw-w64-ucrt-x86_64" 28 | + else raise "unknown mingwarch #{@mingwarch.inspect}" 29 | end 30 | end 31 | 32 | @@ -164,25 +164,25 @@ module Build # Use for: Build, Runtime 33 | end 34 | 35 | case mingwarch 36 | - when 'mingw32' 37 | - vars['MSYSTEM_PREFIX'] = '/mingw32' 38 | - vars['MSYSTEM_CARCH'] = 'i686' 39 | - vars['MSYSTEM_CHOST'] = 'i686-w64-mingw32' 40 | - vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] 41 | - vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] 42 | - when 'mingw64' 43 | - vars['MSYSTEM_PREFIX'] = '/mingw64' 44 | - vars['MSYSTEM_CARCH'] = 'x86_64' 45 | - vars['MSYSTEM_CHOST'] = 'x86_64-w64-mingw32' 46 | - vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] 47 | - vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] 48 | - when 'ucrt64' 49 | - vars['MSYSTEM_PREFIX'] = '/ucrt64' 50 | - vars['MSYSTEM_CARCH'] = 'x86_64' 51 | - vars['MSYSTEM_CHOST'] = 'x86_64-w64-mingw32' 52 | - vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] 53 | - vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] 54 | - else raise "unknown mingwarch #{@mingwarch.inspect}" 55 | + when 'mingw32' 56 | + vars['MSYSTEM_PREFIX'] = '/mingw32' 57 | + vars['MSYSTEM_CARCH'] = 'i686' 58 | + vars['MSYSTEM_CHOST'] = 'i686-w64-mingw32' 59 | + vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] 60 | + vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] 61 | + when 'mingw64' 62 | + vars['MSYSTEM_PREFIX'] = '/mingw64' 63 | + vars['MSYSTEM_CARCH'] = 'x86_64' 64 | + vars['MSYSTEM_CHOST'] = 'x86_64-w64-mingw32' 65 | + vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] 66 | + vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] 67 | + when 'ucrt64' 68 | + vars['MSYSTEM_PREFIX'] = '/ucrt64' 69 | + vars['MSYSTEM_CARCH'] = 'x86_64' 70 | + vars['MSYSTEM_CHOST'] = 'x86_64-w64-mingw32' 71 | + vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] 72 | + vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] 73 | + else raise "unknown mingwarch #{@mingwarch.inspect}" 74 | end 75 | 76 | begin 77 | -------------------------------------------------------------------------------- /patches_basic_boot/basictest.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | Allows running basictest from a Ruby install 3 | diff --git a/basictest/ruby_runner.rb b/basictest/ruby_runner.rb 4 | new file mode 100644 5 | index 0000000000..9642d5d3de 6 | --- /dev/null 7 | +++ b/basictest/ruby_runner.rb 8 | @@ -0,0 +1,28 @@ 9 | +ruby_opts = ENV["RUBYOPT"] 10 | +ENV["RUBYOPT"] = "--disable=gems -W1" 11 | + 12 | +ARGV[0] and opt = ARGV[0][/\A--run-opt=(.*)/, 1] and ARGV.shift 13 | + 14 | +$stderr.reopen($stdout) 15 | +error = '' 16 | + 17 | +`ruby.exe test.rb #{ARGV.join(' ')}`.each_line do |line| 18 | + if line =~ /^end of test/ 19 | + print "\ntest succeeded\n" 20 | + if ruby_opts 21 | + ENV['RUBYOPT'] =ruby_opts 22 | + else 23 | + ENV.delete 'RUBYOPT' 24 | + end 25 | + exit true 26 | + end 27 | + error << line if %r:^(basictest/test.rb|not): =~ line 28 | +end 29 | +puts 30 | +print error 31 | +print "test failed\n" 32 | +if ruby_opts 33 | + ENV['RUBYOPT'] =ruby_opts 34 | +else 35 | + ENV.delete 'RUBYOPT' 36 | +end 37 | diff --git a/basictest/test.rb b/basictest/test.rb 38 | index 95875b52a6..bac4cbbbb0 100755 39 | --- a/basictest/test.rb 40 | +++ b/basictest/test.rb 41 | @@ -10,6 +10,7 @@ def initialize 42 | @tty = nil 43 | @quiet = nil 44 | @verbose = nil 45 | + ruby_arg = "./miniruby" 46 | ARGV.each do |arg| 47 | case arg 48 | when /\A--color(?:=(?:always|(auto)|(never)|(.*)))?\z/ 49 | @@ -23,6 +24,8 @@ def initialize 50 | @quiet = true 51 | when /\A-(v|-verbose)\z/ 52 | @verbose = true 53 | + when /\A-(r|-ruby)\z/ 54 | + ruby_arg = "ruby" 55 | end 56 | end 57 | @tty = STDERR.tty? && !STDOUT.tty? && /dumb/ !~ ENV["TERM"] if @tty.nil? 58 | @@ -47,6 +50,7 @@ def initialize 59 | @passed = @failed = @reset = "" 60 | end 61 | extend(Rotator) if @tty 62 | + Object.const_set(:R_EXE, ruby_arg) 63 | end 64 | 65 | def passed_string 66 | @@ -1964,22 +1968,22 @@ module EvTest 67 | unless /wasi/ =~ RUBY_PLATFORM 68 | test_check "system" 69 | test_ok(`echo foobar` == "foobar\n") 70 | -test_ok(`./miniruby -e 'print "foobar"'` == 'foobar') 71 | +test_ok(`#{R_EXE} -e 'print "foobar"'` == 'foobar') 72 | 73 | script_tmp = "script_tmp.#{$$}" 74 | tmp = open(script_tmp, "w") 75 | tmp.print "print $zzz\n"; 76 | tmp.close 77 | 78 | -test_ok(`./miniruby -s #{script_tmp} -zzz` == 'true') 79 | -test_ok(`./miniruby -s #{script_tmp} -zzz=555` == '555') 80 | +test_ok(`#{R_EXE} -s #{script_tmp} -zzz` == 'true') 81 | +test_ok(`#{R_EXE} -s #{script_tmp} -zzz=555` == '555') 82 | 83 | tmp = open(script_tmp, "w") 84 | tmp.print "#! /usr/local/bin/ruby -s\n"; 85 | tmp.print "print $zzz\n"; 86 | tmp.close 87 | 88 | -test_ok(`./miniruby #{script_tmp} -zzz=678` == '678') 89 | +test_ok(`#{R_EXE} #{script_tmp} -zzz=678` == '678') 90 | 91 | tmp = open(script_tmp, "w") 92 | tmp.print "this is a leading junk\n"; 93 | @@ -1989,8 +1993,8 @@ module EvTest 94 | tmp.print "this is a trailing junk\n"; 95 | tmp.close 96 | 97 | -test_ok(`./miniruby -x #{script_tmp}` == '') 98 | -test_ok(`./miniruby -x #{script_tmp} -zzz=555` == '555') 99 | +test_ok(`#{R_EXE} -x #{script_tmp}` == '') 100 | +test_ok(`#{R_EXE} -x #{script_tmp} -zzz=555` == '555') 101 | 102 | tmp = open(script_tmp, "w") 103 | for i in 1..5 104 | @@ -1998,7 +2002,7 @@ module EvTest 105 | end 106 | tmp.close 107 | 108 | -`./miniruby -i.bak -pe '$_.sub!(/^[0-9]+$/){$&.to_i * 5}' #{script_tmp}` 109 | +`#{R_EXE} -i.bak -pe '$_.sub!(/^[0-9]+$/){$&.to_i * 5}' #{script_tmp}` 110 | done = true 111 | tmp = open(script_tmp, "r") 112 | while tmp.gets 113 | -------------------------------------------------------------------------------- /patches_test/open_port_issues.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb 2 | index 3ec1a71043..d627ae0429 100644 3 | --- a/test/openssl/test_ssl.rb 4 | +++ b/test/openssl/test_ssl.rb 5 | @@ -126,11 +126,29 @@ def test_socket_open_with_context 6 | } 7 | end 8 | 9 | + def get_random_port(host = '127.0.0.1') 10 | + # IANA suggests dynamic port for 49152 to 65535 11 | + # http://www.iana.org/assignments/port-numbers 12 | + addr_range = RUBY_PLATFORM.match?(/mingw|mswin/) ? 50_000..65_535 : 49152..65535 13 | + begin 14 | + port = rand addr_range 15 | + end while port_in_use? host, port 16 | + port 17 | + end 18 | + 19 | + def port_in_use?(host, port) 20 | + TCPServer.open(host, port).close 21 | + false 22 | + rescue Errno::EADDRINUSE, Errno::EACCES 23 | + true 24 | + end 25 | + private :port_in_use?, :get_random_port 26 | + 27 | def test_socket_open_with_local_address_port_context 28 | start_server { |port| 29 | begin 30 | # Guess a free port number 31 | - random_port = rand(49152..65535) 32 | + random_port = get_random_port 33 | ctx = OpenSSL::SSL::SSLContext.new 34 | ssl = OpenSSL::SSL::SSLSocket.open("127.0.0.1", port, "127.0.0.1", random_port, context: ctx) 35 | ssl.sync_close = true 36 | diff --git a/test/socket/test_addrinfo.rb b/test/socket/test_addrinfo.rb 37 | index 0c9529090e..10c9e897bf 100644 38 | --- a/test/socket/test_addrinfo.rb 39 | +++ b/test/socket/test_addrinfo.rb 40 | @@ -366,22 +366,28 @@ def test_ractor_shareable 41 | RUBY 42 | end 43 | 44 | - def random_port 45 | + def random_port(host = '127.0.0.1') 46 | # IANA suggests dynamic port for 49152 to 65535 47 | # http://www.iana.org/assignments/port-numbers 48 | - case RUBY_PLATFORM 49 | - when /mingw|mswin/ 50 | - rand(50000..65535) 51 | - else 52 | - rand(49152..65535) 53 | - end 54 | + addr_range = RUBY_PLATFORM.match?(/mingw|mswin/) ? 50_000..65_535 : 49152..65535 55 | + begin 56 | + port = rand addr_range 57 | + end while port_in_use? host, port 58 | + port 59 | + end 60 | + 61 | + def port_in_use?(host, port) 62 | + TCPServer.open(host, port).close 63 | + false 64 | + rescue Errno::EADDRINUSE, Errno::EACCES 65 | + true 66 | end 67 | + private :port_in_use?, :random_port 68 | 69 | def errors_addrinuse 70 | - errs = [Errno::EADDRINUSE] 71 | # Windows fails with "Errno::EACCES: Permission denied - bind(2) for 0.0.0.0:49721" 72 | - errs << Errno::EACCES if /mingw|mswin/ =~ RUBY_PLATFORM 73 | - errs 74 | + RUBY_PLATFORM.match?(/mingw|mswin/) ? 75 | + [Errno::EADDRINUSE, Errno::EACCES] : [Errno::EADDRINUSE] 76 | end 77 | 78 | def test_connect_from 79 | diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb 80 | index e746aca101..f033c8147e 100644 81 | --- a/test/socket/test_socket.rb 82 | +++ b/test/socket/test_socket.rb 83 | @@ -160,25 +160,28 @@ def test_tcp_cloexec 84 | } 85 | end 86 | 87 | - def random_port 88 | + ADDR_RANGE = RUBY_PLATFORM.match?(/mingw|mswin/) ? 50_000..65_535 : 49152..65535 89 | + 90 | + def random_port(host = '127.0.0.1') 91 | # IANA suggests dynamic port for 49152 to 65535 92 | # http://www.iana.org/assignments/port-numbers 93 | - case RUBY_PLATFORM 94 | - when /mingw|mswin/ 95 | - rand(50000..65535) 96 | - else 97 | - rand(49152..65535) 98 | - end 99 | + begin 100 | + port = rand ADDR_RANGE 101 | + end while port_in_use? host, port 102 | + port 103 | end 104 | 105 | + def port_in_use?(host, port) 106 | + TCPServer.open(host, port).close 107 | + false 108 | + rescue Errno::EADDRINUSE, Errno::EACCES 109 | + true 110 | + end 111 | + private :port_in_use?, :random_port 112 | + 113 | def errors_addrinuse 114 | - errs = [Errno::EADDRINUSE] 115 | - # Windows can fail with "Errno::EACCES: Permission denied - bind(2) for 0.0.0.0:49721" 116 | - # or "Test::Unit::ProxyError: Permission denied - bind(2) for 0.0.0.0:55333" 117 | - if /mswin|mingw/ =~ RUBY_PLATFORM 118 | - errs += [Errno::EACCES, Test::Unit::ProxyError] 119 | - end 120 | - errs 121 | + RUBY_PLATFORM.match?(/mingw|mswin/) ? 122 | + [Errno::EADDRINUSE, Errno::EACCES] : [Errno::EADDRINUSE] 123 | end 124 | 125 | def test_tcp_server_sockets 126 | -------------------------------------------------------------------------------- /1_0_build_install_mswin.ps1: -------------------------------------------------------------------------------- 1 | <# Code by MSP-Greg 2 | Script for building & installing MSWIN Ruby for CI 3 | Assumes a Ruby exe is in path 4 | Assumes 'Git for Windows' is installed at $env:ProgramFiles\Git 5 | Assumes '7z ' is installed at $env:ProgramFiles\7-Zip 6 | For local use, set items in local.ps1 7 | #> 8 | 9 | #————————————————————————————————————————————————————————————————— Set-Variables-Local 10 | # set variables only used in this script 11 | function Set-Variables-Local { 12 | $script:ruby_path = $(ruby.exe -e "puts RbConfig::CONFIG['bindir']").trim().replace('\', '/') 13 | $script:time_info = '' 14 | $script:time_old = $null 15 | $script:time_start = $null 16 | $script:d_vcpkg_install = "$d_vcpkg/installed/x64-windows" 17 | } 18 | 19 | #——————————————————————————————————————————————————————————————————— start build 20 | cd $PSScriptRoot 21 | 22 | (Get-Content ruby/gems/bundled_gems -raw) -replace '(?m)^syslog.+\n', '' | Set-Content ruby/gems/bundled_gems -NoNewline 23 | 24 | $global:build_sys = 'mswin' 25 | 26 | . ./0_common.ps1 mswin 27 | 28 | Set-Variables 29 | 30 | Set-Variables-Local 31 | $env:Path = "$ruby_path;$d_repo/git/cmd;$env:Path;$d_msys2/usr/bin;$d_mingw;" 32 | $env:PKG_CONFIG = "d_vcpkg_install/tools/pkgconf/pkgconf.exe" 33 | 34 | $files = 'C:/Windows/System32/libcrypto-1_1-x64.dll', 35 | 'C:/Windows/System32/libssl-1_1-x64.dll' 36 | 37 | Files-Hide $files 38 | 39 | Run-Patches @('rubyinstaller2', 'patches_ri2') 40 | Run-Patches @('ruby', 'patches_install_all', 'patches_install_mswin') 41 | 42 | Create-Folders 43 | 44 | # set time stamp for reproducible build 45 | $ts = $(git log -1 --format=%at).Trim() 46 | if ($ts -match '\A\d+\z' -and $ts -gt "1540000000") { 47 | $env:SOURCE_DATE_EPOCH = [String][int]$ts 48 | # echo "SOURCE_DATE_EPOCH = $env:SOURCE_DATE_EPOCH" 49 | } 50 | 51 | # below sets some directories to normal in case they're set to read-only 52 | Remove-Read-Only $d_ruby 53 | Remove-Read-Only $d_build 54 | 55 | cd $d_build 56 | 57 | Time-Log "start" 58 | 59 | $cmd_config = "..\ruby\win32\configure.bat --disable-install-doc --prefix=$d_install --with-opt-dir=$d_vcpkg_install --with-gmp" 60 | Run $cmd_config { cmd.exe /c "$cmd_config" } 61 | Time-Log "configure" 62 | Run "Makefile" { cat ./Makefile } 63 | 64 | Run "nmake incs" { 65 | nmake incs 66 | Check-Exit "'make incs` failure" 67 | } 68 | Time-Log "make incs" 69 | 70 | $env:Path = "$d_vcpkg_install\bin;$env:Path" 71 | 72 | Run "nmake" { 73 | nmake 74 | Check-Exit "'make` failure" 75 | } 76 | Time-Log "nmake" 77 | 78 | Files-Unhide $files 79 | 80 | Run "nmake 'DESTDIR=' install-nodoc" { 81 | nmake "DESTDIR=" install-nodoc 82 | Check-Exit "'make install-nodoc' failure" 83 | # generates string like 320, 310, etc 84 | $ruby_abi = ([regex]'\Aruby (\d+\.\d+)').match($(./miniruby.exe -v)).groups[1].value.replace('.', '') + '0' 85 | # set correct ABI version for manifest file 86 | $file = "$d_repo/mswin/ruby-exe.xml" 87 | (Get-Content $file -raw) -replace "ruby\d{3}","ruby$ruby_abi" | Set-Content $file 88 | 89 | cd $d_install\bin\ruby_builtin_dlls 90 | echo "installing dll files: From $d_vcpkg_install/bin" 91 | 92 | # Changes here requires changes to mswin/ruby_builtin_dlls.manifest and 93 | # mswin/ruby-exe.xml, update version in the below 94 | # 95 | $dlls = @('gmp-10', 'gmpxx-4', 'libcrypto-3-x64', 'libssl-3-x64', 'ffi-8', 'readline', 'yaml', 'zlib1') 96 | 97 | foreach ($dll in $dlls) { 98 | Copy-Item $d_vcpkg_install/bin/$dll.dll 99 | echo " $dll.dll" 100 | } 101 | 102 | Copy-Item $d_repo/mswin/ruby_builtin_dlls.manifest 103 | 104 | cd $d_install\bin\lib\ossl-modules 105 | Copy-Item $d_vcpkg_install/bin/legacy.dll 106 | 107 | cd $d_repo 108 | 109 | if (Test-Path -Path $d_install/lib/x64-vcruntime140-ruby$ruby_abi-static.lib -PathType Leaf ) { 110 | del $d_install\lib\x64-vcruntime140-ruby$ruby_abi-static.lib 111 | } 112 | # below can't run from built Ruby, as it needs valid cert files 113 | ruby 1_2_post_install_common.rb run 114 | } 115 | Time-Log "make install-nodoc" 116 | 117 | Run "manifest ruby.exe, rubyw.exe" { 118 | cd $d_install\bin 119 | mt.exe -manifest $d_repo\mswin\ruby-exe.xml -outputresource:ruby.exe;1 120 | mt.exe -manifest $d_repo\mswin\ruby-exe.xml -outputresource:rubyw.exe;1 121 | } 122 | Time-Log "manifest ruby.exe, rubyw.exe" 123 | 124 | Print-Time-Log 125 | 126 | # below needs to run from built/installed Ruby 127 | cd $d_repo 128 | $env:Path = "$d_install\bin;$base_path" 129 | &"$d_install/bin/ruby.exe" 1_4_post_install_bin_files.rb 130 | 131 | if (Test-Path Env:\SOURCE_DATE_EPOCH ) { Remove-Item Env:\SOURCE_DATE_EPOCH } 132 | 133 | $ruby_exe = "$d_install/bin/ruby.exe" 134 | $ruby_v = &$ruby_exe -v 135 | 136 | if (-not ($ruby_v -cmatch "$rarch\]\z")) { 137 | throw("Ruby may have compile/install issue, won't start") 138 | } else { 139 | Write-Host $ruby_v 140 | } 141 | 142 | # reset to original 143 | $env:Path = $orig_path 144 | 145 | # Apply-Patches "mswin_test_patches" -------------------------------------------------------------------------------- /patches_test/rubygems_all.patch: -------------------------------------------------------------------------------- 1 | diff --git a/test/rubygems/bundler_test_gem.rb b/test/rubygems/bundler_test_gem.rb 2 | index ca2980e04b..d730c74081 100644 3 | --- a/test/rubygems/bundler_test_gem.rb 4 | +++ b/test/rubygems/bundler_test_gem.rb 5 | @@ -409,6 +409,8 @@ def with_local_bundler_at(path) 6 | 7 | # If bundler gemspec exists, pretend it's installed 8 | bundler_gemspec = File.expand_path("../../bundler/bundler.gemspec", __dir__) 9 | + bundler_gemspec = File.expand_path("../../lib/bundler/bundler.gemspec", __dir__) unless File.exist?(bundler_gemspec) 10 | + 11 | if File.exist?(bundler_gemspec) 12 | target_gemspec_location = "#{path}/specifications/bundler-#{Bundler::VERSION}.gemspec" 13 | 14 | diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb 15 | index 74c8953904..91c6a5063d 100644 16 | --- a/test/rubygems/test_gem.rb 17 | +++ b/test/rubygems/test_gem.rb 18 | @@ -919,7 +919,7 @@ def test_self_platforms 19 | end 20 | 21 | def test_self_prefix 22 | - assert_equal PROJECT_DIR, Gem.prefix 23 | + assert_nil Gem.prefix 24 | end 25 | 26 | def test_self_prefix_libdir 27 | diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb 28 | index 48252d84d4..e4f130936e 100644 29 | --- a/test/rubygems/test_gem_commands_environment_command.rb 30 | +++ b/test/rubygems/test_gem_commands_environment_command.rb 31 | @@ -29,7 +29,13 @@ def test_execute 32 | @ui.output) 33 | assert_match(/USER INSTALLATION DIRECTORY: #{Regexp.escape Gem.user_dir}/, 34 | @ui.output) 35 | - assert_match(/RUBYGEMS PREFIX: /, @ui.output) 36 | + 37 | + if Gem.prefix.nil? 38 | + refute_match(/RUBYGEMS PREFIX: /, @ui.output) 39 | + else 40 | + assert_match(/RUBYGEMS PREFIX: /, @ui.output) 41 | + end 42 | + 43 | assert_match(/RUBY EXECUTABLE:.*#{RbConfig::CONFIG["ruby_install_name"]}/, 44 | @ui.output) 45 | assert_match(/GIT EXECUTABLE: #{@cmd.send(:git_path)}/, @ui.output) 46 | diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb 47 | index 3b106e4581..8774df1d9c 100644 48 | --- a/test/rubygems/test_gem_commands_update_command.rb 49 | +++ b/test/rubygems/test_gem_commands_update_command.rb 50 | @@ -761,8 +761,11 @@ def test_update_rubygems_arguments 51 | 52 | arguments = @cmd.update_rubygems_arguments 53 | 54 | - assert_equal "--prefix", arguments.shift 55 | - assert_equal Gem.prefix, arguments.shift 56 | + # asserts fail from install folder 57 | + if Gem.method(:host).source_location[0].start_with? "#{File.expand_path "../../..", __FILE__}/" 58 | + assert_equal "--prefix", arguments.shift 59 | + assert_equal Gem.prefix, arguments.shift 60 | + end 61 | assert_equal "--no-document", arguments.shift 62 | assert_equal "--previous-version", arguments.shift 63 | assert_equal Gem::VERSION, arguments.shift 64 | diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb 65 | index 34f85e6b75..e45ab6544c 100644 66 | --- a/test/rubygems/test_gem_ext_builder.rb 67 | +++ b/test/rubygems/test_gem_ext_builder.rb 68 | @@ -247,7 +247,7 @@ def test_build_extensions_extconf_bad 69 | gem_make_out = File.join @spec.extension_dir, "gem_make.out" 70 | cmd_make_out = File.read(gem_make_out) 71 | 72 | - assert_match %r{#{Regexp.escape Gem.ruby} .* extconf\.rb}, cmd_make_out 73 | + assert_match %r{/bin/ruby.exe( .*)? extconf\.rb}, cmd_make_out 74 | assert_match(/: No such file/, cmd_make_out) 75 | 76 | assert_path_not_exist @spec.gem_build_complete_path 77 | diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb 78 | index b970e442c2..e97bcf10be 100644 79 | --- a/test/rubygems/test_gem_ext_cargo_builder.rb 80 | +++ b/test/rubygems/test_gem_ext_cargo_builder.rb 81 | @@ -201,7 +201,8 @@ def skip_unsupported_platforms! 82 | system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out]) 83 | pend "cargo not present" unless $?.success? 84 | pend "ruby.h is not provided by ruby repo" if ruby_repo? 85 | - pend "rust toolchain of mingw is broken" if mingw_windows? 86 | + # ruby-loco pend "rust toolchain of mingw is broken" if mingw_windows? 87 | + pend "rust toolchains of mingw and msvc are broken" if mingw_windows? || vc_windows? 88 | end 89 | 90 | def assert_ffi_handle(bundle, name) 91 | diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb 92 | index f63c23c315..58c2326cc0 100644 93 | --- a/test/rubygems/test_require.rb 94 | +++ b/test/rubygems/test_require.rb 95 | @@ -466,7 +466,7 @@ def test_realworld_default_gem 96 | require "json" 97 | puts Gem.loaded_specs["json"] 98 | RUBY 99 | - output = Gem::Util.popen(*ruby_with_rubygems_in_load_path, "-e", cmd).strip 100 | + output = Gem::Util.popen("ruby", "-e", cmd).strip 101 | assert $?.success? 102 | refute_empty output 103 | end 104 | @@ -486,7 +486,8 @@ def test_realworld_upgraded_default_gem 105 | RUBY 106 | File.write(path, code) 107 | 108 | - output = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, path).strip 109 | + #output = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, path).strip 110 | + output = Gem::Util.popen({ "GEM_HOME" => @gemhome }, "ruby", path).strip 111 | refute_empty output 112 | assert_equal "999.99.9", output.lines[0].chomp 113 | # Make sure only files from the newer json gem are loaded, and no files from the default json gem 114 | -------------------------------------------------------------------------------- /old_patches/spec/ruby-core-file_time.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | See https://bugs.ruby-lang.org/issues/13726, update windows for updated file time 3 | resolution 4 | diff --git a/spec/ruby/core/file/atime_spec.rb b/spec/ruby/core/file/atime_spec.rb 5 | index d4106c0411..c791aa6d74 100644 6 | --- a/spec/ruby/core/file/atime_spec.rb 7 | +++ b/spec/ruby/core/file/atime_spec.rb 8 | @@ -15,7 +15,7 @@ 9 | File.atime(@file).should be_kind_of(Time) 10 | end 11 | 12 | - platform_is :linux do 13 | + guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do 14 | ## NOTE also that some Linux systems disable atime (e.g. via mount params) for better filesystem speed. 15 | it "returns the last access time for the named file with microseconds" do 16 | supports_subseconds = Integer(`stat -c%x '#{__FILE__}'`[/\.(\d+)/, 1], 10) 17 | diff --git a/spec/ruby/core/file/ctime_spec.rb b/spec/ruby/core/file/ctime_spec.rb 18 | index 50ffbe6a79..5753e0d90e 100644 19 | --- a/spec/ruby/core/file/ctime_spec.rb 20 | +++ b/spec/ruby/core/file/ctime_spec.rb 21 | @@ -14,7 +14,7 @@ 22 | File.ctime(@file).should be_kind_of(Time) 23 | end 24 | 25 | - platform_is :linux do 26 | + guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do 27 | it "returns the change time for the named file (the time at which directory information about the file was changed, not the file itself) with microseconds." do 28 | supports_subseconds = Integer(`stat -c%z '#{__FILE__}'`[/\.(\d+)/, 1], 10) 29 | if supports_subseconds != 0 30 | diff --git a/spec/ruby/core/file/mtime_spec.rb b/spec/ruby/core/file/mtime_spec.rb 31 | index 4c26cb5dac..d5769c0584 100644 32 | --- a/spec/ruby/core/file/mtime_spec.rb 33 | +++ b/spec/ruby/core/file/mtime_spec.rb 34 | @@ -15,7 +15,7 @@ 35 | File.mtime(@filename).should be_close(@mtime, 2.0) 36 | end 37 | 38 | - platform_is :linux do 39 | + guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do 40 | it "returns the modification Time of the file with microseconds" do 41 | supports_subseconds = Integer(`stat -c%y '#{__FILE__}'`[/\.(\d+)/, 1], 10) 42 | if supports_subseconds != 0 43 | diff --git a/spec/ruby/core/file/utime_spec.rb b/spec/ruby/core/file/utime_spec.rb 44 | index 542681ea93..64af82ef19 100644 45 | --- a/spec/ruby/core/file/utime_spec.rb 46 | +++ b/spec/ruby/core/file/utime_spec.rb 47 | @@ -1,6 +1,11 @@ 48 | require_relative '../../spec_helper' 49 | 50 | describe "File.utime" do 51 | + 52 | + before :all do 53 | + @time_is_float = /mswin|mingw/ =~ RUBY_PLATFORM && RUBY_VERSION >= '2.5' 54 | + end 55 | + 56 | before :each do 57 | @atime = Time.now 58 | @mtime = Time.now 59 | @@ -16,18 +21,33 @@ 60 | 61 | it "sets the access and modification time of each file" do 62 | File.utime(@atime, @mtime, @file1, @file2) 63 | - File.atime(@file1).to_i.should be_close(@atime.to_i, 2) 64 | - File.mtime(@file1).to_i.should be_close(@mtime.to_i, 2) 65 | - File.atime(@file2).to_i.should be_close(@atime.to_i, 2) 66 | - File.mtime(@file2).to_i.should be_close(@mtime.to_i, 2) 67 | + if @time_is_float 68 | + File.atime(@file1).should be_close(@atime, 0.0001) 69 | + File.mtime(@file1).should be_close(@mtime, 0.0001) 70 | + File.atime(@file2).should be_close(@atime, 0.0001) 71 | + File.mtime(@file2).should be_close(@mtime, 0.0001) 72 | + else 73 | + File.atime(@file1).to_i.should be_close(@atime.to_i, 2) 74 | + File.mtime(@file1).to_i.should be_close(@mtime.to_i, 2) 75 | + File.atime(@file2).to_i.should be_close(@atime.to_i, 2) 76 | + File.mtime(@file2).to_i.should be_close(@mtime.to_i, 2) 77 | + end 78 | end 79 | 80 | it "uses the current times if two nil values are passed" do 81 | + tn = Time.now 82 | File.utime(nil, nil, @file1, @file2) 83 | - File.atime(@file1).to_i.should be_close(Time.now.to_i, 2) 84 | - File.mtime(@file1).to_i.should be_close(Time.now.to_i, 2) 85 | - File.atime(@file2).to_i.should be_close(Time.now.to_i, 2) 86 | - File.mtime(@file2).to_i.should be_close(Time.now.to_i, 2) 87 | + if @time_is_float 88 | + File.atime(@file1).should be_close(tn, 0.050) 89 | + File.mtime(@file1).should be_close(tn, 0.050) 90 | + File.atime(@file2).should be_close(tn, 0.050) 91 | + File.mtime(@file2).should be_close(tn, 0.050) 92 | + else 93 | + File.atime(@file1).to_i.should be_close(Time.now.to_i, 2) 94 | + File.mtime(@file1).to_i.should be_close(Time.now.to_i, 2) 95 | + File.atime(@file2).to_i.should be_close(Time.now.to_i, 2) 96 | + File.mtime(@file2).to_i.should be_close(Time.now.to_i, 2) 97 | + end 98 | end 99 | 100 | it "accepts an object that has a #to_path method" do 101 | @@ -35,11 +55,19 @@ 102 | end 103 | 104 | it "accepts numeric atime and mtime arguments" do 105 | - File.utime(@atime.to_i, @mtime.to_i, @file1, @file2) 106 | - File.atime(@file1).to_i.should be_close(@atime.to_i, 2) 107 | - File.mtime(@file1).to_i.should be_close(@mtime.to_i, 2) 108 | - File.atime(@file2).to_i.should be_close(@atime.to_i, 2) 109 | - File.mtime(@file2).to_i.should be_close(@mtime.to_i, 2) 110 | + if @time_is_float 111 | + File.utime(@atime.to_f, @mtime.to_f, @file1, @file2) 112 | + File.atime(@file1).should be_close(@atime, 0.0001) 113 | + File.mtime(@file1).should be_close(@mtime, 0.0001) 114 | + File.atime(@file2).should be_close(@atime, 0.0001) 115 | + File.mtime(@file2).should be_close(@mtime, 0.0001) 116 | + else 117 | + File.utime(@atime.to_i, @mtime.to_i, @file1, @file2) 118 | + File.atime(@file1).to_i.should be_close(@atime.to_i, 2) 119 | + File.mtime(@file1).to_i.should be_close(@mtime.to_i, 2) 120 | + File.atime(@file2).to_i.should be_close(@atime.to_i, 2) 121 | + File.mtime(@file2).to_i.should be_close(@mtime.to_i, 2) 122 | + end 123 | end 124 | 125 | platform_is :linux do 126 | -------------------------------------------------------------------------------- /1_2_post_install.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # code by MSP-Greg 3 | 4 | require 'open3' 5 | require 'fileutils' 6 | require_relative '1_2_post_install_common.rb' 7 | 8 | module PostInstall2 9 | case ENV['MSYSTEM'] 10 | when 'UCRT64' 11 | D_INSTALL = File.join __dir__, 'ruby-ucrt' 12 | DLL_FN = 'x64-ucrt-ruby' 13 | when 'MINGW32' 14 | D_INSTALL = File.join __dir__, 'ruby-mingw32' 15 | DLL_FN = 'msvcrt-ruby' 16 | else 17 | D_INSTALL = File.join __dir__, 'ruby-mingw' 18 | DLL_FN = 'x64-msvcrt-ruby' 19 | end 20 | 21 | D_MSYS2 = ENV['D_MSYS2'] 22 | D_MINGW = "#{D_MSYS2}#{ENV['MINGW_PREFIX']}" 23 | 24 | D_RI2 = File.join __dir__, 'rubyinstaller2' 25 | # -REMOVE rbreadline- D_RL = File.join __dir__, 'ruby_readline' 26 | D_RUBY = File.join __dir__, 'ruby' 27 | 28 | COL_WID = 36 29 | COL_SPACE = ' ' * COL_WID 30 | 31 | class << self 32 | 33 | def run 34 | copy_dll_files 35 | PostInstall2Common.run 36 | add_priv_assm 37 | end 38 | 39 | private 40 | 41 | # Copies correct dll files from MSYS2 location to package dir. 42 | def copy_dll_files 43 | pkg_pre = ENV['MINGW_PACKAGE_PREFIX'] 44 | pkgs = 'gcc-libs gmp libffi libyaml openssl readline zlib' 45 | dll_files, lib_files = find_dlls pkgs, pkg_pre 46 | 47 | # get mingw bin path for arch 48 | msys2_dll_bin_path = "#{D_MINGW}/bin" 49 | 50 | # create and add manifest 51 | dest = File.join D_INSTALL, 'bin', 'ruby_builtin_dlls' 52 | Dir.mkdir dest unless Dir.exist? dest 53 | create_manifest dll_files, dest 54 | 55 | # copy bin/ dll's 56 | puts "#{'installing dll files:'.ljust(COL_WID)}FROM #{msys2_dll_bin_path}" 57 | dll_files.each { |fn| 58 | src = File.join msys2_dll_bin_path, fn 59 | if File.exist? src 60 | puts "#{COL_SPACE}#{fn}" 61 | cp src, File.join(dest, fn) 62 | else 63 | puts "#{COL_SPACE}ERROR: #{File.basename(fn)} does not exist" 64 | end 65 | } 66 | dll_dirs = lib_files.map{ | fn| File.dirname(fn) }.uniq 67 | dll_dirs.each { |d| 68 | src = File.join D_MINGW, "lib", d 69 | if Dir.exist?(src) 70 | dest = File.join D_INSTALL, 'bin', 'lib', d 71 | FileUtils.mkdir_p dest unless Dir.exist? dest 72 | `xcopy /s /q #{src.gsub('/', '\\')} #{dest.gsub('/', '\\')}` 73 | puts "#{COL_SPACE}Copy dir #{d}" 74 | else 75 | puts "#{COL_SPACE}ERROR: Dir #{src} does not exist" 76 | end 77 | } 78 | end 79 | 80 | # Adds private assembly data to ruby.exe and rubyw.exe files 81 | def add_priv_assm 82 | bin_dir = File.join D_INSTALL, "bin" 83 | Dir.chdir(bin_dir) { |d| 84 | ['ruby.exe', 'rubyw.exe'].each { |fn| 85 | image = File.binread fn 86 | image.sub!(/^/, ' ') 88 | File.binwrite fn, image 89 | } 90 | } 91 | end 92 | 93 | def cp(src, dest) 94 | unless Dir.exist? (dest_dir = File.dirname dest) 95 | FileUtils.mkdir_p dest_dir 96 | end 97 | FileUtils.copy_file(src, dest, preserve: true) 98 | end 99 | 100 | # Creates manifest xml file 101 | # @param dlls [Array] file list 102 | # @param dest [Array] dest dir for manifest file 103 | def create_manifest(dlls, dest) 104 | manifest = +"\n" \ 105 | "\n" \ 106 | " \n" 107 | dlls.each { |fn| manifest << " \n" } 108 | manifest << "\n" 109 | File.open( File.join(dest, 'ruby_builtin_dlls.manifest'), 'wb') { |f| f << manifest } 110 | end 111 | 112 | def find_dlls(pkgs, pkg_pre) 113 | orig_path = ENV['PATH'] 114 | ENV['PATH'] = "#{File.join D_MSYS2, 'usr/bin'};#{orig_path}" 115 | re_dep = /^Depends On +: +([^\r\n]+)/i 116 | dir = ENV['MINGW_PREFIX'][1..-1] 117 | re_bin = /\A\S+ \/#{dir}\/bin\//i 118 | re_lib = /\A\S+ \/#{dir}\/lib\//i 119 | bin_dlls = [] 120 | lib_dlls = [] 121 | pkg_files_added = [] 122 | # add correct package prefix 123 | pkgs = pkgs.split(' ').map { |e| "#{pkg_pre}-#{e}"} 124 | 125 | while !pkgs.empty? do 126 | depends = [] 127 | files = `pacman.exe -Ql #{pkgs.join(' ')} | grep dll` 128 | files.each_line(chomp: true) { |dll| 129 | next unless dll.end_with? '.dll' 130 | if dll.match? re_bin ; bin_dlls << dll.sub(re_bin, '') 131 | elsif dll.match? re_lib ; lib_dlls << dll.sub(re_lib, '') 132 | else 133 | puts "#{dll.ljust(COL_WID)} Unknown dll location!" 134 | end 135 | } 136 | pkg_files_added += pkgs 137 | if info = `pacman.exe -Qi #{pkgs.join(' ')}` 138 | info.scan(re_dep) { |dep| 139 | next if /\ANone/ =~ dep[0] 140 | depends += dep[0].split(/\s+/) 141 | } 142 | if depends && !depends.empty? 143 | depends.uniq! 144 | depends.reject! { |e| pkg_files_added.include?(e) } 145 | unless depends.empty? 146 | stdin, stdout, stderr = Open3.popen3("pacman -Q #{depends.join(' ')}") 147 | errs = stderr.read 148 | stdin.close ; stdout.close ; stderr.close 149 | if errs && !errs.strip.empty? 150 | errs.scan(/'([^']+)'/) { |e| 151 | depends[depends.index(e[0])] += '-git' 152 | } 153 | end 154 | end 155 | end 156 | end 157 | pkgs = depends 158 | end 159 | ENV['PATH'] = orig_path 160 | [ ( bin_dlls.uniq.sort || [] ), ( lib_dlls.uniq.sort || [] ) ] 161 | end 162 | 163 | end 164 | end 165 | PostInstall2.run -------------------------------------------------------------------------------- /1_3_post_install.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # Code by MSP-Greg 3 | 4 | require 'fileutils' 5 | 6 | module PostInstall3 7 | case ENV['MSYSTEM'] 8 | when 'UCRT64' 9 | D_INSTALL = File.join __dir__, 'ruby-ucrt' 10 | when 'MINGW32' 11 | D_INSTALL = File.join __dir__, 'ruby-mingw32' 12 | else 13 | D_INSTALL = File.join __dir__, 'ruby-mingw' 14 | end 15 | 16 | COL_WID = 36 17 | COL_SPACE = ' ' * COL_WID 18 | 19 | D_MSYS2 = ENV['D_MSYS2'] 20 | D_RI2 = File.join __dir__, 'rubyinstaller2' 21 | # -REMOVE rbreadline- D_RL = File.join __dir__, 'ruby_readline' 22 | D_RUBY = File.join __dir__, 'ruby' 23 | 24 | # internal version like 2.5.0 25 | ABI = RbConfig::CONFIG["ruby_version"] 26 | 27 | REWRITE_MARK = /^( *)module Build.*Use for: Build, Runtime/ 28 | 29 | # Files to copy from RI2 repo to ruby package / install dir 30 | RI2_FILES = [ 31 | ["bin", %w| 32 | resources/files/ridk.cmd 33 | resources/files/ridk.ps1 34 | resources/files/setrbvars.cmd | ], 35 | 36 | ["lib/ruby/#{ABI}/rubygems/defaults", %w| 37 | resources\files\operating_system.rb | ], 38 | 39 | ["lib/ruby/site_ruby/#{ABI}", %w| 40 | resources\files\irbrc_predefiner.rb | ], 41 | ] 42 | BINDIR = RbConfig::CONFIG['bindir'] 43 | TOPDIR = RbConfig::TOPDIR 44 | # path to site_ruby dir 45 | SITE_RUBY = File.join TOPDIR, 'lib', 'ruby', 'site_ruby', ABI 46 | 47 | class << self 48 | 49 | def run 50 | add_ri2 51 | add_ri2_site_ruby 52 | generate_version_file 53 | update_gems 54 | end 55 | 56 | private 57 | 58 | # Add files defined in {RI2_FILES} from RI2 59 | def add_ri2 60 | puts "#{'installing RubyInstaller2:'.ljust(COL_WID)}From #{D_RI2}" 61 | Dir.chdir(TOPDIR) { |d| 62 | RI2_FILES.each { |i| 63 | dest_dir = File.join(TOPDIR, i[0]) 64 | FileUtils.mkdir_p dest_dir unless Dir.exist?(dest_dir) 65 | i[1].each { |fn| 66 | fp = "#{D_RI2}/#{fn}" 67 | if File.exist?(fp) 68 | puts "#{COL_SPACE}#{fn}" 69 | #`copy /b /y #{fp.gsub('/', '\\')} #{i[0]}` 70 | FileUtils.cp fp, dest_dir, preserve: true 71 | else 72 | puts "#{COL_SPACE}#{fn} DOES NOT exist!" 73 | end 74 | } 75 | } 76 | #Dir.chdir("lib/ruby/#{ABI}/rubygems/defaults") { |d| 77 | # patch_exe = File.join D_MSYS2, "usr", "bin", "patch.exe" 78 | # patch = `#{patch_exe} -p1 -N --no-backup-if-mismatch -i #{__dir__}/patches/__operating_system.rb.patch` 79 | # puts "#{COL_SPACE}#{patch}" 80 | #} 81 | } 82 | end 83 | 84 | # Adds files to ruby_installer/runtime dir 85 | def add_ri2_site_ruby 86 | src = File.join(D_RI2, 'lib') # .gsub('/', '\\') # + "\\" 87 | site_ruby = SITE_RUBY # .gsub('/', '\\') 88 | puts "#{'installing RI2 runtime files:'.ljust(COL_WID)}From #{src}" 89 | puts "#{COL_SPACE}To #{site_ruby}" 90 | # copy everything over to pkg/install dir 91 | #`xcopy /s /q /y #{src} #{site_ruby}` 92 | FileUtils.copy_entry src, site_ruby, preserve: true 93 | # now, loop thru build dir, and move to runtime 94 | Dir.chdir( File.join(SITE_RUBY, 'ruby_installer') ) { |d| 95 | Dir.glob('build/*.rb').each { |fn| 96 | f_str = File.binread(fn) 97 | if f_str.sub!(REWRITE_MARK, '\1module Runtime # Rewrite') 98 | puts "#{COL_SPACE}rewrite #{fn[6..-1]}" 99 | File.open( File.join( 'runtime', fn[6..-1]), 'wb') { |f| f << f_str } 100 | end 101 | } 102 | `rd /s /q build` 103 | puts "#{COL_SPACE}deleting build dir" 104 | } 105 | end 106 | 107 | # Creates ruby_installer/runtime/package_version.rb file 108 | def generate_version_file 109 | ri2_vers = '' 110 | commit = '' 111 | Dir.chdir(D_RI2) { 112 | commit = `git rev-parse HEAD`[0,7] 113 | if (str = File.binread( File.join('.', 'packages', 'ri', 'Rakefile') )[/^[ \t]*ruby_arch_packages[ \t]*=[^\n]*\n[ \t]*%w\[([\d .-]+)/,1]) 114 | ri2_vers = str.split[-1] 115 | else 116 | ri2_vers = `git tag --list "rubyinstaller-[0-9]*"`[/^rubyinstaller-(\S+)\Z/, 1] 117 | end 118 | } 119 | puts "#{'creating package_version.rb:'.ljust(COL_WID)}#{ri2_vers} commit #{commit}" 120 | puts "#{COL_SPACE}#{commit}" 121 | 122 | f_str = <<~EOT 123 | module RubyInstaller 124 | module Runtime 125 | PACKAGE_VERSION = "ruby-loco RI2 #{ri2_vers}" 126 | GIT_COMMIT = "#{commit}" 127 | end 128 | end 129 | EOT 130 | dest = File.join(SITE_RUBY, 'ruby_installer', 'runtime', 'package_version.rb') 131 | File.binwrite(dest, f_str) 132 | end 133 | 134 | # No changes to trunk/master 135 | def update_gems 136 | require 'rubygems' 137 | require 'rubygems/gem_runner' 138 | suffix = %w[--no-document --env-shebang --silent --norc] 139 | if RUBY_DESCRIPTION.include? 'master' 140 | # added as of r65509 141 | # Gem::GemRunner.new.run(%w[install bundler] + suffix) 142 | else 143 | # Gem::GemRunner.new.run %w[uninstall rubygems-update -x] 144 | # rdoc won't update without UI confirmation of bin directory file replacement ? 145 | Gem::GemRunner.new.run(%w[update minitest power_assert rake rdoc test-unit] + suffix) 146 | if RUBY_VERSION.start_with? '2.4' 147 | Gem::GemRunner.new.run(%w[update did_you_mean] + suffix) 148 | elsif RUBY_VERSION.start_with? '2.3' 149 | Gem::GemRunner.new.run(%w[install did_you_mean:1.0.3] + suffix) 150 | end 151 | Gem::GemRunner.new.run %w[cleanup] 152 | if RUBY_VERSION < "2.6" 153 | Gem::GemRunner.new.run(%w[install bundler] + suffix) 154 | end 155 | end 156 | # clean empty gem folders, needed as of 2019-10-20 157 | ary = Dir["#{Gem.dir}/gems/*"] 158 | ary.each { |d| Dir.rmdir(d) if Dir.empty?(d) } 159 | end 160 | end 161 | end 162 | PostInstall3.run 163 | -------------------------------------------------------------------------------- /old_patches/spec/mspec_multi_v.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | Allows -V option to be used with -j 3 | diff --git a/spec/mspec/lib/mspec/runner/formatters/multi.rb b/spec/mspec/lib/mspec/runner/formatters/multi.rb 4 | index 5932eeef62..917c23bc53 100644 5 | --- a/spec/mspec/lib/mspec/runner/formatters/multi.rb 6 | +++ b/spec/mspec/lib/mspec/runner/formatters/multi.rb 7 | @@ -1,6 +1,12 @@ 8 | -require 'mspec/runner/formatters/spinner' 9 | - 10 | -class MultiFormatter < SpinnerFormatter 11 | +if MSpecScript.config[:verbose] 12 | + require_relative 'dotted' 13 | + multi_super = DottedFormatter 14 | +else 15 | + require_relative 'spinner' 16 | + multi_super = SpinnerFormatter 17 | +end 18 | + 19 | +class MultiFormatter < multi_super 20 | def initialize(out=nil) 21 | super(out) 22 | @counter = @tally = Tally.new 23 | @@ -34,7 +40,13 @@ def print_exception(exc, count) 24 | print "\n#{count})\n#{exc}\n" 25 | end 26 | 27 | - def finish 28 | - super(false) 29 | + if MSpecScript.config[:verbose] 30 | + def start ; end 31 | + def unload ; end 32 | + def finish(_ = nil) ; super() ; end 33 | + else 34 | + def finish ; super(false) ; end 35 | end 36 | + 37 | + 38 | end 39 | diff --git a/spec/mspec/lib/mspec/runner/formatters/yaml.rb b/spec/mspec/lib/mspec/runner/formatters/yaml.rb 40 | index 090a9b1b9d..245144bc49 100644 41 | --- a/spec/mspec/lib/mspec/runner/formatters/yaml.rb 42 | +++ b/spec/mspec/lib/mspec/runner/formatters/yaml.rb 43 | @@ -4,11 +4,16 @@ 44 | class YamlFormatter < DottedFormatter 45 | def initialize(out=nil) 46 | super(nil) 47 | - 48 | - if out.nil? 49 | - @finish = $stdout 50 | + if MSpecScript.config[:verbose] 51 | + @examples_last = 0 52 | + @expectations_last = 0 53 | + @finish = out.nil? ? $stdout : File.open(out, "w") 54 | else 55 | - @finish = File.open out, "w" 56 | + if out.nil? 57 | + @finish = $stdout 58 | + else 59 | + @finish = File.open out, "w" 60 | + end 61 | end 62 | end 63 | 64 | @@ -16,7 +21,21 @@ def switch 65 | @out = @finish 66 | end 67 | 68 | - def after(state) 69 | + def after(state) ; end 70 | + 71 | + if MSpecScript.config[:verbose] 72 | + def register 73 | + super 74 | + MSpec.register :unload, self 75 | + end 76 | + 77 | + def unload 78 | + file_examples = @tally.counter.examples - @examples_last 79 | + file_expectations = @tally.counter.expectations - @expectations_last 80 | + @examples_last = @tally.counter.examples 81 | + @expectations_last = @tally.counter.expectations 82 | + ::STDOUT.write ".#{file_examples}.#{file_expectations}" 83 | + end 84 | end 85 | 86 | def finish 87 | diff --git a/spec/mspec/lib/mspec/runner/parallel.rb b/spec/mspec/lib/mspec/runner/parallel.rb 88 | index 7428b33682..0dad7803e1 100644 89 | --- a/spec/mspec/lib/mspec/runner/parallel.rb 90 | +++ b/spec/mspec/lib/mspec/runner/parallel.rb 91 | @@ -1,4 +1,5 @@ 92 | class ParallelRunner 93 | + 94 | def initialize(files, processes, formatter, argv) 95 | @files = files 96 | @processes = processes 97 | @@ -6,6 +7,14 @@ def initialize(files, processes, formatter, argv) 98 | @argv = argv 99 | @last_files = {} 100 | @output_files = [] 101 | + if MSpecScript.config[:verbose] 102 | + @cntr = 1 103 | + @pid_alpha = {} 104 | + @ttl_files = @files.length 105 | + wid = @ttl_files.to_s.length 106 | + @fmt = "[%#{wid}d/%#{wid}d] %1s %4s %5s %s\n" 107 | + end 108 | + @files.shuffle! if MSpec.randomize? 109 | @success = true 110 | end 111 | 112 | @@ -28,6 +37,16 @@ def handle(child, message) 113 | case message 114 | when '.' 115 | @formatter.unload 116 | + if MSpecScript.config[:verbose] 117 | + while chunk = (child.read_nonblock(64) rescue nil) 118 | + message += chunk 119 | + end 120 | + message.gsub!(/^\.+|\.+$/, '') 121 | + vals = message.split '.' 122 | + fn = @last_files[child][/spec\/ruby\/(\S+)$/,1] 123 | + ::STDOUT.write format(@fmt, @cntr, @ttl_files ,@pid_alpha[child], vals[0], vals[1], fn) 124 | + @cntr += 1 125 | + end 126 | send_new_file_or_quit(child) 127 | else 128 | if message == nil 129 | @@ -79,9 +98,17 @@ def run 130 | 131 | puts @children.map { |child| child.gets }.uniq 132 | @formatter.start 133 | - begin 134 | - @children.each { |child| send_new_file_or_quit(child) } 135 | 136 | + if MSpecScript.config[:verbose] 137 | + wid = @ttl_files.to_s.length 138 | + STDOUT.puts " #{' ' * wid * 2} PID Examples Exp File" 139 | + end 140 | + 141 | + begin 142 | + @children.each_with_index { |child, idx| 143 | + @pid_alpha[child] = (idx + 65).chr if MSpecScript.config[:verbose] 144 | + send_new_file_or_quit(child) 145 | + } 146 | until @children.empty? 147 | IO.select(@children)[0].each { |child| 148 | handle(child, child.read(1)) 149 | diff --git a/spec/mspec/lib/mspec/utils/options.rb b/spec/mspec/lib/mspec/utils/options.rb 150 | index 9f8dd01dbf..30f2c8448e 100644 151 | --- a/spec/mspec/lib/mspec/utils/options.rb 152 | +++ b/spec/mspec/lib/mspec/utils/options.rb 153 | @@ -390,16 +390,20 @@ def repeat 154 | 155 | def verbose 156 | on("-V", "--verbose", "Output the name of each file processed") do 157 | - obj = Object.new 158 | - def obj.start 159 | - @width = MSpec.retrieve(:files).inject(0) { |max, f| f.size > max ? f.size : max } 160 | - end 161 | - def obj.load 162 | - file = MSpec.retrieve :file 163 | - STDERR.print "\n#{file.ljust(@width)}" 164 | + if MSpecScript.config[:multi] || ENV['MSPEC_MULTI'] 165 | + config[:verbose] = true 166 | + else 167 | + obj = Object.new 168 | + def obj.start 169 | + @width = MSpec.retrieve(:files).inject(0) { |max, f| f.size > max ? f.size : max } 170 | + end 171 | + def obj.load 172 | + file = MSpec.retrieve :file 173 | + STDERR.print "\n#{file.ljust(@width)}" 174 | + end 175 | + MSpec.register :start, obj 176 | + MSpec.register :load, obj 177 | end 178 | - MSpec.register :start, obj 179 | - MSpec.register :load, obj 180 | end 181 | 182 | on("-m", "--marker", "MARKER", 183 | -------------------------------------------------------------------------------- /old_patches/15310_0001-thread_pthread.c-close-race-from-UBF_TIMER-and-non-G.patch: -------------------------------------------------------------------------------- 1 | From f5dd3244ffce8193ca5c9e2361d748ec51a75dc6 Mon Sep 17 00:00:00 2001 2 | From: Eric Wong 3 | Date: Thu, 15 Nov 2018 23:56:07 +0000 4 | Subject: [PATCH] thread_pthread.c: close race from UBF_TIMER and 5 | non-GVL-releasing thread 6 | 7 | A Ruby thread may run without releasing the GVL if there is no 8 | contention. And there may be no contention because another 9 | thread missed its wakeup and needs to rely on ubf_list for 10 | wakeups. So we need to ensure the Ruby thread can relinquish 11 | GVL and trigger ubf_list wakeups to target thread when the POSIX 12 | timer fires. 13 | 14 | Thus, we trigger a timeslice on SIGVTALRM when triggered by 15 | UBF_TIMER (we do not want excessive switching overhead on every 16 | SIGVTALRM signal, either). 17 | --- 18 | configure.ac | 1 + 19 | thread.c | 3 ++- 20 | thread_pthread.c | 56 ++++++++++++++++++++++++++++++++++++++---------- 21 | 3 files changed, 48 insertions(+), 12 deletions(-) 22 | 23 | diff --git a/configure.ac b/configure.ac 24 | index 2dc4fd36ae..dfc0e527e1 100644 25 | --- a/configure.ac 26 | +++ b/configure.ac 27 | @@ -1908,6 +1908,7 @@ AC_CHECK_FUNCS(shutdown) 28 | AC_CHECK_FUNCS(sigaction) 29 | AC_CHECK_FUNCS(sigaltstack) 30 | AC_CHECK_FUNCS(sigprocmask) 31 | +AC_CHECK_FUNCS(sigqueue) 32 | AC_CHECK_FUNCS(sinh) 33 | AC_CHECK_FUNCS(spawnv) 34 | AC_CHECK_FUNCS(symlink) 35 | diff --git a/thread.c b/thread.c 36 | index 0711ef5552..5531546e84 100644 37 | --- a/thread.c 38 | +++ b/thread.c 39 | @@ -4238,12 +4238,13 @@ rb_threadptr_check_signal(rb_thread_t *mth) 40 | } 41 | } 42 | 43 | +/* async-signal-safe */ 44 | static void 45 | timer_thread_function(void) 46 | { 47 | volatile rb_execution_context_t *ec; 48 | 49 | - /* for time slice */ 50 | + /* for time slice, this relies on GC for grace period */ 51 | ec = ACCESS_ONCE(rb_execution_context_t *, 52 | ruby_current_execution_context_ptr); 53 | if (ec) RUBY_VM_SET_TIMER_INTERRUPT(ec); 54 | diff --git a/thread_pthread.c b/thread_pthread.c 55 | index 1f2ac00b67..c9edfbf488 100644 56 | --- a/thread_pthread.c 57 | +++ b/thread_pthread.c 58 | @@ -46,6 +46,8 @@ 59 | 60 | #if defined(SIGVTALRM) && !defined(__CYGWIN__) 61 | # define USE_UBF_LIST 1 62 | +static LIST_HEAD(ubf_list_head); 63 | +static rb_nativethread_lock_t ubf_list_lock = RB_NATIVETHREAD_LOCK_INIT; 64 | #endif 65 | 66 | /* 67 | @@ -542,11 +544,20 @@ native_cond_timeout(rb_nativethread_cond_t *cond, const rb_hrtime_t rel) 68 | 69 | static pthread_key_t ruby_native_thread_key; 70 | 71 | +#if defined(HAVE_SIGACTION) && defined(USE_UBF_LIST) 72 | static void 73 | -null_func(int i) 74 | +vtalrm_func(int sig, siginfo_t *info, void *ctx) 75 | { 76 | - /* null */ 77 | + /* 78 | + * if triggered by UBF_TIMER, force running thread to call 79 | + * ubf_wakeup_all_threads via gvl_yield 80 | + */ 81 | + if (info && info->si_ptr == &ubf_list_head) 82 | + timer_thread_function(); 83 | } 84 | +#else /* do any platforms have pthreads, SIGVTALRM, but no sigaction? */ 85 | +static void vtalrm_func(int sig) { /* noop */ } 86 | +#endif /* HAVE_SIGACTION && USE_UBF_LIST */ 87 | 88 | static rb_thread_t * 89 | ruby_thread_from_native(void) 90 | @@ -578,7 +589,19 @@ Init_native_thread(rb_thread_t *th) 91 | th->thread_id = pthread_self(); 92 | fill_thread_id_str(th); 93 | native_thread_init(th); 94 | - posix_signal(SIGVTALRM, null_func); 95 | +#if defined(HAVE_SIGACTION) && defined(USE_UBF_LIST) 96 | + { 97 | + struct sigaction sa; 98 | + 99 | + sigemptyset(&sa.sa_mask); 100 | + sa.sa_sigaction = vtalrm_func; 101 | + sa.sa_flags = SA_SIGINFO; 102 | + if (sigaction(SIGVTALRM, &sa, 0) != 0) 103 | + rb_async_bug_errno("sigaction", errno); 104 | + } 105 | +#else 106 | + posix_signal(SIGVTALRM, vtalrm_func); 107 | +#endif 108 | } 109 | 110 | static void 111 | @@ -1269,8 +1292,6 @@ native_cond_sleep(rb_thread_t *th, rb_hrtime_t *rel) 112 | } 113 | 114 | #ifdef USE_UBF_LIST 115 | -static LIST_HEAD(ubf_list_head); 116 | -static rb_nativethread_lock_t ubf_list_lock = RB_NATIVETHREAD_LOCK_INIT; 117 | 118 | static void 119 | ubf_list_atfork(void) 120 | @@ -1677,7 +1698,7 @@ ubf_timer_pthread_create(rb_pid_t current) 121 | if (setup_communication_pipe_internal(timer_pthread.low) < 0) 122 | return; 123 | 124 | - err = pthread_create(&timer_pthread.thid, 0, timer_pthread_fn, GET_VM()); 125 | + err = pthread_create(&timer_pthread.thid, 0, timer_pthread_fn, 0); 126 | if (!err) 127 | timer_pthread.owner = current; 128 | else 129 | @@ -1700,7 +1721,7 @@ ubf_timer_create(rb_pid_t current) 130 | 131 | sev.sigev_notify = SIGEV_SIGNAL; 132 | sev.sigev_signo = SIGVTALRM; 133 | - sev.sigev_value.sival_ptr = &timer_posix; 134 | + sev.sigev_value.sival_ptr = &ubf_list_head; 135 | if (!timer_create(UBF_TIMER_CLOCK, &sev, &timer_posix.timerid)) 136 | timer_posix.owner = current; 137 | else 138 | @@ -2084,11 +2105,24 @@ native_sleep(rb_thread_t *th, rb_hrtime_t *rel) 139 | } 140 | 141 | #if UBF_TIMER == UBF_TIMER_PTHREAD 142 | +static void 143 | +timer_pthread_sigqueue(rb_pid_t pid, int sig) 144 | +{ 145 | +#if defined(HAVE_SIGQUEUE) && defined(HAVE_SIGACTION) 146 | + union sigval sv; 147 | + 148 | + sv.sival_ptr = &ubf_list_head; 149 | + if (sigqueue(pid, sig, sv) != 0) 150 | + rb_async_bug_errno("sigqueue", errno); 151 | +#else 152 | + kill(pid, sig); 153 | +#endif 154 | +} 155 | + 156 | static void * 157 | -timer_pthread_fn(void *p) 158 | +timer_pthread_fn(void *ignore) 159 | { 160 | - rb_vm_t *vm = p; 161 | - pthread_t main_thread_id = vm->main_thread->thread_id; 162 | + rb_pid_t pid = getpid(); 163 | struct pollfd pfd; 164 | int timeout = -1; 165 | 166 | @@ -2100,7 +2134,7 @@ timer_pthread_fn(void *p) 167 | (void)consume_communication_pipe(pfd.fd); 168 | 169 | if (system_working > 0 && ATOMIC_CAS(timer_pthread.armed, 1, 1)) { 170 | - pthread_kill(main_thread_id, SIGVTALRM); 171 | + timer_pthread_sigqueue(pid, SIGVTALRM); 172 | 173 | if (rb_signal_buff_size() || !ubf_threads_empty()) { 174 | timeout = TIME_QUANTUM_MSEC; 175 | -- 176 | EW 177 | 178 | -------------------------------------------------------------------------------- /trunk_msys2.ps1: -------------------------------------------------------------------------------- 1 | $orig_path = $env:path 2 | 3 | $key = 'D688DA4A77D8FA18' 4 | $ks1 = 'hkp://pool.sks-keyservers.net' 5 | $ks2 = 'hkp://pgp.mit.edu' 6 | 7 | $msys2 = 'C:\msys64' 8 | # OpenSSL 1.1.1 release 9 | $openssl = 'mingw-w64-x86_64-openssl-1.1.1-1-any.pkg.tar.xz' 10 | $openssl_sha = '0c8be3277693f60c319f997659c2fed0eadce8535aed29a4617ec24da082b60ee30a03d3fe1024dae4461041e6e9a5e5cff1a68fa08b4b8791ea1bf7b02abc40' 11 | $dl_uri = 'https://ci.appveyor.com/api/projects/MSP-Greg/ruby-makepkg-mingw/artifacts' 12 | 13 | #$openssl = 'mingw-w64-x86_64-openssl-1.1.0.i-1-any.pkg.tar.xz' 14 | #$dl_uri = 'https://ci.appveyor.com/api/projects/MSP-Greg/ruby-makepkg-mingw/artifacts' 15 | 16 | $wc = $(New-Object System.Net.WebClient) 17 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 18 | 19 | $dash = "$([char]0x2015)" 20 | $pkgs = "C:\pkgs" 21 | $pkgs_u = $pkgs.replace('\', '/') 22 | 23 | $env:path = "$msys2\usr\bin;C:\Ruby25-x64\bin;C:\Program Files\7-Zip;C:\Program Files\AppVeyor\BuildAgent;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Program Files;C:\Windows" 24 | 25 | $pre = "mingw-w64-x86_64-" 26 | $fc = 'Yellow' 27 | 28 | #——————————————————————————————————————————————————————————————————— Check-Exit 29 | # checks whether to exit 30 | function Check-Exit($msg, $pop) { 31 | if ($LastExitCode -and $LastExitCode -ne 0) { 32 | if ($pop) { Pop-Location } 33 | Write-Host $msg -ForegroundColor $fc 34 | exit 1 35 | } 36 | } 37 | 38 | #——————————————————————————————————————————————————————————————————— Check_SHA 39 | # checks SHA512 from file, script variable & Appveyor message 40 | function Check-SHA($path, $file, $uri_dl, $sha_local) { 41 | $uri_bld = $uri_dl -replace '/artifacts$', '' 42 | $obj_bld = ConvertFrom-Json -InputObject $(Invoke-WebRequest -Uri $uri_bld) 43 | $job_id = $obj_bld.build.jobs[0].jobId 44 | 45 | $json_msgs = Invoke-WebRequest -Uri "https://ci.appveyor.com/api/buildjobs/$job_id/messages" 46 | $obj_msgs = ConvertFrom-Json -InputObject $json_msgs 47 | $sha_msg = $($obj_msgs.list | Where {$_.message -eq $($file + '_SHA512')}).details 48 | 49 | $sha_file = $(CertUtil -hashfile $path\$file SHA512).split("`r`n")[1].replace(' ', '') 50 | if ($sha_local -ne '') { 51 | if (($sha_msg -eq $sha_file) -and ($sha_local -eq $sha_file)) { 52 | Write-Host "Three SHA512 values match for file, Appveyor message, and local script" -ForegroundColor $fc 53 | } else { 54 | Write-Host SHA512 values do not match -ForegroundColor $fc 55 | exit 1 56 | } 57 | } else { 58 | if ($sha_msg -eq $sha_file) { 59 | Write-Host SHA512 matches for file and Appveyor message -ForegroundColor $fc 60 | } else { 61 | Write-Host SHA512 values do not match -ForegroundColor $fc 62 | exit 1 63 | } 64 | } 65 | } 66 | 67 | #——————————————————————————————————————————————————————————————————— Update MSYS2 68 | 69 | <#—————————————————————————————————————————————— 30-Aug-2018 Fully updated on Appveyor 70 | # Only use below for really outdated systems, as it wil perform a full update 71 | # for 'newer' systems... 72 | Write-Host "$($dash * 63) Updating MSYS2 / MinGW -Syu" -ForegroundColor $fc 73 | pacman.exe -Syu --noconfirm --needed --noprogressbar 74 | Check-Exit 'Cannot update with -Syu' 75 | 76 | Write-Host "$($dash * 63) Updating MSYS2 / MinGW base" -ForegroundColor $fc 77 | # change to -Syu if above is commented out 78 | pacman.exe -S --noconfirm --needed --noprogressbar base 2> $null 79 | # Check-Exit 'Cannot update base' 80 | #> 81 | 82 | # Some issue with needing to update before toolchain. Check whether it can move 83 | # back to after toolchain update 84 | #Write-Host "$($dash * 63) Updating MSYS2 / MinGW ruby depends 1" -ForegroundColor Yellow 85 | #$tools = "___readline".replace('___', $pre) 86 | #pacman.exe -Sy --noconfirm --needed --noprogressbar $tools.split(' ') 2> $null 87 | 88 | Write-Host "$($dash * 63) Updating MSYS2 / MinGW toolchain" -ForegroundColor $fc 89 | #pacman.exe -Sy --noconfirm --noprogressbar --needed $($pre + 'toolchain') 2> $null 90 | #$tools = " ___binutils ___isl ___libiconv ___mpc ___windows-default-manifest ___libwinpthread ___winpthreads ___gcc-libs ___gcc".replace('___', $pre) 91 | $tools = " ___binutils ___crt ___headers ___isl ___libiconv ___mpc ___windows-default-manifest ___libwinpthread ___winpthreads ___gcc-libs ___gcc".replace('___', $pre) 92 | pacman.exe -Syd --noconfirm --noprogressbar --needed $tools.split(' ') 2> $null 93 | Check-Exit 'Cannot update toolchain' 94 | 95 | Write-Host "$($dash * 63) Updating MSYS2 / MinGW ruby depends 2" -ForegroundColor Yellow 96 | $tools = "___dlfcn ___gdbm ___gmp ___libffi ___libyaml ___openssl ___ragel ___readline ___zlib".replace('___', $pre) 97 | pacman.exe -S --noconfirm --noprogressbar --needed $tools.split(' ') 2> $null 98 | Check-Exit 'Cannot update dependencies' 99 | 100 | # As of Sept-2018 libyaml is not installed on Appveyor 101 | # pacman -Rdd --noconfirm mingw-w64-x86_64-libyaml 102 | 103 | <# 104 | #——————————————————————————————————————————————————————————————————— Add GPG key 105 | Write-Host "$($dash * 63) Adding GPG key" -ForegroundColor Yellow 106 | Write-Host "try retrieving & signing key" -ForegroundColor Yellow 107 | 108 | $t1 = "`"pacman-key -r $key --keyserver $ks1 && pacman-key -f $key && pacman-key --lsign-key $key`"" 109 | Appveyor-Retry bash.exe -c $t1 2> $null 110 | # below is for occasional key retrieve failure on Appveyor 111 | if ($LastExitCode -and $LastExitCode -ne 0) { 112 | Write-Host GPG Key Lookup failed from $ks1 -ForegroundColor Yellow 113 | # try another keyserver 114 | $t1 = "`"pacman-key -r $key --keyserver $ks2 && pacman-key -f $key && pacman-key --lsign-key $key`"" 115 | Appveyor-Retry bash.exe -c $t1 1> $null 116 | if ($LastExitCode -and $LastExitCode -ne 0) { 117 | Write-Host GPG Key Lookup failed from $ks2 -ForegroundColor Yellow 118 | Update-AppveyorBuild -Message "keyserver retrieval failed" 119 | exit $LastExitCode 120 | } else { Write-Host GPG Key Lookup succeeded from $ks2 } 121 | } else { Write-Host GPG Key Lookup succeeded from $ks1 } 122 | #> 123 | 124 | if ( !(Test-Path -Path $pkgs -PathType Container) ) { 125 | New-Item -Path $pkgs -ItemType Directory 1> $null 126 | } 127 | 128 | <# USE STANDARD MSYS2 1.1.1 package see line 87 ($tools = ... ) 129 | #——————————————————————————————————————————————————————————————————— Add openssl 130 | Write-Host "$($dash * 63) Install custom openssl" -ForegroundColor Yellow 131 | Write-Host "Installing $openssl" 132 | 133 | $wc.DownloadFile("$dl_uri/$openssl", "$pkgs\$openssl") 134 | #$wc.DownloadFile("$dl_uri/$openssl" + ".sig", "$pkgs\$openssl" + ".sig") 135 | Check-SHA $pkgs $openssl $dl_uri $openssl_sha 136 | 137 | Write-Host "pacman.exe -Rdd --noconfirm mingw-w64-x86_64-openssl" -ForegroundColor Yellow 138 | pacman.exe -Rdd --noconfirm mingw-w64-x86_64-openssl 139 | Write-Host "pacman.exe -Udd --noconfirm $pkgs_u/$openssl" -ForegroundColor Yellow 140 | pacman.exe -Udd --noconfirm $pkgs_u/$openssl 141 | if ($LastExitCode) { 142 | Write-Host "Error installing openssl" -ForegroundColor Yellow 143 | exit 1 144 | } else { Write-Host "Finished" } 145 | #> 146 | 147 | Write-Host "$($dash * 63) MinGW Package Check" -ForegroundColor Yellow 148 | bash -c "pacman -Qs x86_64\.\+\(gcc\|gdbm\|openssl\) | sed -n '/^local/p' | sed 's/^local\///' | sed 's/ (.\+$//'" 149 | Write-Host "$($dash * 83)" -ForegroundColor Yellow 150 | $env:path = $orig_path 151 | -------------------------------------------------------------------------------- /old_patches/spec/ruby-mingw_additions.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | Add spec tests that pass on newer MinGW builds 3 | diff --git a/spec/ruby/core/array/pack/l_spec.rb b/spec/ruby/core/array/pack/l_spec.rb 4 | index 0a5552b984..f8c6ccaf29 100644 5 | --- a/spec/ruby/core/array/pack/l_spec.rb 6 | +++ b/spec/ruby/core/array/pack/l_spec.rb 7 | @@ -29,7 +29,7 @@ 8 | it_behaves_like :array_pack_32bit_be, 'L>' 9 | end 10 | 11 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 12 | + guard -> { platform_is wordsize: 32 } do 13 | describe "with modifier '<' and '_'" do 14 | it_behaves_like :array_pack_32bit_le, 'L<_' 15 | it_behaves_like :array_pack_32bit_le, 'L_<' 16 | @@ -51,7 +51,7 @@ 17 | end 18 | end 19 | 20 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 21 | + guard -> { platform_is wordsize: 64 } do 22 | describe "with modifier '<' and '_'" do 23 | it_behaves_like :array_pack_64bit_le, 'L<_' 24 | it_behaves_like :array_pack_64bit_le, 'L_<' 25 | @@ -83,7 +83,7 @@ 26 | it_behaves_like :array_pack_32bit_be, 'l>' 27 | end 28 | 29 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 30 | + guard -> { platform_is wordsize: 32 } do 31 | describe "with modifier '<' and '_'" do 32 | it_behaves_like :array_pack_32bit_le, 'l<_' 33 | it_behaves_like :array_pack_32bit_le, 'l_<' 34 | @@ -105,7 +105,7 @@ 35 | end 36 | end 37 | 38 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 39 | + guard -> { platform_is wordsize: 64 } do 40 | describe "with modifier '<' and '_'" do 41 | it_behaves_like :array_pack_64bit_le, 'l<_' 42 | it_behaves_like :array_pack_64bit_le, 'l_<' 43 | @@ -137,7 +137,7 @@ 44 | it_behaves_like :array_pack_32bit_le, 'l' 45 | end 46 | 47 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 48 | + guard -> { platform_is wordsize: 32 } do 49 | describe "Array#pack with format 'L' with modifier '_'" do 50 | it_behaves_like :array_pack_32bit_le, 'L_' 51 | end 52 | @@ -155,7 +155,7 @@ 53 | end 54 | end 55 | 56 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 57 | + guard -> { platform_is wordsize: 64 } do 58 | describe "Array#pack with format 'L' with modifier '_'" do 59 | it_behaves_like :array_pack_64bit_le, 'L_' 60 | end 61 | @@ -183,7 +183,7 @@ 62 | it_behaves_like :array_pack_32bit_be, 'l' 63 | end 64 | 65 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 66 | + guard -> { platform_is wordsize: 32 } do 67 | describe "Array#pack with format 'L' with modifier '_'" do 68 | it_behaves_like :array_pack_32bit_be, 'L_' 69 | end 70 | @@ -201,7 +201,7 @@ 71 | end 72 | end 73 | 74 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 75 | + guard -> { platform_is wordsize: 64 } do 76 | describe "Array#pack with format 'L' with modifier '_'" do 77 | it_behaves_like :array_pack_64bit_be, 'L_' 78 | end 79 | diff --git a/spec/ruby/core/float/round_spec.rb b/spec/ruby/core/float/round_spec.rb 80 | index e04b376c36..df113f97b1 100644 81 | --- a/spec/ruby/core/float/round_spec.rb 82 | +++ b/spec/ruby/core/float/round_spec.rb 83 | @@ -10,11 +10,9 @@ 84 | 0.0.round.should == 0 85 | end 86 | 87 | - platform_is_not :mingw32 do 88 | - it "returns the nearest Integer for Float near the limit" do 89 | - 0.49999999999999994.round.should == 0 90 | - -0.49999999999999994.round.should == 0 91 | - end 92 | + it "returns the nearest Integer for Float near the limit" do 93 | + 0.49999999999999994.round.should == 0 94 | + -0.49999999999999994.round.should == 0 95 | end 96 | 97 | it "raises FloatDomainError for exceptional values" do 98 | diff --git a/spec/ruby/core/string/unpack/l_spec.rb b/spec/ruby/core/string/unpack/l_spec.rb 99 | index 6f9fcd4fd0..61828b8a45 100644 100 | --- a/spec/ruby/core/string/unpack/l_spec.rb 101 | +++ b/spec/ruby/core/string/unpack/l_spec.rb 102 | @@ -14,7 +14,7 @@ 103 | it_behaves_like :string_unpack_32bit_be_unsigned, 'L>' 104 | end 105 | 106 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 107 | + guard -> { platform_is wordsize: 32 } do 108 | describe "with modifier '<' and '_'" do 109 | it_behaves_like :string_unpack_32bit_le, 'L<_' 110 | it_behaves_like :string_unpack_32bit_le, 'L_<' 111 | @@ -44,7 +44,7 @@ 112 | end 113 | end 114 | 115 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 116 | + guard -> { platform_is wordsize: 64 } do 117 | describe "with modifier '<' and '_'" do 118 | it_behaves_like :string_unpack_64bit_le, 'L<_' 119 | it_behaves_like :string_unpack_64bit_le, 'L_<' 120 | @@ -86,7 +86,7 @@ 121 | it_behaves_like :string_unpack_32bit_be_signed, 'l>' 122 | end 123 | 124 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 125 | + guard -> { platform_is wordsize: 32 } do 126 | describe "with modifier '<' and '_'" do 127 | it_behaves_like :string_unpack_32bit_le, 'l<_' 128 | it_behaves_like :string_unpack_32bit_le, 'l_<' 129 | @@ -116,7 +116,7 @@ 130 | end 131 | end 132 | 133 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 134 | + guard -> { platform_is wordsize: 64 } do 135 | describe "with modifier '<' and '_'" do 136 | it_behaves_like :string_unpack_64bit_le, 'l<_' 137 | it_behaves_like :string_unpack_64bit_le, 'l_<' 138 | @@ -160,7 +160,7 @@ 139 | it_behaves_like :string_unpack_32bit_le_signed, 'l' 140 | end 141 | 142 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 143 | + guard -> { platform_is wordsize: 32 } do 144 | describe "String#unpack with format 'L' with modifier '_'" do 145 | it_behaves_like :string_unpack_32bit_le, 'L_' 146 | it_behaves_like :string_unpack_32bit_le_unsigned, 'L_' 147 | @@ -182,7 +182,7 @@ 148 | end 149 | end 150 | 151 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 152 | + guard -> { platform_is wordsize: 64 } do 153 | describe "String#unpack with format 'L' with modifier '_'" do 154 | it_behaves_like :string_unpack_64bit_le, 'L_' 155 | it_behaves_like :string_unpack_64bit_le_unsigned, 'L_' 156 | @@ -218,7 +218,7 @@ 157 | it_behaves_like :string_unpack_32bit_be_signed, 'l' 158 | end 159 | 160 | - guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do 161 | + guard -> { platform_is wordsize: 32 } do 162 | describe "String#unpack with format 'L' with modifier '_'" do 163 | it_behaves_like :string_unpack_32bit_be, 'L_' 164 | it_behaves_like :string_unpack_32bit_be_unsigned, 'L_' 165 | @@ -240,7 +240,7 @@ 166 | end 167 | end 168 | 169 | - guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do 170 | + guard -> { platform_is wordsize: 64 } do 171 | describe "String#unpack with format 'L' with modifier '_'" do 172 | it_behaves_like :string_unpack_64bit_be, 'L_' 173 | it_behaves_like :string_unpack_64bit_be_unsigned, 'L_' 174 | diff --git a/spec/ruby/optional/capi/time_spec.rb b/spec/ruby/optional/capi/time_spec.rb 175 | index 4a59c98100..1191ceabd2 100644 176 | --- a/spec/ruby/optional/capi/time_spec.rb 177 | +++ b/spec/ruby/optional/capi/time_spec.rb 178 | @@ -165,7 +165,7 @@ 179 | usec.should == 500000 180 | end 181 | 182 | - platform_is_not :mingw32 do 183 | + guard -> { platform_is_not :mingw or ruby_version_is '2.5' } do 184 | it "creates a timeval for a negative Fixnum" do 185 | sec, usec = @s.rb_time_timeval(-1232141421) 186 | sec.should be_kind_of(Integer) 187 | @@ -224,7 +224,7 @@ 188 | nsec.should == 500000000 189 | end 190 | 191 | - platform_is_not :mingw32 do 192 | + guard -> { platform_is_not :mingw or ruby_version_is '2.5' } do 193 | it "creates a timespec for a negative Fixnum" do 194 | sec, nsec = @s.rb_time_timespec(-1232141421) 195 | sec.should be_kind_of(Integer) 196 | -------------------------------------------------------------------------------- /1_0_build_install_msys2_64.ps1: -------------------------------------------------------------------------------- 1 | <# Code by MSP-Greg 2 | Script for building & installing MinGW Ruby for CI 3 | Assumes a Ruby exe is in path 4 | Assumes 'Git for Windows' is installed at $env:ProgramFiles\Git 5 | Assumes '7z ' is installed at $env:ProgramFiles\7-Zip 6 | For local use, set items in local.ps1 7 | #> 8 | 9 | #——————————————————————————————————————————————————————————————————— Strip-Build 10 | # Strips dll & so files in build folder 11 | function Strip-Build { 12 | Push-Location $d_build 13 | $strip = "$d_mingw/strip.exe" 14 | 15 | [string[]]$dlls = Get-ChildItem -Include *.dll -Recurse | 16 | select -expand fullname 17 | foreach ($dll in $dlls) { 18 | Set-ItemProperty -Path $dll -Name IsReadOnly -Value $false 19 | $t = $dll.replace('\', '/') 20 | &$strip -Dp --strip-unneeded $t 21 | } 22 | 23 | [string[]]$exes = Get-ChildItem -Path ./*.exe | 24 | select -expand fullname 25 | foreach ($exe in $exes) { 26 | Set-ItemProperty -Path $exe -Name IsReadOnly -Value $false 27 | $t = $exe.replace('\', '/') 28 | &$strip -Dp --strip-all $t 29 | } 30 | 31 | $d_so = "$d_build/.ext/$rarch" 32 | 33 | [string[]]$sos = Get-ChildItem -Include *.so -Path $d_so -Recurse | 34 | select -expand fullname 35 | foreach ($so in $sos) { 36 | Set-ItemProperty -Path $so -Name IsReadOnly -Value $false 37 | $t = $so.replace('\', '/') 38 | &$strip -Dp --strip-unneeded $t 39 | } 40 | $msg = "Build: Stripped {0,2} dll files, {1,2} exe files, and {2,3} so files" -f ` 41 | @($dlls.length, $exes.length, $sos.length) 42 | EchoC $dash_line yel 43 | echo $msg 44 | Pop-Location 45 | } 46 | 47 | #————————————————————————————————————————————————————————————————— Strip-Install 48 | # Strips dll & so files in install folder 49 | function Strip-Install { 50 | Push-Location $d_install 51 | $strip = "$d_mingw/strip.exe" 52 | 53 | $d_bin = "$d_install/bin" 54 | 55 | [string[]]$dlls = Get-ChildItem -Path ./bin/*.dll | 56 | select -expand fullname 57 | foreach ($dll in $dlls) { 58 | Set-ItemProperty -Path $dll -Name IsReadOnly -Value $false 59 | $t = $dll.replace('\', '/') 60 | &$strip -Dp --strip-unneeded $t 61 | } 62 | 63 | [string[]]$exes = Get-ChildItem -Path ./bin/*.exe | 64 | select -expand fullname 65 | foreach ($exe in $exes) { 66 | Set-ItemProperty -Path $exe -Name IsReadOnly -Value $false 67 | $t = $exe.replace('\', '/') 68 | &$strip -Dp --strip-all $t 69 | } 70 | 71 | $abi = ruby.exe -e "print RbConfig::CONFIG['ruby_version']" 72 | $d_so = "$d_install/lib/ruby/$abi/$rarch" 73 | 74 | [string[]]$sos = Get-ChildItem -Include *.so -Path $d_so -Recurse | 75 | select -expand fullname 76 | foreach ($so in $sos) { 77 | Set-ItemProperty -Path $so -Name IsReadOnly -Value $false 78 | $t = $so.replace('\', '/') 79 | &$strip -Dp --strip-unneeded $t 80 | } 81 | 82 | $msg = "Install: Stripped {0,2} dll files, {1,2} exe files, and {2,3} so files" -f ` 83 | @($dlls.length, $exes.length, $sos.length) 84 | EchoC $dash_line yel 85 | echo $msg 86 | Pop-Location 87 | } 88 | 89 | #————————————————————————————————————————————————————————————————— Set-Variables-Local 90 | # set variables only used in this script 91 | function Set-Variables-Local { 92 | $script:ruby_path = $(ruby.exe -e "puts RbConfig::CONFIG['bindir']").trim().replace('\', '/') 93 | $script:time_info = '' 94 | $script:time_old = $null 95 | $script:time_start = $null 96 | } 97 | 98 | #——————————————————————————————————————————————————————————————————————— Set-Env 99 | # Set ENV, including gcc flags 100 | function Set-Env { 101 | $env:Path = "$ruby_path;$d_mingw;$d_repo/git/cmd;$d_msys2/usr/bin;$base_path" 102 | 103 | # used in Ruby scripts 104 | $env:D_MSYS2 = $d_msys2 105 | 106 | $env:MSYS_NO_PATHCONV = 1 107 | 108 | $env:CFLAGS = "-march=$march -mtune=generic -O3 -pipe -fstack-protector-strong" 109 | $env:CXXFLAGS = "-D_FORTIFY_SOURCE=2 -O3 -march=$march -mtune=generic -pipe" 110 | $env:CPPFLAGS = "-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048" 111 | $env:LDFLAGS = "-l:libssp.a -l:libz.a -pipe -fstack-protector-strong -s" 112 | } 113 | 114 | #——————————————————————————————————————————————————————————————————— start build 115 | cd $PSScriptRoot 116 | 117 | if ($args.length -eq 1) { 118 | Switch ($args[0]) { 119 | 'ucrt' { $temp = 'ucrt' } 120 | 'mingw' { $temp = 'mingw' } 121 | default { $temp = 'ucrt' } 122 | } 123 | } else { $temp = 'ucrt' } 124 | 125 | . ./0_common.ps1 $temp 126 | Set-Variables 127 | Set-Variables-Local 128 | Set-Env 129 | 130 | Write-Host "TEMP = $env:TEMP" 131 | Write-Host "TMPDIR = $env:TMPDIR" 132 | 133 | $gcc_vers = ([regex]'\d+\.\d+\.\d+').match($(gcc.exe --version)).value 134 | 135 | $files = "$d_msys2$env:MINGW_PREFIX/lib/libz.dll.a", 136 | "$d_msys2$env:MINGW_PREFIX/lib/gcc/x86_64-w64-mingw32/$gcc_vers/libssp.dll.a", 137 | "C:/Windows/System32/libcrypto-1_1-x64.dll", 138 | "C:/Windows/System32/libssl-1_1-x64.dll" 139 | 140 | Files-Hide $files 141 | 142 | Run-Patches @('rubyinstaller2', 'patches_ri2') 143 | Run-Patches @('ruby', 'patches_install_all', 'patches_install_msys2') 144 | 145 | Create-Folders 146 | 147 | cd $d_repo 148 | ruby 1_1_pre_build.rb 64 149 | 150 | cd $d_ruby 151 | 152 | (Get-Content gems/bundled_gems -raw) -replace '(?m)^syslog.+\n', '' | Set-Content gems/bundled_gems -NoNewline 153 | 154 | # set time stamp for reproducible build 155 | $ts = $(git log -1 --format=%at).Trim() 156 | if ($ts -match '\A\d+\z' -and $ts -gt "1540000000") { 157 | $env:SOURCE_DATE_EPOCH = [String][int]$ts 158 | # echo "SOURCE_DATE_EPOCH = $env:SOURCE_DATE_EPOCH" 159 | } 160 | 161 | # Run "sh -c `"autoreconf -fi`"" { sh -c "autoreconf -fi" } 162 | 163 | Run "sh -c ./autogen.sh" { sh -c "./autogen.sh"sh -c "./autogen.sh"; Get-Content -Path "./configure" | Select-Object -First 4 } 164 | 165 | cd $d_build 166 | Time-Log "start" 167 | 168 | $config_args = "--build=$chost --host=$chost --target=$chost" 169 | 170 | # disable since Ruby adds Actions collapsible sections, can't nest them 171 | $actual_github_actions = $is_actions 172 | $is_actions = $false 173 | Run "sh -c `"../ruby/configure --disable-install-doc --prefix=$d_install $config_args`"" { 174 | sh -c "../ruby/configure --disable-install-doc --prefix=$d_install $config_args" 175 | } 176 | $is_actions = $actual_github_actions 177 | Time-Log "configure" 178 | 179 | # below sets some directories to normal in case they're set to read-only 180 | Remove-Read-Only $d_ruby 181 | Remove-Read-Only $d_build 182 | 183 | Run "make incs -j$jobs 2>&1" { 184 | iex "make incs -j$jobs 2>&1" 185 | Check-Exit "make incs -j$jobs 2>&1 failure" 186 | } 187 | Time-Log "make incs -j$jobs" 188 | 189 | Run "make -j$jobs 2>&1" { 190 | iex "make -j$jobs 2>&1" 191 | Check-Exit "'make -j$jobs 2>&1 failure" 192 | } 193 | Time-Log "make -j$jobs" 194 | 195 | 196 | Files-Unhide $files 197 | 198 | Run "make install-nodoc" { 199 | make install-nodoc 200 | Check-Exit "'make install-nodoc' failure" 201 | cd $d_repo 202 | ruby 1_2_post_install.rb 203 | Check-Exit "'ruby 1_2_post_install.rb' failure" 204 | 205 | $dll_path = "$d_install/bin/ruby_builtin_dlls" 206 | 207 | if (!(Test-Path -Path $dll_path -PathType Container )) { 208 | EchoC "Failed - no bin/ruby_builtin_dlls folder" red 209 | exit 1 210 | } 211 | 212 | if (!(Test-Path -Path "$dll_path/ruby_builtin_dlls.manifest" -PathType Leaf )) { 213 | EchoC "Failed - no bin/ruby_builtin_dlls/ruby_builtin_dlls.manifest file" red 214 | exit 1 215 | } 216 | 217 | $env:Path = "$d_install/bin;$d_mingw;$d_repo/git/cmd;$d_msys2/usr/bin;$base_path" 218 | ruby 1_3_post_install.rb 219 | Check-Exit "'ruby 1_3_post_install.rb' failure" 220 | 221 | # fix up RbConfig - CONFIG["INSTALL"], CONFIG["MAKEDIRS"], CONFIG["MKDIR_P"] 222 | $rubyPath = ruby.exe -e 'print "#{RbConfig::TOPDIR}/lib/ruby/#{RbConfig::CONFIG["ruby_version"]}/#{RUBY_PLATFORM}"' 223 | $rbconfig = "$rubyPath/rbconfig.rb" 224 | (Get-Content $rbconfig) | ForEach-Object { $_ -replace '\/[cd]\/ruby-[a-z]+\/msys64', '' } | Out-File -FilePath $rbconfig -Encoding UTF8 225 | (Get-Content $rbconfig -raw).Replace("`r", "") | Out-File -FilePath $rbconfig -Encoding UTF8 -NoNewline 226 | 227 | ruby 1_4_post_install_bin_files.rb 228 | Check-Exit "'ruby 1_4_post_install_bin_files.rb' failure" 229 | } 230 | Time-Log "make install-nodoc" 231 | 232 | #Time-Log "post install processing" 233 | 234 | Strip-Build 235 | Strip-Install 236 | Time-Log "strip build & install binary files" 237 | 238 | Print-Time-Log 239 | 240 | # save extension build files 241 | Push-Location $d_build 242 | $build_files = "$d_zips/ext_build_files.7z" 243 | &$7z a $build_files config.log .ext\include\$rarch\ruby\*.h ext\**\Makefile ext\**\*.h ext\**\*.log ext\**\*.mk 1> $null 244 | if ($is_av) { Push-AppveyorArtifact $build_files -DeploymentName "Ext build files" } 245 | Pop-Location 246 | 247 | # apply patches to install folder 248 | # Apply-Install-Patches "patches_install" 249 | 250 | if (Test-Path Env:\SOURCE_DATE_EPOCH ) { Remove-Item Env:\SOURCE_DATE_EPOCH } 251 | 252 | $ruby_exe = "$d_install/bin/ruby.exe" 253 | $ruby_v = &$ruby_exe -v 254 | 255 | if (-not ($ruby_v -cmatch "$rarch\]\z")) { 256 | throw("Ruby may have assembly issue, won't start") 257 | } else { 258 | Write-Host $ruby_v 259 | } 260 | $env:Path = $orig_path 261 | -------------------------------------------------------------------------------- /old_patches/14867_2018-10-29_1.patch: -------------------------------------------------------------------------------- 1 | From mboxrd@z Thu Jan 1 00:00:00 1970 2 | Return-Path: 3 | X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on dcvr.yhbt.net 4 | X-Spam-Level: 5 | X-Spam-ASN: AS16276 66.70.128.0/17 6 | X-Spam-Status: No, score=-1.1 required=3.0 tests=BAYES_00,RCVD_IN_SORBS_WEB, 7 | RCVD_IN_XBL,SPF_FAIL,SPF_HELO_FAIL,TO_EQ_FM_DOM_SPF_FAIL shortcircuit=no 8 | autolearn=no autolearn_force=no version=3.4.1 9 | Received: from 80x24.org (tor.cusse.org [66.70.217.179]) 10 | by dcvr.yhbt.net (Postfix) with ESMTP id 451A81F453 11 | for ; Mon, 29 Oct 2018 15:11:07 +0000 (UTC) 12 | From: Eric Wong 13 | To: spew@80x24.org 14 | Subject: [PATCH] process.c: implement rb_f_system without toggling ruby_nocldwait 15 | Date: Mon, 29 Oct 2018 15:11:06 +0000 16 | Message-Id: <20181029151106.9474-1-e@80x24.org> 17 | List-Id: 18 | Archived-At: 19 | List-Archive: 20 | List-Post: 21 | 22 | Following how mjit_worker.c currently works, rb_f_system 23 | now ensures the VM-wide waitpid lists is locked before 24 | creating a new process via fork/vfork. 25 | 26 | This ensures other rb_waitpid callers cannot steal work and 27 | there are no possible race conditions from toggling 28 | ruby_nocldwait without the use of atomics. 29 | 30 | This sets us up for implementing MJIT process management 31 | logic using normal Ruby APIs prepares us for VM-wide 32 | asynchronous/event-base waitpid which can allow MJIT to 33 | work without worker threads. 34 | --- 35 | internal.h | 3 +- 36 | process.c | 96 ++++++++++++++++++++++++++++++++++++++++++-------------------- 37 | 2 files changed, 67 insertions(+), 32 deletions(-) 38 | 39 | diff --git a/internal.h b/internal.h 40 | index 3f6f5e4608..697a1196fa 100644 41 | --- a/internal.h 42 | +++ b/internal.h 43 | @@ -1671,6 +1671,7 @@ VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additi 44 | /* process.c */ 45 | #define RB_MAX_GROUPS (65536) 46 | 47 | +struct waitpid_state; 48 | struct rb_execarg { 49 | union { 50 | struct { 51 | @@ -1700,7 +1701,7 @@ struct rb_execarg { 52 | unsigned uid_given : 1; 53 | unsigned gid_given : 1; 54 | unsigned exception : 1; 55 | - unsigned nocldwait_prev : 1; 56 | + struct waitpid_state *waitpid_state; /* for async process management */ 57 | rb_pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0ec)->waitpid_lock); 80 | + } 81 | #ifdef HAVE_WORKING_VFORK 82 | if (!has_privilege()) 83 | pid = vfork(); 84 | @@ -3906,6 +3910,13 @@ retry_fork_async_signal_safe(int *status, int *ep, 85 | #endif 86 | } 87 | err = errno; 88 | + if (w && WAITPID_USE_SIGCHLD) { 89 | + if (pid > 0) { 90 | + w->pid = pid; 91 | + list_add(&rb_ec_vm_ptr(w->ec)->waiting_pids, &w->wnode); 92 | + } 93 | + rb_native_mutex_unlock(&rb_ec_vm_ptr(w->ec)->waitpid_lock); 94 | + } 95 | disable_child_handler_fork_parent(&old); 96 | if (0 < pid) /* fork succeed, parent process */ 97 | return pid; 98 | @@ -3916,28 +3927,34 @@ retry_fork_async_signal_safe(int *status, int *ep, 99 | } 100 | COMPILER_WARNING_POP 101 | 102 | -rb_pid_t 103 | -rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, 104 | - char *errmsg, size_t errmsg_buflen) 105 | +static rb_pid_t 106 | +fork_check_err(int *status, int (*chfunc)(void*, char *, size_t), void *charg, 107 | + VALUE fds, char *errmsg, size_t errmsg_buflen, 108 | + struct rb_execarg *eargp) 109 | { 110 | rb_pid_t pid; 111 | int err; 112 | int ep[2]; 113 | int error_occurred; 114 | + struct waitpid_state *w; 115 | + 116 | + w = eargp && eargp->waitpid_state ? eargp->waitpid_state : 0; 117 | 118 | if (status) *status = 0; 119 | 120 | if (pipe_nocrash(ep, fds)) return -1; 121 | - pid = retry_fork_async_signal_safe(status, ep, chfunc, charg, errmsg, errmsg_buflen); 122 | + pid = retry_fork_async_signal_safe(status, ep, chfunc, charg, 123 | + errmsg, errmsg_buflen, w); 124 | if (pid < 0) 125 | return pid; 126 | close(ep[1]); 127 | error_occurred = recv_child_error(ep[0], &err, errmsg, errmsg_buflen); 128 | if (error_occurred) { 129 | if (status) { 130 | + VM_ASSERT(w == 0 && "only used by extensions"); 131 | rb_protect(proc_syswait, (VALUE)pid, status); 132 | } 133 | - else { 134 | + else if (!w) { 135 | rb_syswait(pid); 136 | } 137 | errno = err; 138 | @@ -3946,6 +3963,21 @@ rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), voi 139 | return pid; 140 | } 141 | 142 | +/* 143 | + * The "async_signal_safe" name is a lie, but it is used by pty.c and 144 | + * maybe other exts. fork() is not async-signal-safe due to pthread_atfork 145 | + * and future POSIX revisions will remove it from a list of signal-safe 146 | + * functions. rb_waitpid is not async-signal-safe since MJIT, either. 147 | + * For our purposes, we do not need async-signal-safety, here 148 | + */ 149 | +rb_pid_t 150 | +rb_fork_async_signal_safe(int *status, 151 | + int (*chfunc)(void*, char *, size_t), void *charg, 152 | + VALUE fds, char *errmsg, size_t errmsg_buflen) 153 | +{ 154 | + return fork_check_err(status, chfunc, charg, fds, errmsg, errmsg_buflen, 0); 155 | +} 156 | + 157 | COMPILER_WARNING_PUSH 158 | #ifdef __GNUC__ 159 | COMPILER_WARNING_IGNORED(-Wdeprecated-declarations) 160 | @@ -4234,7 +4266,8 @@ rb_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen) 161 | #endif 162 | 163 | #if defined HAVE_WORKING_FORK && !USE_SPAWNV 164 | - pid = rb_fork_async_signal_safe(NULL, rb_exec_atfork, eargp, eargp->redirect_fds, errmsg, errmsg_buflen); 165 | + pid = fork_check_err(0, rb_exec_atfork, eargp, eargp->redirect_fds, 166 | + errmsg, errmsg_buflen, eargp); 167 | #else 168 | prog = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name; 169 | 170 | @@ -4353,37 +4386,39 @@ rb_spawn(int argc, const VALUE *argv) 171 | static VALUE 172 | rb_f_system(int argc, VALUE *argv) 173 | { 174 | - rb_pid_t pid; 175 | - int status; 176 | + /* 177 | + * n.b. using alloca for now to simplify future Thread::Light code 178 | + * when we need to use malloc for non-native Fiber 179 | + */ 180 | + struct waitpid_state *w = alloca(sizeof(struct waitpid_state)); 181 | + rb_pid_t pid; /* may be different from waitpid_state.pid on exec failure */ 182 | VALUE execarg_obj; 183 | struct rb_execarg *eargp; 184 | + int exec_errnum; 185 | 186 | execarg_obj = rb_execarg_new(argc, argv, TRUE, TRUE); 187 | TypedData_Get_Struct(execarg_obj, struct rb_execarg, &exec_arg_data_type, eargp); 188 | -#if RUBY_SIGCHLD 189 | - eargp->nocldwait_prev = ruby_nocldwait; 190 | - ruby_nocldwait = 0; 191 | -#endif 192 | - pid = rb_execarg_spawn(execarg_obj, NULL, 0); 193 | + w->ec = GET_EC(); 194 | + waitpid_state_init(w, 0, 0); 195 | + eargp->waitpid_state = w; 196 | + pid = rb_execarg_spawn(execarg_obj, 0, 0); 197 | + exec_errnum = pid < 0 ? errno : 0; 198 | + 199 | #if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) 200 | - if (pid > 0) { 201 | - int ret, status; 202 | - ret = rb_waitpid(pid, &status, 0); 203 | - if (ret == (rb_pid_t)-1) { 204 | -# if RUBY_SIGCHLD 205 | - ruby_nocldwait = eargp->nocldwait_prev; 206 | -# endif 207 | - RB_GC_GUARD(execarg_obj); 208 | - rb_sys_fail("Another thread waited the process started by system()."); 209 | + if (w->pid > 0) { 210 | + /* `pid' (not w->pid) may be < 0 here if execve failed in child */ 211 | + if (WAITPID_USE_SIGCHLD) { 212 | + rb_ensure(waitpid_sleep, (VALUE)w, waitpid_cleanup, (VALUE)w); 213 | + } 214 | + else { 215 | + waitpid_no_SIGCHLD(w); 216 | } 217 | + rb_last_status_set(w->status, w->ret); 218 | } 219 | #endif 220 | -#if RUBY_SIGCHLD 221 | - ruby_nocldwait = eargp->nocldwait_prev; 222 | -#endif 223 | - if (pid < 0) { 224 | + if (w->pid < 0 /* fork failure */ || pid < 0 /* exec failure */) { 225 | if (eargp->exception) { 226 | - int err = errno; 227 | + int err = exec_errnum ? exec_errnum : w->errnum; 228 | VALUE command = eargp->invoke.sh.shell_script; 229 | RB_GC_GUARD(execarg_obj); 230 | rb_syserr_fail_str(err, command); 231 | @@ -4392,12 +4427,11 @@ rb_f_system(int argc, VALUE *argv) 232 | return Qnil; 233 | } 234 | } 235 | - status = PST2INT(rb_last_status_get()); 236 | - if (status == EXIT_SUCCESS) return Qtrue; 237 | + if (w->status == EXIT_SUCCESS) return Qtrue; 238 | if (eargp->exception) { 239 | VALUE command = eargp->invoke.sh.shell_script; 240 | VALUE str = rb_str_new_cstr("Command failed with"); 241 | - rb_str_cat_cstr(pst_message_status(str, status), ": "); 242 | + rb_str_cat_cstr(pst_message_status(str, w->status), ": "); 243 | rb_str_append(str, command); 244 | RB_GC_GUARD(execarg_obj); 245 | rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, str)); 246 | -------------------------------------------------------------------------------- /old_patches/test/net_openssl_ctx.rb.patch: -------------------------------------------------------------------------------- 1 | Patch by MSP-Greg 2 | Add shared utils_ssl.rb file with create_ssl_ctx method 3 | Removes duplicated code in ftp, imap, & smtp 4 | diff --git a/test/net/ftp/test_ftp.rb b/test/net/ftp/test_ftp.rb 5 | index 2504a48d0a..24d43b7c90 100644 6 | --- a/test/net/ftp/test_ftp.rb 7 | +++ b/test/net/ftp/test_ftp.rb 8 | @@ -6,8 +6,11 @@ 9 | require "stringio" 10 | require "tempfile" 11 | require "tmpdir" 12 | +require File.expand_path('..\utils_ssl', File.dirname(__FILE__)) 13 | 14 | class FTPTest < Test::Unit::TestCase 15 | + include TestNetUtilsSSL 16 | + 17 | SERVER_NAME = "localhost" 18 | SERVER_ADDR = 19 | begin 20 | @@ -15,9 +18,6 @@ class FTPTest < Test::Unit::TestCase 21 | rescue SocketError 22 | "127.0.0.1" 23 | end 24 | - CA_FILE = File.expand_path("../fixtures/cacert.pem", __dir__) 25 | - SERVER_KEY = File.expand_path("../fixtures/server.key", __dir__) 26 | - SERVER_CERT = File.expand_path("../fixtures/server.crt", __dir__) 27 | 28 | def setup 29 | @thread = nil 30 | @@ -1862,14 +1862,7 @@ def test_active_private_data_connection 31 | sock.print("220 (test_ftp).\r\n") 32 | commands.push(sock.gets) 33 | sock.print("234 AUTH success.\r\n") 34 | - ctx = OpenSSL::SSL::SSLContext.new 35 | - ctx.ca_file = CA_FILE 36 | - ctx.key = File.open(SERVER_KEY) { |f| 37 | - OpenSSL::PKey::RSA.new(f) 38 | - } 39 | - ctx.cert = File.open(SERVER_CERT) { |f| 40 | - OpenSSL::X509::Certificate.new(f) 41 | - } 42 | + ctx = create_ctx 43 | sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) 44 | sock.sync_close = true 45 | begin 46 | @@ -1946,14 +1939,7 @@ def test_passive_private_data_connection 47 | sock.print("220 (test_ftp).\r\n") 48 | commands.push(sock.gets) 49 | sock.print("234 AUTH success.\r\n") 50 | - ctx = OpenSSL::SSL::SSLContext.new 51 | - ctx.ca_file = CA_FILE 52 | - ctx.key = File.open(SERVER_KEY) { |f| 53 | - OpenSSL::PKey::RSA.new(f) 54 | - } 55 | - ctx.cert = File.open(SERVER_CERT) { |f| 56 | - OpenSSL::X509::Certificate.new(f) 57 | - } 58 | + ctx = create_ctx 59 | sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) 60 | sock.sync_close = true 61 | begin 62 | @@ -2028,14 +2014,7 @@ def test_active_clear_data_connection 63 | sock.print("220 (test_ftp).\r\n") 64 | commands.push(sock.gets) 65 | sock.print("234 AUTH success.\r\n") 66 | - ctx = OpenSSL::SSL::SSLContext.new 67 | - ctx.ca_file = CA_FILE 68 | - ctx.key = File.open(SERVER_KEY) { |f| 69 | - OpenSSL::PKey::RSA.new(f) 70 | - } 71 | - ctx.cert = File.open(SERVER_CERT) { |f| 72 | - OpenSSL::X509::Certificate.new(f) 73 | - } 74 | + ctx = create_ctx 75 | sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) 76 | sock.sync_close = true 77 | begin 78 | @@ -2097,14 +2076,7 @@ def test_passive_clear_data_connection 79 | sock.print("220 (test_ftp).\r\n") 80 | commands.push(sock.gets) 81 | sock.print("234 AUTH success.\r\n") 82 | - ctx = OpenSSL::SSL::SSLContext.new 83 | - ctx.ca_file = CA_FILE 84 | - ctx.key = File.open(SERVER_KEY) { |f| 85 | - OpenSSL::PKey::RSA.new(f) 86 | - } 87 | - ctx.cert = File.open(SERVER_CERT) { |f| 88 | - OpenSSL::X509::Certificate.new(f) 89 | - } 90 | + ctx = create_ctx 91 | sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) 92 | sock.sync_close = true 93 | begin 94 | @@ -2189,14 +2161,7 @@ def test_abort_tls 95 | sock.print("220 (test_ftp).\r\n") 96 | commands.push(sock.gets) 97 | sock.print("234 AUTH success.\r\n") 98 | - ctx = OpenSSL::SSL::SSLContext.new 99 | - ctx.ca_file = CA_FILE 100 | - ctx.key = File.open(SERVER_KEY) { |f| 101 | - OpenSSL::PKey::RSA.new(f) 102 | - } 103 | - ctx.cert = File.open(SERVER_CERT) { |f| 104 | - OpenSSL::X509::Certificate.new(f) 105 | - } 106 | + ctx = create_ctx 107 | sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) 108 | sock.sync_close = true 109 | sock.accept 110 | @@ -2493,14 +2458,7 @@ def tls_test 111 | sock.print("220 (test_ftp).\r\n") 112 | commands.push(sock.gets) 113 | sock.print("234 AUTH success.\r\n") 114 | - ctx = OpenSSL::SSL::SSLContext.new 115 | - ctx.ca_file = CA_FILE 116 | - ctx.key = File.open(SERVER_KEY) { |f| 117 | - OpenSSL::PKey::RSA.new(f) 118 | - } 119 | - ctx.cert = File.open(SERVER_CERT) { |f| 120 | - OpenSSL::X509::Certificate.new(f) 121 | - } 122 | + ctx = create_ctx 123 | sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) 124 | sock.sync_close = true 125 | begin 126 | diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb 127 | index 64101b6bda..8140bd2b07 100644 128 | --- a/test/net/http/test_https.rb 129 | +++ b/test/net/http/test_https.rb 130 | @@ -4,23 +4,15 @@ 131 | require 'net/https' 132 | require 'stringio' 133 | require 'timeout' 134 | - require File.expand_path("utils", File.dirname(__FILE__)) 135 | + require File.expand_path("utils", __dir__) 136 | + require File.expand_path('..\utils_ssl', File.dirname(__FILE__)) 137 | rescue LoadError 138 | # should skip this test 139 | end 140 | 141 | class TestNetHTTPS < Test::Unit::TestCase 142 | include TestNetHTTPUtils 143 | - 144 | - def self.read_fixture(key) 145 | - File.read(File.expand_path("../fixtures/#{key}", __dir__)) 146 | - end 147 | - 148 | - CA_CERT = OpenSSL::X509::Certificate.new(read_fixture("cacert.pem")) 149 | - SERVER_KEY = OpenSSL::PKey.read(read_fixture("server.key")) 150 | - SERVER_CERT = OpenSSL::X509::Certificate.new(read_fixture("server.crt")) 151 | - DHPARAMS = OpenSSL::PKey::DH.new(read_fixture("dhparams.pem")) 152 | - TEST_STORE = OpenSSL::X509::Store.new.tap {|s| s.add_cert(CA_CERT) } 153 | + include TestNetUtilsSSL 154 | 155 | CONFIG = { 156 | 'host' => '127.0.0.1', 157 | @@ -141,6 +133,7 @@ def test_session_reuse 158 | 159 | http = Net::HTTP.new("localhost", config("port")) 160 | http.use_ssl = true 161 | + http.max_version = OpenSSL::SSL::TLS1_2_VERSION 162 | http.cert_store = TEST_STORE 163 | 164 | http.start 165 | diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb 166 | index 6c6a657552..df104ef44e 100644 167 | --- a/test/net/imap/test_imap.rb 168 | +++ b/test/net/imap/test_imap.rb 169 | @@ -2,11 +2,10 @@ 170 | 171 | require "net/imap" 172 | require "test/unit" 173 | +require File.expand_path('..\utils_ssl', File.dirname(__FILE__)) 174 | 175 | class IMAPTest < Test::Unit::TestCase 176 | - CA_FILE = File.expand_path("../fixtures/cacert.pem", __dir__) 177 | - SERVER_KEY = File.expand_path("../fixtures/server.key", __dir__) 178 | - SERVER_CERT = File.expand_path("../fixtures/server.crt", __dir__) 179 | + include TestNetUtilsSSL 180 | 181 | def setup 182 | @do_not_reverse_lookup = Socket.do_not_reverse_lookup 183 | @@ -757,14 +756,7 @@ def test_append_fail 184 | def imaps_test 185 | server = create_tcp_server 186 | port = server.addr[1] 187 | - ctx = OpenSSL::SSL::SSLContext.new 188 | - ctx.ca_file = CA_FILE 189 | - ctx.key = File.open(SERVER_KEY) { |f| 190 | - OpenSSL::PKey::RSA.new(f) 191 | - } 192 | - ctx.cert = File.open(SERVER_CERT) { |f| 193 | - OpenSSL::X509::Certificate.new(f) 194 | - } 195 | + ctx = create_ctx 196 | ssl_server = OpenSSL::SSL::SSLServer.new(server, ctx) 197 | started = false 198 | ths = Thread.start do 199 | @@ -806,14 +798,7 @@ def starttls_test 200 | sock.print("* OK test server\r\n") 201 | sock.gets 202 | sock.print("RUBY0001 OK completed\r\n") 203 | - ctx = OpenSSL::SSL::SSLContext.new 204 | - ctx.ca_file = CA_FILE 205 | - ctx.key = File.open(SERVER_KEY) { |f| 206 | - OpenSSL::PKey::RSA.new(f) 207 | - } 208 | - ctx.cert = File.open(SERVER_CERT) { |f| 209 | - OpenSSL::X509::Certificate.new(f) 210 | - } 211 | + ctx = create_ctx 212 | sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) 213 | sock.sync_close = true 214 | sock.accept 215 | diff --git a/test/net/smtp/test_smtp.rb b/test/net/smtp/test_smtp.rb 216 | index 90c92e06f8..70f2575d5e 100644 217 | --- a/test/net/smtp/test_smtp.rb 218 | +++ b/test/net/smtp/test_smtp.rb 219 | @@ -2,12 +2,11 @@ 220 | require 'net/smtp' 221 | require 'stringio' 222 | require 'test/unit' 223 | +require File.expand_path('..\utils_ssl', File.dirname(__FILE__)) 224 | 225 | module Net 226 | class TestSMTP < Test::Unit::TestCase 227 | - CA_FILE = File.expand_path("../fixtures/cacert.pem", __dir__) 228 | - SERVER_KEY = File.expand_path("../fixtures/server.key", __dir__) 229 | - SERVER_CERT = File.expand_path("../fixtures/server.crt", __dir__) 230 | + include TestNetUtilsSSL 231 | 232 | class FakeSocket 233 | attr_reader :write_io 234 | @@ -105,14 +104,7 @@ def test_crlf_injection 235 | 236 | def test_tls_connect 237 | servers = Socket.tcp_server_sockets("localhost", 0) 238 | - ctx = OpenSSL::SSL::SSLContext.new 239 | - ctx.ca_file = CA_FILE 240 | - ctx.key = File.open(SERVER_KEY) { |f| 241 | - OpenSSL::PKey::RSA.new(f) 242 | - } 243 | - ctx.cert = File.open(SERVER_CERT) { |f| 244 | - OpenSSL::X509::Certificate.new(f) 245 | - } 246 | + ctx = create_ctx 247 | begin 248 | sock = nil 249 | Thread.start do 250 | diff --git a/test/net/utils_ssl.rb b/test/net/utils_ssl.rb 251 | new file mode 100644 252 | index 0000000000..81e7f082e7 253 | --- /dev/null 254 | +++ b/test/net/utils_ssl.rb 255 | @@ -0,0 +1,23 @@ 256 | +# frozen_string_literal: true 257 | + 258 | +module TestNetUtilsSSL 259 | + 260 | + def self.fixture(fn) 261 | + File.read File.expand_path("fixtures/#{fn}", __dir__) 262 | + end 263 | + 264 | + CA_FILE = File.expand_path("fixtures/cacert.pem", __dir__) 265 | + CA_CERT = OpenSSL::X509::Certificate.new fixture("cacert.pem") 266 | + SERVER_KEY = OpenSSL::PKey.read fixture("server.key") 267 | + SERVER_CERT = OpenSSL::X509::Certificate.new fixture("server.crt") 268 | + DHPARAMS = OpenSSL::PKey::DH.new fixture("dhparams.pem") 269 | + TEST_STORE = OpenSSL::X509::Store.new.tap {|s| s.add_cert(CA_CERT) } 270 | + 271 | + def create_ctx 272 | + ctx = OpenSSL::SSL::SSLContext.new 273 | + ctx.ca_file = CA_FILE 274 | + ctx.key = SERVER_KEY 275 | + ctx.cert = SERVER_CERT 276 | + ctx 277 | + end 278 | +end 279 | --------------------------------------------------------------------------------