summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel DeLeo <dan@opscode.com>2012-02-22 13:02:02 -0800
committerDaniel DeLeo <dan@opscode.com>2012-02-22 13:02:02 -0800
commitd67c9a9494c74e6443262024d0e46e83df1af6c6 (patch)
treebec9c68740d9b6b68f5a02cfeaed1657a85e15a0
parentc9eb0082179fdeaaced80dacf4dc8df67ae30817 (diff)
parent6b7ee13e87baec291d982c5d2d81c32866214a49 (diff)
downloadmixlib-shellout-d67c9a9494c74e6443262024d0e46e83df1af6c6.tar.gz
Merge branch 'CHEF-2947'
-rw-r--r--lib/mixlib/shellout/unix.rb4
-rw-r--r--spec/mixlib/shellout/shellout_spec.rb17
2 files changed, 19 insertions, 2 deletions
diff --git a/lib/mixlib/shellout/unix.rb b/lib/mixlib/shellout/unix.rb
index 243ca24..fe307b5 100644
--- a/lib/mixlib/shellout/unix.rb
+++ b/lib/mixlib/shellout/unix.rb
@@ -185,7 +185,7 @@ module Mixlib
end
rescue Errno::EAGAIN
rescue EOFError
- open_pipes.delete_at(0)
+ open_pipes.delete(child_stdout)
end
def read_stderr_to_buffer
@@ -194,7 +194,7 @@ module Mixlib
end
rescue Errno::EAGAIN
rescue EOFError
- open_pipes.delete_at(1)
+ open_pipes.delete(child_stderr)
end
def fork_subprocess
diff --git a/spec/mixlib/shellout/shellout_spec.rb b/spec/mixlib/shellout/shellout_spec.rb
index cc896e0..5ee0df4 100644
--- a/spec/mixlib/shellout/shellout_spec.rb
+++ b/spec/mixlib/shellout/shellout_spec.rb
@@ -337,6 +337,23 @@ describe Mixlib::ShellOut do
cmd.run_command
cmd.stdout.should == "true"
end
+
+ it "doesn't hang when STDOUT is closed before STDERR" do
+ # Regression test:
+ # We need to ensure that stderr is removed from the list of file
+ # descriptors that we attempt to select() on in the case that:
+ # a) STDOUT closes first
+ # b) STDERR closes
+ # c) The program does not exit for some time after (b) occurs.
+ # Otherwise, we will attempt to read from the closed STDOUT pipe over and
+ # over again and generate lots of garbage, which will not be collected
+ # since we have to turn GC off to avoid segv.
+ cmd = Mixlib::ShellOut.new(%q{ruby -e 'STDOUT.puts "F" * 4096; STDOUT.close; sleep 0.1 STDERR.puts "foo"; STDERR.close; sleep 0.1; exit'})
+ cmd.run_command
+ unclosed_pipes = cmd.send(:open_pipes)
+ unclosed_pipes.should be_empty
+ end
+
end
it "formats itself for exception messages" do