added unixy extension
This commit is contained in:
parent
497960163a
commit
a11a0d1889
1 changed files with 111 additions and 0 deletions
111
xurfer/ext/unixy/main.lua
Normal file
111
xurfer/ext/unixy/main.lua
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
-- The unixy extension allows proxying api-functions through cli apps.
|
||||
-- Why?
|
||||
-- Sometimes the host OS already has cli-apps which can make up for missing lua functionality.
|
||||
-- The unixy extension is written in such way that it does not block the mainloop too much.
|
||||
-- Instead it checks whether the PID still exists at a certain interval-seconds (dtmax)
|
||||
--
|
||||
-- example of proxying an api-function to a cli app (curl):
|
||||
--
|
||||
-- api.protocol.http.request = unixy.proxyCLI(
|
||||
-- function(url,opts, cb) return string.format( "curl -v -s %s", url ) end,
|
||||
-- function( stdout, stderr, retcode, url, opts, cb)
|
||||
-- local status = 200
|
||||
-- if retcode ~= 0 then status = retcode end
|
||||
-- cb( retcode, stdout, {string = stderr}) -- todo: parse string into key/values
|
||||
-- end
|
||||
-- )
|
||||
--
|
||||
-- api.protocol.http.request( "https://2wa.isvery.ninja", {}, function(status,data,headers)
|
||||
-- print_r(status)
|
||||
-- print_r(headers)
|
||||
-- print_r(data)
|
||||
-- end)
|
||||
--
|
||||
local api = ...
|
||||
local ecs = api.ecs
|
||||
|
||||
if table.unpack == nil then
|
||||
table.unpack = unpack
|
||||
end
|
||||
|
||||
local unixy
|
||||
unixy = {
|
||||
name = "unixy",
|
||||
enabled = true,
|
||||
jobs = {},
|
||||
dtmax = 1,
|
||||
dt = 0,
|
||||
|
||||
init = function()
|
||||
end,
|
||||
|
||||
proxyCLI = function( cmdfunc, callback )
|
||||
return function(...)
|
||||
return unixy.addjob( cmdfunc, callback, ...)
|
||||
end
|
||||
end,
|
||||
|
||||
update = function(dt)
|
||||
unixy.dt = unixy.dt + dt
|
||||
if unixy.dt > unixy.dtmax then
|
||||
unixy.dt = 0
|
||||
if #unixy.jobs > 0 then
|
||||
unixy.check_jobs()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
addjob = function( cmdgen, callback, ...)
|
||||
local stdout_file = os.tmpname()
|
||||
local stderr_file = os.tmpname()
|
||||
local pid_file = os.tmpname()
|
||||
|
||||
-- Run curl in the background (&) + Save curl's PID ($!) to a file
|
||||
local cmd = cmdgen( ... )
|
||||
cmd = string.format( cmd .. " 1> %s 2> %s & echo $! > %s", stdout_file, stderr_file, pid_file)
|
||||
os.execute(cmd)
|
||||
|
||||
-- Read the PID that was generated
|
||||
local f = io.open(pid_file, "r")
|
||||
local pid = f:read("*a"):gsub("%s+", "")
|
||||
f:close()
|
||||
os.remove(pid_file) -- clean up pid file immediately
|
||||
|
||||
table.insert(unixy.jobs, {
|
||||
pid = pid,
|
||||
args = {...},
|
||||
stdout_file = stdout_file,
|
||||
stderr_file = stderr_file,
|
||||
callback = callback
|
||||
})
|
||||
trace("[unixy] start job with pid " .. pid .. " => 1> " .. stdout_file .. " 2> " .. stderr_file)
|
||||
print_r(unixy.jobs)
|
||||
end,
|
||||
|
||||
check_jobs = function()
|
||||
for i = #unixy.jobs, 1, -1 do
|
||||
local job = unixy.jobs[i]
|
||||
-- 'kill -0' doesn't kill the process, it just checks if it exists.
|
||||
local retcode = os.execute("ps -p " .. job.pid .. " > /dev/null")
|
||||
if retcode ~= 0 then
|
||||
-- Process finished! Read stdout & stderr
|
||||
local f = io.open(job.stdout_file, "r")
|
||||
local stdout = f:read("*a")
|
||||
f:close()
|
||||
f = io.open(job.stderr_file, "r")
|
||||
local stderr = f:read("*a")
|
||||
f:close()
|
||||
-- Clean up
|
||||
os.remove(job.stdout_file)
|
||||
os.remove(job.stderr_file)
|
||||
job.callback(stdout, stderr, retcode, unpack(job.args) )
|
||||
table.remove(unixy.jobs, i)
|
||||
else
|
||||
io.write(".")
|
||||
io.flush()
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
return unixy
|
||||
Loading…
Add table
Reference in a new issue