summaryrefslogtreecommitdiff
path: root/spec/ruby/core/process/exec_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/process/exec_spec.rb')
-rw-r--r--spec/ruby/core/process/exec_spec.rb107
1 files changed, 65 insertions, 42 deletions
diff --git a/spec/ruby/core/process/exec_spec.rb b/spec/ruby/core/process/exec_spec.rb
index b4eddf526e..0f371b39c8 100644
--- a/spec/ruby/core/process/exec_spec.rb
+++ b/spec/ruby/core/process/exec_spec.rb
@@ -1,57 +1,49 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Process.exec" do
it "raises Errno::ENOENT for an empty string" do
- lambda { Process.exec "" }.should raise_error(Errno::ENOENT)
+ -> { Process.exec "" }.should raise_error(Errno::ENOENT)
end
it "raises Errno::ENOENT for a command which does not exist" do
- lambda { Process.exec "bogus-noent-script.sh" }.should raise_error(Errno::ENOENT)
+ -> { Process.exec "bogus-noent-script.sh" }.should raise_error(Errno::ENOENT)
end
it "raises an ArgumentError if the command includes a null byte" do
- lambda { Process.exec "\000" }.should raise_error(ArgumentError)
+ -> { Process.exec "\000" }.should raise_error(ArgumentError)
end
unless File.executable?(__FILE__) # Some FS (e.g. vboxfs) locate all files executable
platform_is_not :windows do
it "raises Errno::EACCES when the file does not have execute permissions" do
- lambda { Process.exec __FILE__ }.should raise_error(Errno::EACCES)
+ -> { Process.exec __FILE__ }.should raise_error(Errno::EACCES)
end
end
platform_is :windows do
it "raises Errno::EACCES or Errno::ENOEXEC when the file is not an executable file" do
- lambda { Process.exec __FILE__ }.should raise_error(SystemCallError) { |e|
+ -> { Process.exec __FILE__ }.should raise_error(SystemCallError) { |e|
[Errno::EACCES, Errno::ENOEXEC].should include(e.class)
}
end
end
end
- platform_is_not :openbsd do
- it "raises Errno::EACCES when passed a directory" do
- lambda { Process.exec File.dirname(__FILE__) }.should raise_error(Errno::EACCES)
- end
- end
-
- platform_is :openbsd do
- it "raises Errno::EISDIR when passed a directory" do
- lambda { Process.exec File.dirname(__FILE__) }.should raise_error(Errno::EISDIR)
- end
+ it "raises Errno::EACCES when passed a directory" do
+ -> { Process.exec __dir__ }.should raise_error(Errno::EACCES)
end
it "runs the specified command, replacing current process" do
- ruby_exe('Process.exec "echo hello"; puts "fail"', escape: true).should == "hello\n"
+ ruby_exe('Process.exec "echo hello"; puts "fail"').should == "hello\n"
end
it "sets the current directory when given the :chdir option" do
tmpdir = tmp("")[0..-2]
platform_is_not :windows do
- ruby_exe("Process.exec(\"pwd\", chdir: #{tmpdir.inspect})", escape: true).should == "#{tmpdir}\n"
+ ruby_exe("Process.exec(\"pwd\", chdir: #{tmpdir.inspect})").should == "#{tmpdir}\n"
end
platform_is :windows do
- ruby_exe("Process.exec(\"cd\", chdir: #{tmpdir.inspect})", escape: true).tr('\\', '/').should == "#{tmpdir}\n"
+ ruby_exe("Process.exec(\"cd\", chdir: #{tmpdir.inspect})").tr('\\', '/').should == "#{tmpdir}\n"
end
end
@@ -81,13 +73,13 @@ describe "Process.exec" do
platform_is_not :windows do
it "subjects the specified command to shell expansion" do
result = Dir.chdir(@dir) do
- ruby_exe('Process.exec "echo *"', escape: true)
+ ruby_exe('Process.exec "echo *"')
end
result.chomp.should == @name
end
it "creates an argument array with shell parsing semantics for whitespace" do
- ruby_exe('Process.exec "echo a b c d"', escape: true).should == "a b c d\n"
+ ruby_exe('Process.exec "echo a b c d"').should == "a b c d\n"
end
end
@@ -95,13 +87,13 @@ describe "Process.exec" do
# There is no shell expansion on Windows
it "does not subject the specified command to shell expansion on Windows" do
result = Dir.chdir(@dir) do
- ruby_exe('Process.exec "echo *"', escape: true)
+ ruby_exe('Process.exec "echo *"')
end
result.should == "*\n"
end
it "does not create an argument array with shell parsing semantics for whitespace on Windows" do
- ruby_exe('Process.exec "echo a b c d"', escape: true).should == "a b c d\n"
+ ruby_exe('Process.exec "echo a b c d"').should == "a b c d\n"
end
end
@@ -113,7 +105,7 @@ describe "Process.exec" do
platform_is :windows do
cmd = '"cmd.exe", "/C", "echo", "*"'
end
- ruby_exe("Process.exec #{cmd}", escape: true).should == "*\n"
+ ruby_exe("Process.exec #{cmd}").should == "*\n"
end
end
@@ -132,29 +124,29 @@ describe "Process.exec" do
end
it "sets environment variables in the child environment" do
- ruby_exe('Process.exec({"FOO" => "BAR"}, "echo ' + var + '")', escape: true).should == "BAR\n"
+ ruby_exe('Process.exec({"FOO" => "BAR"}, "echo ' + var + '")').should == "BAR\n"
end
it "unsets environment variables whose value is nil" do
platform_is_not :windows do
- ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")', escape: true).should == "\n"
+ ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")').should == "\n"
end
platform_is :windows do
# On Windows, echo-ing a non-existent env var is treated as echo-ing any other string of text
- ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")', escape: true).should == var + "\n"
+ ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")').should == var + "\n"
end
end
it "coerces environment argument using to_hash" do
- ruby_exe('o = Object.new; def o.to_hash; {"FOO" => "BAR"}; end; Process.exec(o, "echo ' + var + '")', escape: true).should == "BAR\n"
+ ruby_exe('o = Object.new; def o.to_hash; {"FOO" => "BAR"}; end; Process.exec(o, "echo ' + var + '")').should == "BAR\n"
end
it "unsets other environment variables when given a true :unsetenv_others option" do
platform_is_not :windows do
- ruby_exe('Process.exec("echo ' + var + '", unsetenv_others: true)', escape: true).should == "\n"
+ ruby_exe('Process.exec("echo ' + var + '", unsetenv_others: true)').should == "\n"
end
platform_is :windows do
- ruby_exe('Process.exec("' + ENV['COMSPEC'].gsub('\\', '\\\\\\') + ' /C echo ' + var + '", unsetenv_others: true)', escape: true).should == var + "\n"
+ ruby_exe('Process.exec("' + ENV['COMSPEC'].gsub('\\', '\\\\\\') + ' /C echo ' + var + '", unsetenv_others: true)').should == var + "\n"
end
end
end
@@ -162,26 +154,26 @@ describe "Process.exec" do
describe "with a command array" do
it "uses the first element as the command name and the second as the argv[0] value" do
platform_is_not :windows do
- ruby_exe('Process.exec(["/bin/sh", "argv_zero"], "-c", "echo $0")', escape: true).should == "argv_zero\n"
+ ruby_exe('Process.exec(["/bin/sh", "argv_zero"], "-c", "echo $0")').should == "argv_zero\n"
end
platform_is :windows do
- ruby_exe('Process.exec(["cmd.exe", "/C"], "/C", "echo", "argv_zero")', escape: true).should == "argv_zero\n"
+ ruby_exe('Process.exec(["cmd.exe", "/C"], "/C", "echo", "argv_zero")').should == "argv_zero\n"
end
end
it "coerces the argument using to_ary" do
platform_is_not :windows do
- ruby_exe('o = Object.new; def o.to_ary; ["/bin/sh", "argv_zero"]; end; Process.exec(o, "-c", "echo $0")', escape: true).should == "argv_zero\n"
+ ruby_exe('o = Object.new; def o.to_ary; ["/bin/sh", "argv_zero"]; end; Process.exec(o, "-c", "echo $0")').should == "argv_zero\n"
end
platform_is :windows do
- ruby_exe('o = Object.new; def o.to_ary; ["cmd.exe", "/C"]; end; Process.exec(o, "/C", "echo", "argv_zero")', escape: true).should == "argv_zero\n"
+ ruby_exe('o = Object.new; def o.to_ary; ["cmd.exe", "/C"]; end; Process.exec(o, "/C", "echo", "argv_zero")').should == "argv_zero\n"
end
end
it "raises an ArgumentError if the Array does not have exactly two elements" do
- lambda { Process.exec([]) }.should raise_error(ArgumentError)
- lambda { Process.exec([:a]) }.should raise_error(ArgumentError)
- lambda { Process.exec([:a, :b, :c]) }.should raise_error(ArgumentError)
+ -> { Process.exec([]) }.should raise_error(ArgumentError)
+ -> { Process.exec([:a]) }.should raise_error(ArgumentError)
+ -> { Process.exec([:a, :b, :c]) }.should raise_error(ArgumentError)
end
end
@@ -200,18 +192,49 @@ describe "Process.exec" do
it "maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value" do
map_fd_fixture = fixture __FILE__, "map_fd.rb"
cmd = <<-EOC
- f = File.open("#{@name}", "w+")
- child_fd = f.fileno + 1
- File.open("#{@child_fd_file}", "w") { |io| io.print child_fd }
- Process.exec "#{ruby_cmd(map_fd_fixture)} \#{child_fd}", { child_fd => f }
+ f = File.open(#{@name.inspect}, "w+")
+ File.open(#{__FILE__.inspect}, "r") do |io|
+ child_fd = io.fileno
+ File.open(#{@child_fd_file.inspect}, "w") { |io| io.print child_fd }
+ Process.exec "#{ruby_cmd(map_fd_fixture)} \#{child_fd}", { child_fd => f }
+ end
EOC
- ruby_exe(cmd, escape: true)
+ ruby_exe(cmd)
child_fd = IO.read(@child_fd_file).to_i
child_fd.to_i.should > STDERR.fileno
File.read(@name).should == "writing to fd: #{child_fd}"
end
+
+ it "lets the process after exec have specified file descriptor despite close_on_exec" do
+ map_fd_fixture = fixture __FILE__, "map_fd.rb"
+ cmd = <<-EOC
+ f = File.open(#{@name.inspect}, 'w+')
+ puts(f.fileno, f.close_on_exec?)
+ STDOUT.flush
+ Process.exec("#{ruby_cmd(map_fd_fixture)} \#{f.fileno}", f.fileno => f.fileno)
+ EOC
+
+ output = ruby_exe(cmd)
+ child_fd, close_on_exec = output.split
+
+ child_fd.to_i.should > STDERR.fileno
+ close_on_exec.should == 'true'
+ File.read(@name).should == "writing to fd: #{child_fd}"
+ end
+
+ it "sets close_on_exec to false on specified fd even when it fails" do
+ cmd = <<-EOC
+ f = File.open(#{__FILE__.inspect}, 'r')
+ puts(f.close_on_exec?)
+ Process.exec('/', f.fileno => f.fileno) rescue nil
+ puts(f.close_on_exec?)
+ EOC
+
+ output = ruby_exe(cmd)
+ output.split.should == ['true', 'false']
+ end
end
end
end