Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"certstore",
"CFPREFERENCES",
"cfprefsd",
"cgroupv",
"chaput",
"chardev",
"chatops",
Expand Down Expand Up @@ -333,6 +334,7 @@
"dscacheutil",
"dscresource",
"dslocal",
"ducktype",
"DUPEUX",
"DWORDLONG",
"DYNALINK",
Expand All @@ -358,6 +360,7 @@
"encap",
"Encryptor",
"encryptor",
"endgrent",
"endlocal",
"entriesread",
"envdata",
Expand Down Expand Up @@ -451,6 +454,7 @@
"GETFD",
"GETFL",
"getgr",
"getgrent",
"getgrgid",
"getgrnam",
"gethostbyname",
Expand Down Expand Up @@ -704,6 +708,7 @@
"loginclass",
"loginwindow",
"LOGLOCATION",
"LOGNAME",
"logopts",
"logstring",
"LONGLONG",
Expand Down Expand Up @@ -1017,6 +1022,7 @@
"PFILETIME",
"PFLOAT",
"PGENERICMAPPING",
"pgid",
"phabricator",
"PHALF",
"PHANDLE",
Expand Down Expand Up @@ -1245,6 +1251,8 @@
"Scriptable",
"SCROLLBAR",
"SCROLLBARS",
"secondarygroups",
"seconderies",
"secontext",
"secoption",
"secopts",
Expand Down Expand Up @@ -1291,6 +1299,7 @@
"SETTINGCHANGE",
"setuid",
"SETX",
"sgids",
"SHARENAME",
"SHAs",
"shas",
Expand Down Expand Up @@ -1626,6 +1635,7 @@
"WINVER",
"WKSTA",
"WMIGUID",
"WNOHANG",
"woot",
"workdir",
"WPARAM",
Expand Down
44 changes: 32 additions & 12 deletions lib/mixlib/shellout/unix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def run_command
unless ready_buffers
@execution_time += READ_WAIT_TIME
if @execution_time >= timeout && !@result
# kill the bad proccess
# kill the bad process
reap_errant_child
# read anything it wrote when we killed it
attempt_buffer_read
Expand Down Expand Up @@ -288,30 +288,50 @@ def attempt_buffer_read(timeout = READ_WAIT_TIME)
ready
end

def read_stdout_to_buffer
while ( chunk = child_stdout.read_nonblock(READ_SIZE) )
@stdout << chunk
@live_stdout << chunk if @live_stdout
# Drain everything currently readable on +io+ into +buffer+, and into
# +live+ as well when a live stream is attached.
#
# Without a live stream we can hand read_nonblock a scratch buffer to
# read into and reuse it for every read, rather than letting it allocate
# a fresh READ_SIZE String each time -- for an output-heavy command that
# is nearly all of the garbage this class produces. Reuse is safe here
# only because #<< copies the bytes into +buffer+.
#
# A live stream is free to hold onto whatever it is handed, so when one
# is attached each read gets its own String, exactly as before.
def drain(io, buffer, live, scratch)
if live
while ( chunk = io.read_nonblock(READ_SIZE) )
buffer << chunk
live << chunk
end
else
while ( chunk = io.read_nonblock(READ_SIZE, scratch) )
buffer << chunk
end
end
end

def read_buffer(name)
(@read_buffers ||= {})[name] ||= String.new
end

def read_stdout_to_buffer
drain(child_stdout, @stdout, @live_stdout, read_buffer(:stdout))
rescue Errno::EAGAIN
rescue EOFError
open_pipes.delete(child_stdout)
end

def read_stderr_to_buffer
while ( chunk = child_stderr.read_nonblock(READ_SIZE) )
@stderr << chunk
@live_stderr << chunk if @live_stderr
end
drain(child_stderr, @stderr, @live_stderr, read_buffer(:stderr))
rescue Errno::EAGAIN
rescue EOFError
open_pipes.delete(child_stderr)
end

def read_process_status_to_buffer
while ( chunk = child_process_status.read_nonblock(READ_SIZE) )
@process_status << chunk
end
drain(child_process_status, @process_status, nil, read_buffer(:process_status))
rescue Errno::EAGAIN
rescue EOFError
open_pipes.delete(child_process_status)
Expand Down
Loading