Contains all the common code for "daemon" programs on Linux.
This module contains all the common code for "daemon" programs (eg. servers etc.) to be run on the Linux operating system. (All this is very likely to work on all Unix systems, though it has been tested on Linux only.)
〈Overview〉 ≡
if not port? system/ports/system [
system/ports/system: open system://
]
handler!: context [
title: "Daemon"
logging: [all to output]
on-init: none
on-wakeup: none
on-quit: none
on-child-termination: none
pid-file: none
wait-loop: none
]
start-daemon: func [
"Handle signals and basic daemon functionality"
handlers [block! object!] "Handler functions and other settings"
] [
if block? handlers [handlers: make handler! handlers]
set-modes system/ports/system [
signal: [SIGINT SIGTERM SIGUSR1 SIGQUIT]
]
setup-logging handlers/logging
append-log 'info [handlers/title "starting up..."]
system/ports/system/awake: func [port /local result message pid] [
result: false
while [message: pick port 1] [
parse message [
'signal [
'SIGUSR1 (
append-log 'info ["Received SIGUSR1. Process is alive."]
handlers/on-wakeup
)
|
'SIGINT (
append-log 'info ["Received SIGINT. Quitting."]
quit
)
|
['SIGTERM | 'SIGQUIT] (
append-log 'info ["Received " uppercase form message/2 ". Quitting nicely."]
handlers/on-quit
if handlers/pid-file [delete handlers/pid-file]
result: true
)
]
|
'child set pid integer! integer! (
handlers/on-child-termination pid
)
]
]
result
]
if file? handlers/pid-file [
save handlers/pid-file first load/next %/proc/self/stat
]
handlers/on-init
either get in handlers 'wait-loop [
insert tail system/ports/wait-list system/ports/system
handlers/wait-loop
] [
; workaround for CHILD messages not waking up the system port
forever [
if port? wait [system/ports/system 10] [exit]
system/ports/system/awake system/ports/system
]
]
]