diff options
author | Daniel DeLeo <dan@opscode.com> | 2012-02-22 13:02:02 -0800 |
---|---|---|
committer | Daniel DeLeo <dan@opscode.com> | 2012-02-22 13:02:02 -0800 |
commit | d67c9a9494c74e6443262024d0e46e83df1af6c6 (patch) | |
tree | bec9c68740d9b6b68f5a02cfeaed1657a85e15a0 | |
parent | c9eb0082179fdeaaced80dacf4dc8df67ae30817 (diff) | |
parent | 6b7ee13e87baec291d982c5d2d81c32866214a49 (diff) | |
download | mixlib-shellout-d67c9a9494c74e6443262024d0e46e83df1af6c6.tar.gz |
Merge branch 'CHEF-2947'
-rw-r--r-- | lib/mixlib/shellout/unix.rb | 4 | ||||
-rw-r--r-- | spec/mixlib/shellout/shellout_spec.rb | 17 |
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 |