module RSpec::Support::InSubProcess

def in_sub_process(prevent_warnings=true) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize

rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def in_sub_process(prevent_warnings=true) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
  exception_reader, exception_writer = IO.pipe
  result_reader, result_writer = IO.pipe
  # Set binary mode to avoid errors surrounding ascii-8bit to utf-8 conversion
  # this happens with warnings on rspec-rails for example
  [exception_reader, exception_writer, result_reader, result_writer].each { |io| io.binmode }
  pid = Process.fork do
    warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr)
    begin
      result = yield
      warning_preventer.verify_no_warnings! if prevent_warnings
      # rubocop:disable Lint/HandleExceptions
    rescue Support::AllExceptionsExceptOnesWeMustNotRescue => exception
      # rubocop:enable Lint/HandleExceptions
    end
    exception_writer.write marshal_dump_with_unmarshable_object_handling(exception)
    exception_reader.close
    exception_writer.close
    result_writer.write marshal_dump_with_unmarshable_object_handling(result)
    result_reader.close
    result_writer.close
    exit! # prevent at_exit hooks from running (e.g. minitest)
  end
  exception_writer.close
  result_writer.close
  Process.waitpid(pid)
  exception = Marshal.load(exception_reader.read)
  exception_reader.close
  raise exception if exception
  result = Marshal.load(result_reader.read)
  result_reader.close
  result
end

def in_sub_process(*)

def in_sub_process(*)
  skip "This spec requires forking to work properly, " \
       "and your platform does not support forking"
end

def in_sub_process_if_possible(*)

def in_sub_process_if_possible(*)
  yield
end

def marshal_dump_with_unmarshable_object_handling(object)

def marshal_dump_with_unmarshable_object_handling(object)
  Marshal.dump(object)
rescue TypeError => error
  Marshal.dump(UnmarshableObject.new(error))
end