(Submitted as requested by Jeff Mc Cune?)
I've been fighting these annoying hangs for a day and a bit and
finally have something I believe works. It's not elegant (the
approaches I took became steadily more hacky...) but it seems to work
for me.
I started using a trimmed version of util.rb:execute, asking it run
run "apt-get install osirisd". strace()ing this showed the read()
being restarted. The child process had died but puppet was still
reading from the pipe.
I tried using readpartial and read_nonblock but these didn't seem to
capture the stdout and stderr (no idea why - they worked in the
trimmed version but not when run in puppet).
I then tried using pipes and also spawning threads to either do the
reads (using readpartial) or to do the Process.waitpid and then close
the file descriptor. Again, this worked in the trimmed version but
not in puppet (neither stdout or stderr were captured).
Finally in desperation I thought "sod it" and redirected the child
process to a temporary file. This appears to work but I've only tried
a few simple tests on it.
I've attached two diffs against 0.22.4 - a full diff and a diff
excluding whitespace differences.