fix piping of redirected stdout

e.g.
Assume you have a script that print to stdout as well as stderr:
[test.lua]
print("foo")
io.stderr:write("bar")

Then run this script, redirecting [2] to stdout, and [1] to dev null, then piping to grep

./test.lua 2>&1 >/dev/null | grep baz

This test should print NOTHING to the terminal, "foo" went to dev null, "bar" when to stdout, and grep matched on "baz", thus should not print. But the bug I found was that [2] was redirected to terminal tty stdout and then AFTER that the piping code added a pipe on [1], but [2] was already pointing to tty. The fix is to move the piping before redirections are created, so that when [2] redirects to stdout, stdout is already the pipe.
This commit is contained in:
payonel 2016-07-21 09:38:16 -07:00
parent 5be3dc5ad2
commit 35d93e2a93

View File

@ -252,27 +252,32 @@ function sh.internal.createThreads(commands, eargs, env)
threads[i] = thread threads[i] = thread
if thread then if not thread then
-- smart check if ios should be loaded
if tx.first(args, function(token) return token == "<" or token:find(">") end) then
args, reason = sh.internal.buildCommandRedirects(thread, args)
end
end
if not args or not thread then
for i,t in ipairs(threads) do for i,t in ipairs(threads) do
process.internal.close(t) process.internal.close(t)
end end
return nil, reason return nil, reason
end end
process.info(thread).data.args = tx.concat(args, eargs or {}) process.info(thread).data.args = args
end end
if #threads > 1 then if #threads > 1 then
sh.internal.buildPipeChain(threads) sh.internal.buildPipeChain(threads)
end end
for i = 1, #threads do
local thread = threads[i]
local args = process.info(thread).data.args
-- smart check if ios should be loaded
if tx.first(args, function(token) return token == "<" or token:find(">") end) then
args, reason = sh.internal.buildCommandRedirects(thread, args)
end
process.info(thread).data.args = tx.concat(args, eargs or {})
end
return threads return threads
end end