Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3fef5d1f3d0a
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0a96710a0853
Choose a head ref
  • 7 commits
  • 27 files changed
  • 1 contributor

Commits on Oct 15, 2014

  1. Copy the full SHA
    479b979 View commit details
  2. Copy the full SHA
    90dd6e1 View commit details
  3. Explicitly set FSAPI dir mode.

    brixen committed Oct 15, 2014
    Copy the full SHA
    d6c0dd2 View commit details
  4. Avoid caching singleton classes.

    Singleton classes reference the object.
    brixen committed Oct 15, 2014
    Copy the full SHA
    977fe2e View commit details
  5. Added more IO.popen specs.

    brixen committed Oct 15, 2014
    Copy the full SHA
    82fef83 View commit details

Commits on Oct 16, 2014

  1. Copy the full SHA
    558cc97 View commit details
  2. Some fixes for IO.popen.

    brixen committed Oct 16, 2014
    Copy the full SHA
    0a96710 View commit details
15 changes: 0 additions & 15 deletions kernel/bootstrap/process.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
module Process
def self.perform_fork
Rubinius.primitive :vm_fork
raise PrimitiveFailure, "Process.perform_fork primitive failed"
end

def self.perform_exec(file, args)
Rubinius.primitive :vm_exec
raise PrimitiveFailure, "Process.perform_exec primitive failed"
end

def self.replace(str)
Rubinius.primitive :vm_replace
raise PrimitiveFailure, "Process.replace primitive failed"
end

def self.wait_pid_prim(pid, no_hang)
Rubinius.primitive :vm_wait_pid
raise PrimitiveFailure, "Process.wait_pid primitive failed"
172 changes: 83 additions & 89 deletions kernel/common/io.rb
Original file line number Diff line number Diff line change
@@ -718,112 +718,55 @@ def self.pipe(external=nil, internal=nil, options=nil)
end
end

##
# Runs the specified command string as a subprocess;
# the subprocess‘s standard input and output will be
# connected to the returned IO object. If cmd_string
# starts with a ``-’’, then a new instance of Ruby is
# started as the subprocess. The default mode for the
# new file object is ``r’’, but mode may be set to any
# of the modes listed in the description for class IO.
#
# If a block is given, Ruby will run the command as a
# child connected to Ruby with a pipe. Ruby‘s end of
# the pipe will be passed as a parameter to the block.
# At the end of block, Ruby close the pipe and sets $?.
# In this case IO::popen returns the value of the block.
#
# If a block is given with a cmd_string of ``-’’, the
# block will be run in two separate processes: once in
# the parent, and once in a child. The parent process
# will be passed the pipe object as a parameter to the
# block, the child version of the block will be passed
# nil, and the child‘s standard in and standard out will
# be connected to the parent through the pipe.
# Not available on all platforms.
#
# f = IO.popen("uname")
# p f.readlines
# puts "Parent is #{Process.pid}"
# IO.popen ("date") { |f| puts f.gets }
# IO.popen("-") { |f| $stderr.puts "#{Process.pid} is here, f is #{f}"}
# p $?
# produces:
#
# ["Linux\n"]
# Parent is 26166
# Wed Apr 9 08:53:52 CDT 2003
# 26169 is here, f is
# 26166 is here, f is #<IO:0x401b3d44>
# #<Process::Status: pid=26166,exited(0)>
def self.popen(str, mode=undefined, options=undefined)
mode, binary, external, internal, autoclose = IO.normalize_options(mode, options)
mode = parse_mode(mode || 'r')

readable = false
writable = false
def self.popen(*args)
if env = Rubinius::Type.try_convert(args.first, Hash, :to_hash)
args.shift
end

if mode & IO::RDWR != 0
readable = true
writable = true
elsif mode & IO::WRONLY != 0
writable = true
else # IO::RDONLY
readable = true
if io_options = Rubinius::Type.try_convert(args.last, Hash, :to_hash)
args.pop
end

pa_read, ch_write = pipe if readable
ch_read, pa_write = pipe if writable
if args.size > 2
raise ArgumentError, "#{__method__}: given #{args.size}, expected 1..2"
end

pid = Process.fork
cmd, mode = args
mode ||= "r"

# child
if !pid
if readable
pa_read.close
STDOUT.reopen ch_write
if cmd.kind_of? Array
if sub_env = Rubinius::Type.try_convert(cmd.first, Hash, :to_hash)
env = sub_env unless env
cmd.shift
end

