summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorJames Turnbull <james@lovedthanlost.net>2009-12-31 17:34:30 +1100
committerJames Turnbull <james@lovedthanlost.net>2009-12-31 17:34:30 +1100
commitc84186ab0736a8e1379294546159d8f6cfec6894 (patch)
treeb13e63dc28f6aafe8b3954dc394e2446ea2b6e80 /lib/puppet
parent74d9693516df7f15b2940537eb414ad78436e774 (diff)
downloadpuppet-c84186ab0736a8e1379294546159d8f6cfec6894.tar.gz
puppet-c84186ab0736a8e1379294546159d8f6cfec6894.tar.xz
puppet-c84186ab0736a8e1379294546159d8f6cfec6894.zip
Revert "Fix for #2731 (problem communicating with processes in SELinux)"
Due to problems introduced on HP-UX (See #2997) This reverts commit 6ab2453d966d1d48e12d8a8cec34b9e460597d04.
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/util.rb73
1 files changed, 51 insertions, 22 deletions
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index dd6ae69fa..21573d1da 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -259,17 +259,28 @@ module Util
@@os ||= Facter.value(:operatingsystem)
output = nil
child_pid, child_status = nil
- output_read, output_write = IO.pipe
+ # There are problems with read blocking with badly behaved children
+ # read.partialread doesn't seem to capture either stdout or stderr
+ # We hack around this using a temporary file
+
+ # The idea here is to avoid IO#read whenever possible.
+ output_file="/dev/null"
+ error_file="/dev/null"
+ if ! arguments[:squelch]
+ require "tempfile"
+ output_file = Tempfile.new("puppet")
+ if arguments[:combine]
+ error_file=output_file
+ end
+ end
oldverb = $VERBOSE
$VERBOSE = nil
child_pid = Kernel.fork
$VERBOSE = oldverb
if child_pid
- output_write.close
# Parent process executes this
- Process.waitpid(child_pid)
- child_status = $?.exitstatus
+ child_status = (Process.waitpid2(child_pid)[1]).to_i >> 8
else
# Child process executes this
Process.setsid
@@ -277,18 +288,10 @@ module Util
if arguments[:stdinfile]
$stdin.reopen(arguments[:stdinfile])
else
- $stdin.close
- end
- if arguments[:squelch]
- $stdout.close
- else
- $stdout.reopen(output_write)
- end
- if arguments[:combine]
- $stderr.reopen(output_write)
- else
- $stderr.close
+ $stdin.reopen("/dev/null")
end
+ $stdout.reopen(output_file)
+ $stderr.reopen(error_file)
3.upto(256){|fd| IO::new(fd).close rescue nil}
if arguments[:gid]
@@ -300,17 +303,43 @@ module Util
Process.uid = arguments[:uid] unless @@os == "Darwin"
end
ENV['LANG'] = ENV['LC_ALL'] = ENV['LC_MESSAGES'] = ENV['LANGUAGE'] = 'C'
- Kernel.exec(*command)
+ if command.is_a?(Array)
+ Kernel.exec(*command)
+ else
+ Kernel.exec(command)
+ end
rescue => detail
- puts detail
+ puts detail.to_s
exit!(1)
- end
- end
+ end # begin; rescue
+ end # if child_pid
# read output in if required
if ! arguments[:squelch]
- output = output_read.read
- output_read.close
+
+ # Make sure the file's actually there. This is
+ # basically a race condition, and is probably a horrible
+ # way to handle it, but, well, oh well.
+ unless FileTest.exists?(output_file.path)
+ Puppet.warning "sleeping"
+ sleep 0.5
+ unless FileTest.exists?(output_file.path)
+ Puppet.warning "sleeping 2"
+ sleep 1
+ unless FileTest.exists?(output_file.path)
+ Puppet.warning "Could not get output"
+ output = ""
+ end
+ end
+ end
+ unless output
+ # We have to explicitly open here, so that it reopens
+ # after the child writes.
+ output = output_file.open.read
+
+ # The 'true' causes the file to get unlinked right away.
+ output_file.close(true)
+ end
end
if arguments[:failonfail]
@@ -319,7 +348,7 @@ module Util
end
end
- output
+ return output
end
module_function :execute