-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,36 +44,36 @@ function show(io::IO, cmd::Cmd) | |
end | ||
|
||
function show(io::IO, cmds::OrCmds) | ||
if isa(cmds.a, AndCmds) | ||
print("(") | ||
if isa(cmds.a, AndCmds) || isa(cmds.a, CmdRedirect) | ||
print(io,"(") | ||
show(io, cmds.a) | ||
print(")") | ||
print(io,")") | ||
else | ||
show(io, cmds.a) | ||
end | ||
print(" | ") | ||
if isa(cmds.b, AndCmds) | ||
print("(") | ||
print(" |> ") | ||
if isa(cmds.b, AndCmds) || isa(cmds.b, CmdRedirect) | ||
print(io,"(") | ||
show(io, cmds.b) | ||
print(")") | ||
print(io,")") | ||
else | ||
show(io, cmds.b) | ||
end | ||
end | ||
|
||
function show(io::IO, cmds::AndCmds) | ||
if isa(cmds.a, OrCmds) | ||
print("(") | ||
if isa(cmds.a, OrCmds) || isa(cmds.a, CmdRedirect) | ||
print(io,"(") | ||
show(io, cmds.a) | ||
print(")") | ||
print(io,")") | ||
else | ||
show(io, cmds.a) | ||
end | ||
print(" & ") | ||
if isa(cmds.b, OrCmds) | ||
print("(") | ||
print(io," & ") | ||
if isa(cmds.b, OrCmds) || isa(cmds.b, CmdRedirect) | ||
print(io,"(") | ||
show(io, cmds.b) | ||
print(")") | ||
print(io,")") | ||
else | ||
show(io, cmds.b) | ||
end | ||
|
@@ -83,29 +83,57 @@ const STDIN_NO = 0 | |
const STDOUT_NO = 1 | ||
const STDERR_NO = 2 | ||
|
||
typealias Redirectable Union(UVStream,FS.File) | ||
immutable FileRedirect | ||
filename::ASCIIString | ||
This comment has been minimized.
Sorry, something went wrong. |
||
append::Bool | ||
end | ||
|
||
typealias Redirectable Union(UVStream,FS.File,FileRedirect) | ||
|
||
type CmdRedirect <: AbstractCmd | ||
cmd::AbstractCmd | ||
handle::Redirectable | ||
stream_no::Int | ||
end | ||
|
||
function show(io::IO, cr::CmdRedirect) | ||
if cr.stream_no == STDOUT_NO | ||
show(io,cr.cmd) | ||
print(io," |> ") | ||
show(io,cr.handle) | ||
elseif cr.stream_no == STDERR_NO | ||
show(io,cr.cmd) | ||
print(io," .> ") | ||
show(io,cr.handle) | ||
elseif cr.stream_no == STDIN_NO | ||
show(io,cr.handle) | ||
print(io," |> ") | ||
show(io,cr.cmd) | ||
end | ||
end | ||
|
||
|
||
ignorestatus(cmd::Cmd) = (cmd.ignorestatus=true; cmd) | ||
ignorestatus(cmd::Union(OrCmds,AndCmds)) = (ignorestatus(cmd.a); ignorestatus(cmd.b); cmd) | ||
detach(cmd::Cmd) = (cmd.detach=true; cmd) | ||
|
||
(&)(left::AbstractCmd,right::AbstractCmd) = AndCmds(left,right) | ||
(|)(src::AbstractCmd,dest::AbstractCmd) = OrCmds(src,dest) | ||
(<)(left::AbstractCmd,right::Redirectable) = CmdRedirect(left,right,STDIN_NO) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
(>)(left::AbstractCmd,right::Redirectable) = CmdRedirect(left,right,STDOUT_NO) | ||
(<)(left::AbstractCmd,right::String) = left < FS.open(right,JL_O_RDONLY) | ||
(>)(left::AbstractCmd,right::String) = left > FS.open(right,JL_O_WRONLY|JL_O_CREAT|JL_O_TRUNC,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) | ||
(>>)(left::AbstractCmd,right::String) = left > FS.open(right,JL_O_WRONLY|JL_O_APPEND|JL_O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) | ||
(>)(left::Any,right::AbstractCmd) = right < left | ||
(.>)(left::AbstractCmd,right::Redirectable) = CmdRedirect(left,right,STDERR_NO) | ||
|
||
typealias RawOrBoxedHandle Union(UVHandle,UVStream,FS.File) | ||
(|>)(src::AbstractCmd,dest::AbstractCmd) = OrCmds(src,dest) | ||
|
||
# Stream Redirects | ||
(|>)(dest::Redirectable,src::AbstractCmd) = CmdRedirect(src,dest,STDIN_NO) | ||
(|>)(src::AbstractCmd,dest::Redirectable) = CmdRedirect(src,dest,STDOUT_NO) | ||
(.>)(src::AbstractCmd,dest::Redirectable) = CmdRedirect(src,dest,STDERR_NO) | ||
|
||
# File redirects | ||
(|>)(src::AbstractCmd,dest::ASCIIString) = CmdRedirect(src,FileRedirect(dest,false),STDOUT_NO) | ||
(|>)(dest::Redirectable,src::AbstractCmd) = CmdRedirect(src,dest,STDIN_NO) | ||
(.>)(src::AbstractCmd,dest::Redirectable) = CmdRedirect(src,FileRedirect(dest,false),STDERR_NO) | ||
This comment has been minimized.
Sorry, something went wrong.
JeffBezanson
Member
|
||
(>>)(src::AbstractCmd,dest::ASCIIString) = CmdRedirect(src,FileRedirect(dest,true),STDOUT_NO) | ||
(.>>)(src::AbstractCmd,dest::Redirectable) = CmdRedirect(src,FileRedirect(dest,true),STDERR_NO) | ||
This comment has been minimized.
Sorry, something went wrong.
StefanKarpinski
Member
|
||
|
||
|
||
typealias RawOrBoxedHandle Union(UVHandle,UVStream,FS.File,FileRedirect) | ||
typealias StdIOSet (RawOrBoxedHandle, RawOrBoxedHandle, RawOrBoxedHandle) | ||
|
||
type Process | ||
|
@@ -136,9 +164,9 @@ end | |
|
||
type ProcessChain | ||
processes::Vector{Process} | ||
in::UVStream | ||
out::UVStream | ||
err::UVStream | ||
in::Redirectable | ||
out::Redirectable | ||
err::Redirectable | ||
ProcessChain(stdios::StdIOSet) = new(Process[],stdios[1],stdios[2],stdios[3]) | ||
end | ||
typealias ProcessChainOrNot Union(Bool,ProcessChain) | ||
|
@@ -184,52 +212,6 @@ function _uv_hook_close(proc::Process) | |
notify(proc.closenotify) | ||
end | ||
|
||
function spawn(pc::ProcessChainOrNot,cmd::Cmd,stdios::StdIOSet,exitcb::Callback,closecb::Callback) | ||
loop = eventloop() | ||
close_in,close_out,close_err = false,false,false | ||
pp = Process(cmd,C_NULL,stdios[1],stdios[2],stdios[3]); | ||
in,out,err=stdios | ||
if(isa(stdios[1],NamedPipe)&&stdios[1].handle==C_NULL) | ||
in = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#in = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(in,false,stdios[1],true) | ||
close_in = true | ||
end | ||
if(isa(stdios[2],NamedPipe)&&stdios[2].handle==C_NULL) | ||
out = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#out = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(stdios[2],false,out,true) | ||
close_out = true | ||
end | ||
if(isa(stdios[3],NamedPipe)&&stdios[3].handle==C_NULL) | ||
err = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#err = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(stdios[3],false,err,true) | ||
close_err = true | ||
end | ||
ptrs = _jl_pre_exec(cmd.exec) | ||
pp.exitcb = exitcb | ||
pp.closecb = closecb | ||
pp.handle = _jl_spawn(ptrs[1], convert(Ptr{Ptr{Uint8}}, ptrs), loop, pp, | ||
in,out,err) | ||
if pc != false | ||
push!(pc.processes, pp) | ||
end | ||
if(close_in) | ||
close_pipe_sync(in) | ||
#c_free(in) | ||
end | ||
if(close_out) | ||
close_pipe_sync(out) | ||
#c_free(out) | ||
end | ||
if(close_err) | ||
close_pipe_sync(err) | ||
#c_free(err) | ||
end | ||
pp | ||
end | ||
|
||
function spawn(pc::ProcessChainOrNot,redirect::CmdRedirect,stdios::StdIOSet,exitcb::Callback,closecb::Callback) | ||
spawn(pc,redirect.cmd,(redirect.stream_no==STDIN_NO ?redirect.handle:stdios[1], | ||
redirect.stream_no==STDOUT_NO?redirect.handle:stdios[2], | ||
|
@@ -258,45 +240,95 @@ function spawn(pc::ProcessChainOrNot,cmds::OrCmds,stdios::StdIOSet,exitcb::Callb | |
pc | ||
end | ||
|
||
macro setup_stdio() | ||
esc( | ||
quote | ||
close_in,close_out,close_err = false,false,false | ||
in,out,err = stdios | ||
if isa(stdios[1],NamedPipe) | ||
if stdios[1].handle==C_NULL | ||
in = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#in = c_malloc(_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,O_RDONLY) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
close_in = true | ||
end | ||
if isa(stdios[2],NamedPipe) | ||
if stdios[2].handle==C_NULL | ||
out = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#out = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(stdios[2],false,out,true) | ||
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) | ||
close_out = true | ||
end | ||
if isa(stdios[3],NamedPipe) | ||
if stdios[3].handle==C_NULL | ||
err = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#err = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(stdios[3],false,err,true) | ||
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) | ||
close_err = true | ||
end | ||
end) | ||
end | ||
|
||
macro cleanup_stdio() | ||
esc( | ||
quote | ||
if close_in | ||
if isa(in,Ptr) | ||
close_pipe_sync(in) | ||
else | ||
close(in) | ||
end | ||
end | ||
if(close_out) | ||
if isa(out,Ptr) | ||
close_pipe_sync(out) | ||
else | ||
close(out) | ||
end | ||
end | ||
if(close_err) | ||
if isa(err,Ptr) | ||
close_pipe_sync(err) | ||
else | ||
close(err) | ||
end | ||
end | ||
end) | ||
end | ||
|
||
function spawn(pc::ProcessChainOrNot,cmd::Cmd,stdios::StdIOSet,exitcb::Callback,closecb::Callback) | ||
loop = eventloop() | ||
pp = Process(cmd,C_NULL,stdios[1],stdios[2],stdios[3]); | ||
@setup_stdio | ||
ptrs = _jl_pre_exec(cmd.exec) | ||
pp.exitcb = exitcb | ||
pp.closecb = closecb | ||
pp.handle = _jl_spawn(ptrs[1], convert(Ptr{Ptr{Uint8}}, ptrs), loop, pp, | ||
in,out,err) | ||
@cleanup_stdio | ||
pp | ||
end | ||
|
||
function spawn(pc::ProcessChainOrNot,cmds::AndCmds,stdios::StdIOSet,exitcb::Callback,closecb::Callback) | ||
if pc == false | ||
pc = ProcessChain(stdios) | ||
end | ||
close_in,close_out,close_err = false,false,false | ||
in,out,err = stdios | ||
if(isa(stdios[1],NamedPipe)&&stdios[1].handle==C_NULL) | ||
in = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#in = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(in,false,stdios[1],true) | ||
close_in = true | ||
end | ||
if(isa(stdios[2],NamedPipe)&&stdios[2].handle==C_NULL) | ||
out = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#out = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(stdios[2],false,out,true) | ||
close_out = true | ||
end | ||
if(isa(stdios[3],NamedPipe)&&stdios[3].handle==C_NULL) | ||
err = box(Ptr{Void},Intrinsics.jl_alloca(unbox(Int32,_sizeof_uv_named_pipe))) | ||
#err = c_malloc(_sizeof_uv_named_pipe) | ||
link_pipe(stdios[3],false,err,true) | ||
close_err = true | ||
end | ||
@setup_stdio | ||
spawn(pc, cmds.a, (in,out,err), exitcb, closecb) | ||
spawn(pc, cmds.b, (in,out,err), exitcb, closecb) | ||
if(close_in) | ||
close_pipe_sync(in) | ||
#c_free(in) | ||
end | ||
if(close_out) | ||
close_pipe_sync(out) | ||
#c_free(out) | ||
end | ||
if(close_err) | ||
close_pipe_sync(err) | ||
#c_free(err) | ||
end | ||
pp | ||
@cleanup_stdio | ||
pc | ||
end | ||
|
||
|
@@ -319,22 +351,18 @@ end | |
# | \ The function to be called once the process exits | ||
# \ A set of up to 256 stdio instructions, where each entry can be either: | ||
# | - An AsyncStream to be passed to the child | ||
# | - true: This will let the child inherit the parents' io (only valid for 0-2) | ||
# \ - false: None (for 3-255) or /dev/null (for 0-2) | ||
|
||
|
||
for (sym, stdin, stdout, stderr) in {(:spawn_opts_inherit, STDIN,STDOUT,STDERR), | ||
(:spawn_opts_swallow, null_handle,null_handle,null_handle)} | ||
@eval begin | ||
($sym)(stdios::StdIOSet,exitcb::Callback,closecb::Callback) = (stdios,exitcb,closecb) | ||
($sym)(stdios::StdIOSet,exitcb::Callback) = (stdios,exitcb,false) | ||
($sym)(stdios::StdIOSet) = (stdios,false,false) | ||
($sym)() = (($stdin,$stdout,$stderr),false,false) | ||
($sym)(in::UVStream) = ((isa(in,AsyncStream)?in:$stdin,$stdout,$stderr),false,false) | ||
($sym)(in::UVStream,out::UVStream) = ((isa(in,AsyncStream)?in:$stdin,isa(out,AsyncStream)?out:$stdout,$stderr),false,false) | ||
($sym)(in::UVStream,out::UVStream,err::UVStream) = ((isa(in,AsyncStream)?in:$stdin,isa(out,AsyncStream)?out:$stdout,isa(err,AsyncStream)?err:$stderr),false,false) | ||
end | ||
end | ||
# | - null_handle to pass /dev/null | ||
# | - An FS.File object to redirect the output to | ||
# \ - An ASCIIString specifying a filename to be opened | ||
|
||
spawn_opts_swallow(stdios::StdIOSet,exitcb::Callback=false,closecb::Callback=false) = | ||
(stdios,exitcb,closecb) | ||
spawn_opts_swallow(in::Redirectable=null_handle,out::Redirectable=null_handle,err::Redirectable=null_handle,args...) = | ||
(tuple(in,out,err,args...),false,false) | ||
spawn_opts_inherit(stdios::StdIOSet,exitcb::Callback=false,closecb::Callback=false) = | ||
(stdios,exitcb,closecb) | ||
spawn_opts_inherit(in::Redirectable=STDIN,out::Redirectable=STDOUT,err::Redirectable=STDERR,args...) = | ||
(tuple(in,out,err,args...),false,false) | ||
|
||
spawn(pc::ProcessChainOrNot,cmds::AbstractCmd,args...) = spawn(pc,cmds,spawn_opts_swallow(args...)...) | ||
spawn(cmds::AbstractCmd,args...) = spawn(false,cmds,spawn_opts_swallow(args...)...) | ||
|
What about UTF8 filenames?