if writable
pa_write.close
STDIN.reopen ch_read
if exec_options = Rubinius::Type.try_convert(cmd.last, Hash, :to_hash)
cmd.pop
end
end

if str == "-"
if block_given?
yield nil
exit! 0
else
return nil
end
elsif str.kind_of? Array
if str.first.kind_of? Hash
env = str.first
env.each { |k, v| ENV[k] = v }
cmd = str[1..-1]
else
cmd = str
end
mode, binary, external, internal, autoclose =
IO.normalize_options(mode, io_options || {})
mode_int = parse_mode mode

if str.last.kind_of? Hash
redirects, options = Rubinius::Spawn.adjust_options(str.pop)
Rubinius::Spawn.setup_redirects(redirects)
Rubinius::Spawn.setup_options(options)
end
readable = false
writable = false

Process.perform_exec cmd.first, cmd.map(&:to_s)
else
Process.perform_exec str, []
end
if mode_int & IO::RDWR != 0
readable = true
writable = true
elsif mode_int & IO::WRONLY != 0
writable = true
else # IO::RDONLY
readable = true
end

ch_write.close if readable
ch_read.close if writable
pa_read, ch_write = pipe if readable
ch_read, pa_write = pipe if writable

# We only need the Bidirectional pipe if we're reading and writing.
# If we're only doing one, we can just return the IO object for
# the proper half.
#
if readable and writable
# Transmogrify pa_read into a BidirectionalPipe object,
# and then tell it abou it's pid and pa_write
@@ -843,8 +786,59 @@ def self.popen(str, mode=undefined, options=undefined)
pipe.binmode if binary
pipe.set_encoding(external || Encoding.default_external, internal)

if cmd == "-"
pid = Rubinius::Mirror::Process.fork

if !pid
# Child
begin
if readable
pa_read.close
STDOUT.reopen ch_write
end

if writable
pa_write.close
STDIN.reopen ch_read
end

if block_given?
yield nil
exit! 0
else
return nil
end
rescue
exit! 0
end
end
else
options = {}
options[:in] = ch_read.fileno if ch_read
options[:out] = ch_write.fileno if ch_write

if io_options
io_options.delete_if do |key, _|
[:mode, :external_encoding, :internal_encoding,
:encoding, :textmode, :binmode, :autoclose
].include? key
end

options.merge! io_options
end

if exec_options
options.merge! exec_options
end

pid = Rubinius::Mirror::Process.spawn(env || {}, *cmd, options)
end

pipe.pid = pid

ch_write.close if readable
ch_read.close if writable

return pipe unless block_given?

begin
36 changes: 35 additions & 1 deletion kernel/common/kernel.rb
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ def Array(obj)

def Complex(*args)
Rubinius.privately do
Complex.convert *args
Complex.convert(*args)
end
end
module_function :Complex
@@ -183,6 +183,15 @@ def __dir__
end
module_function :__dir__

def `(str) #`
str = StringValue(str) unless str.kind_of?(String)
pid, output = Rubinius::Mirror::Process.backtick str
Process.waitpid(pid)

Rubinius::Type.external_string output
end
module_function :` # `

def =~(other)
nil
end
@@ -293,6 +302,11 @@ def extend(*modules)

alias_method :__extend__, :extend

def fork(&block)
Process.fork(&block)
end
module_function :fork

def getc
$stdin.getc
end
@@ -849,11 +863,28 @@ def singleton_methods(all=true)
methods.uniq
end

def spawn(*args)
Process.spawn(*args)
end
module_function :spawn

def syscall(*args)
raise NotImplementedError
end
module_function :syscall

def system(*args)
begin
pid = Process.spawn(*args)
rescue SystemCallError
return nil
end

Process.waitpid pid
$?.exitstatus == 0
end
module_function :system

def to_s
Rubinius::Type.infect("#<#{self.class}:0x#{self.__id__.to_s(16)}>", self)
end
@@ -906,3 +937,6 @@ def warning(message)
module_function :warning
end

module Kernel

end
1 change: 1 addition & 0 deletions kernel/common/load_order.txt
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ string.rbc
range.rbc
struct.rbc
process.rbc
process_mirror.rbc
random.rbc
regexp.rbc
signal.rbc
Loading