On Unix/Linux a daemon is a program that runs in the background independent from the logged in user.
The way to achieve this is normally to directly fork after the execution and let the parent process exit. This results in the child process having lost its parent which leads to the init process automatically inheriting this process.
A simple way to do this in Eiffel is to use eposix. Simple inherit from POSXI_DAEMON and call detach.
Another thing is to implement signal handlers for several signals, this allows for example to correctly shut down a daemon.
class
MY_DAEMON
inherit
POSIX_SIGNAL_HANDLER
POSIX_CONSTANTS
export
{NONE} all
end
POSIX_DAEMON
ARGUMENTS
feature {NONE} -- Initialization
make
-- Create.
do
-- only if the -d argument is given, launch daemonized
-- this is useful as debugging with the daemonized program does not work
if argument_count = 1 and then argument (1).is_equal("-d") then
detach
else
execute
end
end
feature -- Status
is_exit: BOOLEAN
-- Should we exit?
feature {NONE} -- Implementation
execute is
-- Execute as daemon.
local
l_signal_handler: POSIX_SIGNAL
do
-- setup the signal handler for the TERM signal and call signalled.
create l_signal_handler.make (SIGTERM)
l_signal_handler.set_handler (Current)
l_signal_handler.apply
-- an infinite loop
from
until
is_exit
loop
-- do something useful
end
end
feature {NONE} -- Callbacks
signalled (signal_value: INTEGER) is
-- We received a signal.
do
if signal_value = SIGTERM then
is_exit := True
end
end
Correction?
Shouldn't the call to "execute" be outside of the if-then conditional?
No. Detach, forks and then calls execute in the new process.
Ok. I would have thought that when detach returned, after the call to fork, that execution would have continued within the if-then, and then fallen through bypassing the call to execute. I was confused, I guess, so I'll have to study it some more.