From 3d9621c85299355a08f8b86eaf30c4f23ac312ac Mon Sep 17 00:00:00 2001 From: Mason Protter Date: Thu, 21 Apr 2022 18:22:44 -0600 Subject: [PATCH] Allow `redirect_stdout` to work on a `TeeStream` --- src/TeeStreams.jl | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/TeeStreams.jl b/src/TeeStreams.jl index 5983c29..4d64167 100644 --- a/src/TeeStreams.jl +++ b/src/TeeStreams.jl @@ -120,6 +120,38 @@ end # end # end +# adapted from Logging2.jl +# https://github.com/JuliaLogging/Logging2.jl/blob/094eb6619aeaa8815585dbe7f33b4972f9a4ce6b/src/Logging2.jl#L12-L37 +function (redirect_func::Base.RedirectStdStream)(f::Function, io::TeeStream) + prev_stream, stream_name = + redirect_func.unix_fd == 0 ? (stdin, :stdin) : + redirect_func.unix_fd == 1 ? (stdout, :stdout) : + redirect_func.unix_fd == 2 ? (stderr, :stderr) : + throw(ArgumentError("Not implemented to get old handle of fd except for stdio")) + + result = nothing + + rd, rw = redirect_func() + try + @sync begin + try + Threads.@spawn write(io, rd) # loops while !eof(rd) + result = f() + finally + # To close the read side of the pipe, we must close *all* + # writers. This includes `rw`, but *also* the dup'd fd + # created behind the scenes by redirect_func(). (To close + # that, must call redirect_func() here with the prev stream.) + close(rw) + redirect_func(prev_stream) + end + end + finally + close(rd) + end + return result +end + end # module