views:

72

answers:

2

How to add daemon stop, start and report function to this daemon code?

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>

int main(void) {

        /* Our process ID and Session ID */
        pid_t pid, sid;

        /* Fork off the parent process */
        pid = fork();
        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }

        /* Change the file mode mask */
        umask(0);

        /* Open any logs here */        

        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }



        /* Change the current working directory */
        if ((chdir("/")) < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }

        /* Close out the standard file descriptors */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);

        /* Daemon-specific initialization goes here */

        /* The Big Loop */
        while (1) {
           /* Do some task here ... */

           sleep(30); /* wait 30 seconds */
        }
   exit(EXIT_SUCCESS);
}
+1  A: 
  1. Write the pid of the daemon to /var/run/mydaemonname.pid so that you can easily look up the pid later.
  2. Set up a signal handler for SIGUSR1 and SIGUSR2.
  3. When you get SIGUSR1, toggle a stop flag.
  4. When you get SIGUSR2, set a report flag.
  5. In your while loop, check each flag.
  6. If the stop flag is set, stop until it is cleared.
  7. If the report flag it set, clear the flag and do your report.

There are some complications around stop/start, but if I'm understanding the question correctly, this should get you on the right track.

Edit: Added pid file as suggested by Dummy00001 in a comment below.

bstpierre
You might also mention creation of a pid file - so that the pid would be known without guessing.
Dummy00001
@Dummy00001 - Good call, thanks.
bstpierre
+1  A: 

First, you probably don't have to do so much forking and house keeping yourself: http://linux.die.net/man/3/daemon

Next, remember that your daemon's interface to the world is probably through some sort of shell script that you also write located in /etc/init.d or whatever other distro-defined place.

So for the above answer, your shell script would send those signals to the pid of the process. There probably is a better way though. Signaling like above is a one way process, your controlling script has to jump through race-condition-prone and fragile hoops in order to confirm if the daemon successfully stopped or restarted. I would look for precedence and examples in /etc/init.d.