popen: shell commands with envvars and execopts

* io.c (is_popen_fork): check if fork and raise NotImplementedError if
  unavailable.
* io.c (rb_io_s_popen): allow environment variables hash and exec
  options as flat parameters, not in an array arguments.
  [Feature#6651] [EXPERIMENTAL]
* process.c (rb_execarg_extract_options): extract exec options, but no
  exceptions on non-exec options and returns them as a Hash.
* process.c (rb_execarg_setenv): set environment variables.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36229 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-06-27 00:15:51 +00:00
parent 1ca611f360
commit 2240eb37b8
5 changed files with 152 additions and 33 deletions

View file

@ -303,6 +303,47 @@ class TestProcess < Test::Unit::TestCase
end
end
def _test_execopts_env_popen(cmd)
message = cmd.inspect
IO.popen({"FOO"=>"BAR"}, cmd) {|io|
assert_equal('FOO=BAR', io.read[/^FOO=.*/], message)
}
old = ENV["hmm"]
begin
ENV["hmm"] = "fufu"
IO.popen(cmd) {|io| assert_match(/^hmm=fufu$/, io.read, message)}
IO.popen({"hmm"=>""}, cmd) {|io| assert_match(/^hmm=$/, io.read, message)}
IO.popen({"hmm"=>nil}, cmd) {|io| assert_not_match(/^hmm=/, io.read, message)}
ENV["hmm"] = ""
IO.popen(cmd) {|io| assert_match(/^hmm=$/, io.read, message)}
IO.popen({"hmm"=>""}, cmd) {|io| assert_match(/^hmm=$/, io.read, message)}
IO.popen({"hmm"=>nil}, cmd) {|io| assert_not_match(/^hmm=/, io.read, message)}
ENV["hmm"] = nil
IO.popen(cmd) {|io| assert_not_match(/^hmm=/, io.read, message)}
IO.popen({"hmm"=>""}, cmd) {|io| assert_match(/^hmm=$/, io.read, message)}
IO.popen({"hmm"=>nil}, cmd) {|io| assert_not_match(/^hmm=/, io.read, message)}
ensure
ENV["hmm"] = old
end
end
def test_execopts_env_popen_vector
_test_execopts_env_popen(ENVCOMMAND)
end
def test_execopts_env_popen_string
with_tmpchdir do |d|
open('test-script', 'w') do |f|
ENVCOMMAND.each_with_index do |cmd, i|
next if i.zero? or cmd == "-e"
f.puts cmd
end
end
_test_execopts_env_popen("#{RUBY} test-script")
end
end
def test_execopts_preserve_env_on_exec_failure
with_tmpchdir {|d|
write_file 's', <<-"End"