articleDaemon howto

patrickr's picture

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

Comments

Correction?

Shouldn't the call to "execute" be outside of the if-then conditional?

No. Detach, forks and then

patrickr's picture

No. Detach, forks and then calls execute in the new process.

Ok. I would have thought

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.

Syndicate content