diff --git a/gap/exec.g b/gap/exec.g new file mode 100644 index 00000000..74080892 --- /dev/null +++ b/gap/exec.g @@ -0,0 +1,4 @@ +BindGlobal("_ORIG_ExecuteProcess", ExecuteProcess); +MakeReadWriteGlobal("ExecuteProcess"); +ExecuteProcess := Julia.GAP.GAP_ExecuteProcess; +MakeReadOnlyGlobal("ExecuteProcess"); diff --git a/src/GAP.jl b/src/GAP.jl index ce3acf6e..86e18340 100644 --- a/src/GAP.jl +++ b/src/GAP.jl @@ -154,6 +154,7 @@ function initialize(argv::Vector{String}) GAP.Globals.Read(GapObj(joinpath(@__DIR__, "..", "gap", "pkg.g"))) GAP.Globals.Read(GapObj(joinpath(@__DIR__, "..", "gap", "repl.g"))) + GAP.Globals.Read(GapObj(joinpath(@__DIR__, "..", "gap", "exec.g"))) # If we are in "stand-alone mode", stop here if handle_signals @@ -288,6 +289,7 @@ include("utils.jl") include("help.jl") include("packages.jl") include("prompt.jl") +include("exec.jl") include("doctestfilters.jl") end diff --git a/src/exec.jl b/src/exec.jl new file mode 100644 index 00000000..57e62612 --- /dev/null +++ b/src/exec.jl @@ -0,0 +1,40 @@ +# Replacement for the GAP kernel function ExecuteProcess +const use_orig_ExecuteProcess = Ref{Bool}(false) +function GAP_ExecuteProcess(dir::GapObj, prg::GapObj, in::Int, out::Int, args::GapObj) + if use_orig_ExecuteProcess[] + return GAP.Globals._ORIG_ExecuteProcess(dir, prg, in, out, args) + end + return GAP_ExecuteProcess(String(dir), String(prg), in, out, Vector{String}(args)) +end + +function GAP_ExecuteProcess(dir::String, prg::String, fin::Int, fout::Int, args::Vector{String}) + # TODO: the GAP kernel function `ExecuteProcess` also handles so-called + # "window mode" but this function currently does not + + if fin < 0 + fin = Base.devnull + else + fin = ccall((:SyBufFileno, libgap), Int, (Culong, ), fin) + if fin == -1 + error("fin invalid") + end + fin = RawFD(fin) + end + + if fout < 0 + fout = Base.devnull + else + fout = ccall((:SyBufFileno, libgap), Int, (Culong, ), fout) + if fout == -1 + error("fout invalid") + end + fout = RawFD(fout) + end + + + # TODO: verify `dir` is a valid dir? + cd(dir) do + res = run(pipeline(`$prg $args`, stdin=fin, stdout=fout)) + return res == 255 ? GAP.Globals.Fail : res + end +end