Lua: how to check if a process is running
I would like to start a process from Lua and check if the process continues.
[EDIT] I know launch can be done with os: execute, but that is blocking. I would like to find a way to start a process without blocking and monitor if it keeps running.
The following Lua library provides functions (asynchronously) for starting and monitoring processes.
http://stevedonovan.github.io/winapi/
One dumb way would be to just use io.popen () and monitor its output, or process them yourself using some other Linux tool like ps .
Another way would be to use some Lua POSIX bindings like POSIX.signal and POSIX.unistd # fork ()
If you are using luajit, you can use external function interface to call OS api functions directly. for example for Linux or similar.
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
int fork(void);
int execlp(const char* file, const char *arg, ...);
int waitpid(int pid, int *status, int options);
void _exit(int status);
unsigned int sleep(unsigned int seconds);
]]
local pid = C.fork()
if pid > 0 then -- parent
print("Waiting for child process:");
local status = ffi.new('int[1]')
local WNOHANG = 1
local done = false
while not done do
local id = C.waitpid(-1, status, WNOHANG)
if id == pid then
done = true
elseif pid < 0 then
print("error occurred")
os.exit(-1)
else
print("status=",status[0])
C.sleep(1)
-- do other stuff. We aren't waiting
end
end
print("Child exited with status=", status[0])
elseif pid == 0 then -- child
print("Starting child")
C.execlp('sleep', 'sleep', '5')
C._exit(-1) -- exec never returns
elseif pid < 0 then -- failure
print("failed to fork")
end
You will see that with WNOHANG = 1 you can still get the result to see if the child exited, but then keep doing other things.
Coroutines in Lua allow you to do what you want (since Lua 5.0):
local function Body()
print( "First resume" )
coroutine.yield()
print( "Second resume" )
coroutine.yield()
print( "Final resume" )
end
local co = coroutine.create( Body )
print( type( co ) ) -- prints "thread"
coroutine.resume( co ) -- prints "First resume"
print( "After first yield" )
coroutine.resume( co ) -- prints "Second resume"
print( "After second yield" )
coroutine.resume( co ) -- prints "Final resume"
print( coroutine.status( co ) ) -- "suspended", "dead"