|
Packit |
437b5e |
local sig = require "posix.signal"
|
|
Packit |
437b5e |
local unistd = require "posix.unistd"
|
|
Packit |
437b5e |
local syswait = require "posix.sys.wait"
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
local function go (fn, ...)
|
|
Packit |
437b5e |
local cpid = unistd.fork ()
|
|
Packit |
437b5e |
if cpid == 0 then -- run function as child
|
|
Packit |
437b5e |
unistd._exit (fn (...) or 0)
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
return cpid
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
local verbose = #arg > 0
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
local function sleepx (secs)
|
|
Packit |
437b5e |
while true do
|
|
Packit |
437b5e |
secs = unistd.sleep (secs)
|
|
Packit |
437b5e |
if verbose then print ("sleep", secs) end
|
|
Packit |
437b5e |
if secs == 0 then return end
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
local nchild, nsig = 0, 0
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
sig.signal (sig.SIGCHLD, function()
|
|
Packit |
437b5e |
local pid, status, code = syswait.wait (-1, syswait.WNOHANG)
|
|
Packit |
437b5e |
while pid do
|
|
Packit |
437b5e |
if pid ~= 0 then
|
|
Packit |
437b5e |
if verbose then print ("wait", pid, status, code) end
|
|
Packit |
437b5e |
nchild = nchild + 1
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
pid, status, code = syswait.wait (-1, syswait.WNOHANG)
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
end)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
local function handler (signo)
|
|
Packit |
437b5e |
if verbose then print ("handled", signo) end
|
|
Packit |
437b5e |
nsig = nsig + 1
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
sig.signal (sig.SIGUSR1, handler)
|
|
Packit |
437b5e |
sig.signal (sig.SIGUSR2, handler)
|
|
Packit |
437b5e |
sig.signal (60, handler)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
local function killp (nsig)
|
|
Packit |
437b5e |
return sig.kill (unistd.getppid (), nsig)
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
c1 = go (function() unistd.sleep (1); killp (sig.SIGUSR1); killp (sig.SIGUSR2) end)
|
|
Packit |
437b5e |
c2 = go (function() unistd.sleep (2); killp (sig.SIGUSR2); end)
|
|
Packit |
437b5e |
c3 = go (function() unistd.sleep (2); killp (sig.SIGUSR1) end)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
sleepx(3)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if verbose then
|
|
Packit |
437b5e |
print ("children", nchild, "signals", nsig)
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
assert (nchild == 3)
|
|
Packit |
437b5e |
assert (nsig == 4)
|
|
Packit |
437b5e |
print '+++ tests OK +++'
|
|
Packit |
437b5e |
end
|