eiffelroom

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

Correction?

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

patrickr's picture

No. Detach, forks and then

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.

about - contact