Linux Daemon In C

This is a template for a Linux daemon written in C. It includes:

  • Command-line argument handling via getopt
  • Signal Handling
  • Syslog output and filtering via setlogmask
  • Forking of process
  • Changing of file mode mask
  • Setting of Session ID
  • Closing of STDOUT, STDIN, and STDERR

The following code can be compiled using the following command (assuming gcc):

gcc -DDEBUG -o daemonname downloaded_file.c

The code:

/*
 * Example daemon shell code for all of the requirements of a basic
 * linux daemon written in C.
 *
 * To use this code, search for 'TODO' and follow the directions.
 * 
 * To compile this file:
 *      gcc -o [daemonname] thisfile.c
 *
 * Substitute gcc with cc on some platforms.
 *
 * Peter Lombardo (peter AT lombardo DOT info)
 * 5/1/2006
 *
 */
 
#include <sys /types.h>
#include </sys><sys /stat.h>
#include <stdio .h>
#include <stdlib .h>
#include <fcntl .h>
#include <errno .h>
#include <unistd .h>
#include <syslog .h>
#include <string .h>
#include <assert .h>
#include <signal .h>
 
// TODO: Change '[daemonname]' to the name of _your_ daemon
#define DAEMON_NAME "[daemonname]"
#define PID_FILE "/var/run/[daemonname].pid"
 
/**************************************************************************
    Function: Print Usage
 
    Description:
        Output the command-line options for this daemon.
 
    Params:
        @argc - Standard argument count
        @argv - Standard argument array
 
    Returns:
        returns void always
**************************************************************************/
void PrintUsage(int argc, char *argv[]) {
    if (argc >=1) {
        printf("Usage: %s -h -nn", argv[0]);
        printf("  Options:n");
        printf("      -ntDon't fork off as a daemon.n");
        printf("      -htShow this help screen.n");
        printf("n");
    }
}
 
/**************************************************************************
    Function: signal_handler
 
    Description:
        This function handles select signals that the daemon may
        receive.  This gives the daemon a chance to properly shut
        down in emergency situations.  This function is installed
        as a signal handler in the 'main()' function.
 
    Params:
        @sig - The signal received
 
    Returns:
        returns void always
**************************************************************************/
void signal_handler(int sig) {
 
    switch(sig) {
        case SIGHUP:
            syslog(LOG_WARNING, "Received SIGHUP signal.");
            break;
        case SIGTERM:
            syslog(LOG_WARNING, "Received SIGTERM signal.");
            break;
        default:
            syslog(LOG_WARNING, "Unhandled signal (%d) %s", strsignal(sig));
            break;
    }
}
 
/**************************************************************************
    Function: main
 
    Description:
        The c standard 'main' entry point function.
 
    Params:
        @argc - count of command line arguments given on command line
        @argv - array of arguments given on command line
 
    Returns:
        returns integer which is passed back to the parent process
**************************************************************************/
int main(int argc, char *argv[]) {
 
#if defined(DEBUG)
    int daemonize = 0;
#else
    int daemonize = 1;
#endif
 
    // Setup signal handling before we start
    signal(SIGHUP, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGQUIT, signal_handler);
 
    int c;
    while( (c = getopt(argc, argv, "nh|help")) != -1) {
        switch(c){
            case 'h':
                PrintUsage(argc, argv);
                exit(0);
                break;
            case 'n':
                daemonize = 0;
                break;
            default:
                PrintUsage(argc, argv);
                exit(0);
                break;
        }
    }
 
    syslog(LOG_INFO, "%s daemon starting up", DAEMON_NAME);
 
    // Setup syslog logging - see SETLOGMASK(3)
#if defined(DEBUG)
    setlogmask(LOG_UPTO(LOG_DEBUG));
    openlog(DAEMON_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
#else
    setlogmask(LOG_UPTO(LOG_INFO));
    openlog(DAEMON_NAME, LOG_CONS, LOG_USER);
#endif
 
    /* Our process ID and Session ID */
    pid_t pid, sid;
 
    if (daemonize) {
        syslog(LOG_INFO, "starting the daemonizing process");
 
        /* 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);
 
        /* 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);
    }
 
    //****************************************************
    // TODO: Insert core of your daemon processing here
    //****************************************************
 
    syslog(LOG_INFO, "%s daemon exiting", DAEMON_NAME);
 
    //****************************************************
    // TODO: Free any allocated resources before exiting
    //****************************************************
 
    exit(0);
}
 

你可能感兴趣的:(C++,c,linux,C#,gcc)