August 2005

Simple C Daemon Part II

In the first C Daemon article, a very basic daemon process was created that basically just ran. Some minor logging will be added, two command line opts and one arg, a purpose (of sorts) is added and finally some thoughts about software reuse are tossed in.[1]

Adding Syslog and Opts/Args

The following program now has syslog facilities plus command line options to change the default interval and whether or not logging is actually used:

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>

#define DEFAULT_INTERVAL 20
#define DEFAULT_LOGFLAG 0

/* main */
int
main(int argc, char **argv)
{
        static int      ch, interval, logflag;
        pid_t   pid, sid;

        interval = DEFAULT_INTERVAL;
        logflag  = DEFAULT_LOGFLAG;


        while ((ch = getopt(argc, argv, "lp:")) != -1) {
                switch (ch) {
                case 'l':
                        logflag = 1;
                        break;
                case 'p':
                        interval = atoi(optarg);
                        break;
                }
        }

        pid = fork();

        if (pid < 0) {
                exit(EXIT_FAILURE);
        } else if (pid > 0) {
                exit(EXIT_SUCCESS);
        }

        umask(0);

        sid = setsid();

        if (sid < 0) {
                exit(EXIT_FAILURE);
        }

        if ((chdir("/")) < 0) {
                exit(EXIT_FAILURE);
        }

        if (logflag == 1)
                syslog (LOG_NOTICE, " started by User %d", getuid ());

        while (1) {
                sleep(interval);
                printf("tic\n");
        }

        exit(EXIT_SUCCESS);
}

A lot different than the bared code - but relatively speaking still a minimal amount.

Using getopt

Using the getopt API is pretty straightforward. We grab either l or p and with p there is a required argument. The getopt code will handle any mistakes there. Note that there are default values, so the daemon can just be started without any arguments at all. No default case is specified since arguments and options are not required.

On syslog

The example of syslog is rudimentary, however, it works. In addition to the messages in the example, error messages and info messages can easily be added.

Library Help for daemons

There are a plethora of daemon tools available for administrators and programmers alike. The two that are mentioned here actually apply to each one in kind. First there is the daemontools package which can be used to replace stock system services. The second is is Phil Howard's libh software.

Daemontools [2]

Daemon tools is a services system for managing UNIX services. It is also relatively simple to plug in new or custom services and comes packed with many utilities for managing and monitoring services.

The ultimate advantage of daemontools is that it can be used across several UNIX or UNIXlike platforms. The disadvantage, in a manner of speaking, is that if one replaces their standard daemon system with it, support could be an issue (although the wiser will just keep the old system lying around just in case).

Using libh [3] [4]

The libh library is a popular set of commonly used routines that many a programmer may find they can use. Within libh there is, of course, a subset of capabilities for use with daemons. As one example, there is the code for a File Daemon. While the code may look intimidating note that it takes advantage of straightaway callbacks to the libh syslog capabilities.

Summary

Writing a basic daemon is none too difficult, however, there are tools and software out there to help along the way.

Footnotes

  1. The glibc Manual covers using syslog, getopt, sockets and much much more.
  2. Daemontools Website
  3. All of libh can be found at Phil's main libh site.
  4. A note to readers: Phil emailed the author and brought the libh capabilities point to attention. Thank you Phil.

Previous: C Daemon I