Markus Roberts <[email protected]> writes:
> This last bears some elaboration; if the following steps occur:
>
> * Puppet "exec"s child process (apt-get, for example) and attempts to
> capture the output
> * The child process launches a "grandchild" process (the buggy version
> of the osirid daemon under Debian Etch, for example) without closing
> its STDOUT
> * The grandchild does not close its inherited STDOUT
> * The child exits
> * The grandchild does not trap SIGPIPE
> * The grandchild writes to STDOUT
>
> the grandchild will receive an (unhandled) SIGPIPE and exit. There is
> no presently known case where this would occur (the osirid daemon, as
> best as I can determine, did not actually write to the handle, just
> kept it around out of misplaced sentimentality). The solutions to
> this problem, if it exists, are messy and best left unimplemented
> unless they are needed.
just a note: it's quite essential that SIGPIPE is set to SIG_DFL in the
child process. luckily, execve(2) will reset to SIG_DFL unless it's set
to SIG_IGN. a child with SIGPIPE set unexpectedly to SIG_IGN can easily
get stuck in endless loops. the grandchild SHOULD die when it tries to
write to the closed stdout.
> + method = output_read.respond_to?(:readpartial) ? :readpartial : :sysread
> + begin
> + # The timeout needs to be high enough to avoid thrashing but low
> + # enough that we don't waste too much time waiting for processes
> + # that exit without closing the pipe (see ticket #1563 comment #7)
> + # One second seems a reasonable compromise.
> + output << timeout(1) { output_read.send(method,1) } while true
> + rescue Timeout::Error
> + break if reaped_pid = Process.waitpid(child_pid,Process::WNOHANG)
> + rescue Errno::EINTR
> + # Just popping out to handle an unrelated signal, but we're not done
> + end while true
I guess this will work, but it seems a bit hackish compared to just
catching SIGCHLD. if done right, no polling (timeout) is needed.
> ENV['LANG'] = ENV['LC_ALL'] = ENV['LC_MESSAGES'] = ENV['LANGUAGE'] =
> 'C'
> Kernel.exec(*command)
not part of your patch, but I couldn't resist commenting on this cargo
cult code :-). setting ENV['LC_ALL'] is sufficient. 'LANGUAGE' is not
POSIX, and not consulted when LC_MESSAGES (effectively) is 'C'.
--
Kjetil T. Homme
Redpill Linpro AS - Changing the game
--
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en.