<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -7,6 +7,7 @@ require 'facter/util/confine'
 
 require 'timeout'
 require 'rbconfig'
+require 'open3'
 
 class Facter::Util::Resolution
     attr_accessor :interpreter, :code, :name, :timeout
@@ -42,17 +43,27 @@ class Facter::Util::Resolution
         end
 
         out = nil
+        err = nil
         begin
-            out = %x{#{code}}.chomp
+            Open3.popen3(code) do |stdin,stdout,stderr|
+              out = self.parse_output(stdout.readlines)
+              err = self.parse_output(stderr.readlines)
+            end
         rescue =&gt; detail
             $stderr.puts detail
             return nil
         end
-        if out == &quot;&quot;
-            return nil
-        else
-            return out
-        end
+        Facter.warn(err)
+
+        return nil if out == &quot;&quot;
+        out
+    end
+
+    def self.parse_output(output)
+        return nil unless output and output.size &gt; 0
+        result = output.collect{|line| line.chomp }
+        return result.first unless result.size &gt; 1
+        result
     end
 
     # Add a new confine to the resolution mechanism.</diff>
      <filename>lib/facter/util/resolution.rb</filename>
    </modified>
    <modified>
      <diff>@@ -227,10 +227,54 @@ describe Facter::Util::Resolution do
         Facter::Util::Resolution.should respond_to(:exec)
     end
 
+    it &quot;should have a class method to parse output&quot; do
+        Facter::Util::Resolution.should respond_to(:parse_output)
+    end
+
     # It's not possible, AFAICT, to mock %x{}, so I can't really test this bit.
     describe &quot;when executing code&quot; do
         it &quot;should fail if any interpreter other than /bin/sh is requested&quot; do
             lambda { Facter::Util::Resolution.exec(&quot;/something&quot;, &quot;/bin/perl&quot;) }.should raise_error(ArgumentError)
         end
+
+        it &quot;should produce stderr content as a warning&quot; do
+            stdout = stdin = stub('fh', :readlines =&gt; [&quot;aaa\n&quot;])
+            stderr = stub('stderr', :readlines =&gt; %w{my content})
+            Open3.expects(:popen3).with(&quot;/bin/true&quot;).yields(stdin, stdout, stderr)
+
+            Facter.expects(:warn).with(['my','content'])
+            Facter::Util::Resolution.exec(&quot;/bin/true&quot;).should == 'aaa'
+        end
+
+        it &quot;should produce nil as a warning if nothing is printed to stderr&quot; do
+            stdout = stdin = stub('fh', :readlines =&gt; [&quot;aaa\n&quot;])
+            stderr = stub('stderr', :readlines =&gt; [])
+            Open3.expects(:popen3).with(&quot;/bin/true&quot;).yields(stdin, stdout, stderr)
+
+            Facter.expects(:warn).with(nil)
+            Facter::Util::Resolution.exec(&quot;/bin/true&quot;).should == 'aaa'
+        end
+    end
+
+    describe &quot;when parsing output&quot; do
+        it &quot;should return nil on nil&quot; do
+            Facter::Util::Resolution.parse_output(nil).should be_nil
+        end
+
+        it &quot;should return nil on empty string&quot; do
+            Facter::Util::Resolution.parse_output('').should be_nil
+        end
+
+        it &quot;should return nil on an empty array&quot; do
+            Facter::Util::Resolution.parse_output([]).should be_nil
+        end
+
+        it &quot;should return a string on a 1 size array&quot; do
+            Facter::Util::Resolution.parse_output([&quot;aaa\n&quot;]).should == &quot;aaa&quot;
+        end
+
+        it &quot;should return a string on a multi sized array containing a seperator&quot; do
+            result = Facter::Util::Resolution.parse_output([&quot;aaa\n&quot;,&quot;bbb\n&quot;,&quot;ccc\n&quot;]).should == [ &quot;aaa&quot;, &quot;bbb&quot;, &quot;ccc&quot; ]
+        end
     end
 end</diff>
      <filename>spec/unit/util/resolution.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>810980659d86a30cc9dde6018a4749f659fe2d00</id>
    </parent>
  </parents>
  <author>
    <name>Peter Meier</name>
    <email>peter.meier@immerda.ch</email>
  </author>
  <url>http://github.com/jamtur01/facter/commit/fabe21e702e7d3878fc0775a7dcf24c44aaf4698</url>
  <id>fabe21e702e7d3878fc0775a7dcf24c44aaf4698</id>
  <committed-date>2009-11-07T03:16:14-08:00</committed-date>
  <authored-date>2009-11-07T03:10:56-08:00</authored-date>
  <message>use popen3 in Resolution.exec to catch stderr

So far messages to stderr haven't been catched by
Facter::Util::Resolution.exec and were insted printed out to
stderr. This will cause facter and even puppet to print to stderr
themself, which is not very nice when running puppetd by cron,
as you might get every run a mail if a command outputs to stderr.

We are now wrapping the command execution with Open3.popen3 to
catch stderr and passing them to the new introduced Facter.warn
method.

We are also catching multiline outputs chomping newlines and
returning an array if there have been more than one line. Otherwise
we return an array containing the different lines.

This prevents in general cases as described in #2766 and should
handle command execution in a bit saner way.</message>
  <tree>c28a42981ccf4d7547079e7d3dae04e6104e7bee</tree>
  <committer>
    <name>James Turnbull</name>
    <email>james@lovedthanlost.net</email>
  </committer>
</commit>
