“1.8.7” as a frozen string. We use this with a hack that disables GC to avoid segfaults on Ruby 1.8.7, so we need to allocate the fewest objects we possibly can.
Run the command, writing the command’s standard out and standard error to stdout and stderr, and saving its exit status object to status
returns self; stdout, stderr, status, and exitstatus will be populated with results of the command.
Errno::EACCES when you are not privileged to execute the command
Errno::ENOENT when the command is not available on the system (or not in the current $PATH)
Chef::Exceptions::CommandTimeout when the command does not complete within timeout seconds (default: 600s). When this happens, ShellOut will send a TERM and then KILL to the entire process group to ensure that any grandchild processes are terminated. If the invocation of the child process spawned multiple child processes (which commonly happens if the command is passed as a single string to be interpreted by bin/sh, and bin/sh is not bash), the exit status object may not contain the correct exit code of the process (of course there is no exit code if the command is killed by SIGKILL, also).
# File lib/mixlib/shellout/unix.rb, line 51 def run_command @child_pid = fork_subprocess @reaped = false configure_parent_process_file_descriptors # Ruby 1.8.7 and 1.8.6 from mid 2009 try to allocate objects during GC # when calling IO.select and IO#read. Disabling GC works around the # segfault, but obviously it's a bad workaround. We no longer support # 1.8.6 so we only need this hack for 1.8.7. GC.disable if RUBY_VERSION == ONE_DOT_EIGHT_DOT_SEVEN # CHEF-3390: Marshall.load on Ruby < 1.8.7p369 also has a GC bug related # to Marshall.load, so try disabling GC first. propagate_pre_exec_failure get_child_pgid @result = nil @execution_time = 0 write_to_child_stdin until @status ready_buffers = attempt_buffer_read unless ready_buffers @execution_time += READ_WAIT_TIME if @execution_time >= timeout && !@result # kill the bad proccess reap_errant_child # read anything it wrote when we killed it attempt_buffer_read # raise raise CommandTimeout, "Command timed out after #{@execution_time.to_i}s:\n#{format_for_exception}" end end attempt_reap end self rescue Errno::ENOENT # When ENOENT happens, we can be reasonably sure that the child process # is going to exit quickly, so we use the blocking variant of waitpid2 reap raise ensure reap_errant_child if should_reap? # make one more pass to get the last of the output after the # child process dies attempt_buffer_read # no matter what happens, turn the GC back on, and hope whatever busted # version of ruby we're on doesn't allocate some objects during the next # GC run. GC.enable close_all_pipes end
Generated with the Darkfish Rdoc Generator 2.