signal.lua
#! /usr/bin/env lua
local M = require 'posix.signal'
local unistd = require 'posix.unistd'
local syswait = require 'posix.sys.wait'
local function go(fn, ...)
   local childpid = unistd.fork()
   if childpid == 0 then       unistd._exit(fn(...) or 0)
   else
      return childpid
   end
end
local verbose = #arg > 0
local function sleepx(secs)
   while true do
      secs = unistd.sleep(secs)
      if verbose then
         print('sleep', secs)
      end
      if secs == 0 then
         return
      end
   end
end
local nchild, nsig = 0, 0
M.signal(M.SIGCHLD, function()
   local pid, status, code = syswait.wait(-1, syswait.WNOHANG)
   while pid do
      if pid ~= 0 then
         if verbose then
            print('wait', pid, status, code)
         end
         nchild = nchild + 1
      end
      pid, status, code = syswait.wait(-1, syswait.WNOHANG)
   end
end)
local function handler(signo)
   if verbose then
      print('handled', signo)
   end
   nsig = nsig + 1
end
M.signal(M.SIGUSR1, handler)
M.signal(M.SIGUSR2, handler)
M.signal(60, handler)
local function killp(nsig)
   return M.kill(unistd.getppid(), nsig)
end
c1 = go(function() unistd.sleep(1); killp(M.SIGUSR1); killp(M.SIGUSR2) end)
c2 = go(function() unistd.sleep(2); killp(M.SIGUSR2); end)
c3 = go(function() unistd.sleep(2); killp(M.SIGUSR1) end)
sleepx(3)
if verbose then
   print('children', nchild, 'signals', nsig)
else
   assert(nchild == 3)
   assert(nsig ==   4)
   print '+++ tests OK +++'
end