-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make it possible again to read STDERR without calling cat
#11919
Changes from 3 commits
14bdff3
a201a5b
ac569bd
10966d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1160,7 +1160,8 @@ export | |
nb_available, | ||
ntoh, | ||
open, | ||
pipe, | ||
pipeline, | ||
Pipe, | ||
PipeBuffer, | ||
poll_fd, | ||
poll_file, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,7 +50,7 @@ function show(io::IO, cmd::Cmd) | |
end | ||
|
||
function show(io::IO, cmds::Union{OrCmds,ErrOrCmds}) | ||
print(io, "pipe(") | ||
print(io, "pipeline(") | ||
show(io, cmds.a) | ||
print(io, ", ") | ||
print(io, isa(cmds, ErrOrCmds) ? "stderr=" : "stdout=") | ||
|
@@ -100,7 +100,7 @@ type CmdRedirect <: AbstractCmd | |
end | ||
|
||
function show(io::IO, cr::CmdRedirect) | ||
print(io, "pipe(") | ||
print(io, "pipeline(") | ||
show(io, cr.cmd) | ||
print(io, ", ") | ||
if cr.stream_no == STDOUT_NO | ||
|
@@ -149,7 +149,7 @@ redir_err(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirec | |
redir_out_append(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, true), STDOUT_NO) | ||
redir_err_append(src::AbstractCmd, dest::AbstractString) = CmdRedirect(src, FileRedirect(dest, true), STDERR_NO) | ||
|
||
function pipe(cmd::AbstractCmd; stdin=nothing, stdout=nothing, stderr=nothing, append::Bool=false) | ||
function pipeline(cmd::AbstractCmd; stdin=nothing, stdout=nothing, stderr=nothing, append::Bool=false) | ||
if append && stdout === nothing && stderr === nothing | ||
error("append set to true, but no output redirections specified") | ||
end | ||
|
@@ -165,10 +165,10 @@ function pipe(cmd::AbstractCmd; stdin=nothing, stdout=nothing, stderr=nothing, a | |
return cmd | ||
end | ||
|
||
pipe(cmd::AbstractCmd, dest) = pipe(cmd, stdout=dest) | ||
pipe(src::Union{Redirectable,AbstractString}, cmd::AbstractCmd) = pipe(cmd, stdin=src) | ||
pipeline(cmd::AbstractCmd, dest) = pipeline(cmd, stdout=dest) | ||
pipeline(src::Union{Redirectable,AbstractString}, cmd::AbstractCmd) = pipeline(cmd, stdin=src) | ||
|
||
pipe(a, b, c, d...) = pipe(pipe(a,b), c, d...) | ||
pipeline(a, b, c, d...) = pipeline(pipeline(a,b), c, d...) | ||
|
||
typealias RawOrBoxedHandle Union{UVHandle,AsyncStream,Redirectable,IOStream} | ||
typealias StdIOSet NTuple{3,RawOrBoxedHandle} | ||
|
@@ -311,7 +311,9 @@ macro setup_stdio() | |
in,out,err = stdios | ||
if isa(stdios[1], Pipe) | ||
if stdios[1].handle == C_NULL | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ref #10469 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reminder (this should be using the test There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As per our discussion, the C_NULL here should be fine as this way you get an error in the use-after-close case whereas otherwise it would silently pass |
||
error("pipes passed to spawn must be initialized") | ||
in = box(Ptr{Void},Intrinsics.jl_alloca(_sizeof_uv_named_pipe)) | ||
link_pipe(in,false,stdios[1],true) | ||
close_in = true | ||
end | ||
elseif isa(stdios[1], FileRedirect) | ||
in = FS.open(stdios[1].filename, JL_O_RDONLY) | ||
|
@@ -321,7 +323,9 @@ macro setup_stdio() | |
end | ||
if isa(stdios[2], Pipe) | ||
if stdios[2].handle == C_NULL | ||
error("pipes passed to spawn must be initialized") | ||
out = box(Ptr{Void},Intrinsics.jl_alloca(_sizeof_uv_named_pipe)) | ||
link_pipe(stdios[2],true,out,false) | ||
close_out = true | ||
end | ||
elseif isa(stdios[2], FileRedirect) | ||
out = FS.open(stdios[2].filename, JL_O_WRONLY | JL_O_CREAT | (stdios[2].append?JL_O_APPEND:JL_O_TRUNC), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) | ||
|
@@ -331,7 +335,9 @@ macro setup_stdio() | |
end | ||
if isa(stdios[3], Pipe) | ||
if stdios[3].handle == C_NULL | ||
error("pipes passed to spawn must be initialized") | ||
err = box(Ptr{Void},Intrinsics.jl_alloca(_sizeof_uv_named_pipe)) | ||
link_pipe(stdios[3],true,err,false) | ||
close_err = true | ||
end | ||
elseif isa(stdios[3], FileRedirect) | ||
err = FS.open(stdios[3].filename, JL_O_WRONLY | JL_O_CREAT | (stdios[3].append?JL_O_APPEND:JL_O_TRUNC), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) | ||
|
@@ -345,9 +351,9 @@ end | |
macro cleanup_stdio() | ||
esc( | ||
quote | ||
close_in && close(in) | ||
close_out && close(out) | ||
close_err && close(err) | ||
close_in && (isa(in,Ptr) ? close_pipe_sync(in) : close(in)) | ||
close_out && (isa(out,Ptr) ? close_pipe_sync(out) : close(out)) | ||
close_err && (isa(err,Ptr) ? close_pipe_sync(err) : close(err)) | ||
end) | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kinda confusing to export this when it's a rather different thing than the
pipe
functionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think once processes are readable/writable, this can just be
pipe()
(although @vtjnash wants that to return a pair). I think maybe the right design is instead of have another method that creates the other pipe end.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe have a real API design discussion about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd be ok with calling this
pipe()
and addingpipepair()
in the future if necessary. Names that differ only in case are really annoying.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what does the
pipe
function do now then? Either connect two commands via a pipe or construct a pipe object?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keno and I both suggested that at the beginning of this thread 17 days ago.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with that is that
pipe
with more than one argument is a lazy constructor for a command object, whilePipe()
creates a pipe object thatrun
modifies.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might just have to be
Pipe
andpipeline
, though I sorta dread having to tell people they have to go from one character to 8 for this functionality.Of course, I also suggested
const 🚰= Pipe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Maybe having
pipe
andPipe
isn't so bad :-\There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One suggestion that I forgot to mention here was
pipe
andPipeEnd
. I also consideredPiping
(as in to get data out of your pipeline, just add somePiping
).