Daemon (computer software)

From Wikipedia, the free encyclopedia

Jump to: navigation, search

In Unix and other computer multitasking operating systems, a daemon (pronounced /ˈdiːmən/ or /ˈdeɪmən/)[1] is a computer program that runs in the background, rather than under the direct control of a user; they are usually initiated as background processes. Typically daemons have names that end with the letter "d": for example, syslogd, the daemon that handles the system log, or sshd, which handles incoming SSH connections.

In a Unix environment, the parent process of a daemon is often (but not always) the init process (PID=1). Processes usually become daemons by forking a child process and then having their parent process immediately exit, thus causing init to adopt the child process. This is a somewhat simplified view of the process as other operations are generally performed, such as disassociating the daemon process from any controlling tty. Convenience routines such as daemon(3) exist in some UNIX systems for that purpose.

Systems often start (or "launch") daemons at boot time: they often serve the function of responding to network requests, hardware activity, or other programs by performing some task. Daemons can also configure hardware (like devfsd on some Linux systems), run scheduled tasks (like cron), and perform a variety of other tasks.

Contents

[edit] Terminology

The term was coined by the programmers of MIT's Project MAC. They took the name from Maxwell's demon, an imaginary being from a famous thought experiment that constantly works in the background, sorting molecules.[2] Unix systems inherited this terminology. Daemons are also characters in Greek mythology, some of whom handled tasks that the gods could not be bothered with, much as computer daemons often handle tasks in the background that the user cannot be bothered with. BSD and some of its derivatives have adopted a daemon as its mascot, although this mascot is actually a cute variation of the demons which appear in Christian artwork.

Unix users sometimes spell daemon as demon, and most usually pronounce the word that way.

[edit] Pronunciation

The word daemon is an alternative spelling of demon, and taken out of its computer science context, it is pronounced /ˈdiːmən/ DEE-mən.[3][4][5] Perhaps due to the relative obscurity of this spelling elsewhere, the computer term daemon is sometimes pronounced incorrectly, /ˈdeɪmən/ DAY-mən.

[edit] Types of daemons

In a strictly technical sense, a Unix-like system process is a daemon when its parent process terminates and is therefore 'adopted' by the init process (process number 1) as its parent process and has no controlling terminal. However, more commonly, a daemon may be any background process, whether a child of init or not.

The common method for a process to become a daemon involves:

  • Disassociating from the controlling tty
  • Becoming a session leader
  • Becoming a process group leader
  • Staying in the background by forking and exiting (once or twice). This is required sometimes for the process to become a session leader. It also allows the parent process to continue its normal execution. This idiom is sometimes summarized with the phrase "fork off and die"
  • Setting the root directory ("/") as the current working directory so that the process will not keep any directory in use that may be on a mounted file system (allowing it to be unmounted).
  • Changing the umask to 0 to allow open(), creat(), et al. calls to provide their own permission masks and not to depend on the umask of the caller
  • Closing all inherited open files at the time of execution that are left open by the parent process, including file descriptors 0, 1 and 2 (stdin, stdout, stderr). Required files will be opened later.
  • Using a logfile, the console, or /dev/null as stdin, stdout, and stderr

[edit] Windows equivalent

In the Microsoft DOS environment, such programs were written as Terminate and Stay Resident (TSR) software. On Microsoft Windows systems, programs called services perform the functions of daemons. They run as processes, usually do not interact with the monitor, keyboard, and mouse, and may be launched by the operating system at boot time. With Windows NT and later versions, one can configure and manually start and stop Windows services using the Control Panel → Administrative Tools or typing "Services.msc" in the Run command on Start menu.

[edit] Mac OS equivalent

On the original Mac OS, optional features and services were provided by files loaded at startup time that patched the operating system; these were known as system extensions and control panels. Later versions of classic Mac OS augmented these with fully-fledged faceless background applications: regular applications that ran in the background. To the user, these were still described as regular system extensions.

Mac OS X, being a Unix system, has daemons. There is a category of software called services as well, but these are different in concept from Windows' services.

[edit] Etymology

In the general sense, daemon is an older form of the word demon. In the Unix System Administration Handbook, Evi Nemeth states the following about daemons:[6]

Many people equate the word "daemon" with the word "demon", implying some kind of satanic connection between UNIX and the underworld. This is an egregious misunderstanding. "Daemon" is actually a much older form of "demon"; daemons have no particular bias towards good or evil, but rather serve to help define a person's character or personality. The ancient Greeks' concept of a "personal daemon" was similar to the modern concept of a "guardian angel" — eudaemonia is the state of being helped or protected by a kindly spirit. As a rule, UNIX systems seem to be infested with both daemons and demons. (p.403)

[edit] Sample Program in C on Linux

   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <syslog.h>
   #include <errno.h>
   #include <pwd.h>
   #include <signal.h>
   
   /* Change this to whatever your daemon is called */
   #define DAEMON_NAME "mydaemon"
   
   /* Change this to the user under which to run */
   #define RUN_AS_USER "daemon"
   
   #define EXIT_SUCCESS 0
   #define EXIT_FAILURE 1
   
   static void child_handler(int signum)
   {
       switch(signum) {
       case SIGALRM: exit(EXIT_FAILURE); break;
       case SIGUSR1: exit(EXIT_SUCCESS); break;
       case SIGCHLD: exit(EXIT_FAILURE); break;
       }
   }
   
   static void daemonize( const char *lockfile )
   {
       pid_t pid, sid, parent;
       int lfp = -1;
       
       /* already a daemon */
       if ( getppid() == 1 ) return;
       
       /* Create the lock file as the current user */
       if ( lockfile && lockfile[0] ) {
           lfp = open(lockfile,O_RDWR|O_CREAT,0640);
           if ( lfp < 0 ) {
               syslog( LOG_ERR, "unable to create lock file %s, code=%d (%s)",
                       lockfile, errno, strerror(errno) );
               exit(EXIT_FAILURE);
           }
       }
       
       /* Drop user if there is one, and we were run as root */
       if ( getuid() == 0 || geteuid() == 0 ) {
           struct passwd *pw = getpwnam(RUN_AS_USER);
           if ( pw ) {
               syslog( LOG_NOTICE, "setting user to " RUN_AS_USER );
               setuid( pw->pw_uid );
           }
       }
       
       /* Trap signals that we expect to receive */
       signal(SIGCHLD,child_handler);
       signal(SIGUSR1,child_handler);
       signal(SIGALRM,child_handler);
       
       /* Fork off the parent process */
       pid = fork();
       if (pid < 0) {
           syslog( LOG_ERR, "unable to fork daemon, code=%d (%s)",
                   errno, strerror(errno) );
           exit(EXIT_FAILURE);
       }
       /* If we got a good PID, then we can exit the parent process. */
       if (pid > 0) {
           
           /* Wait for confirmation from the child via SIGTERM or SIGCHLD, or
              for two seconds to elapse (SIGALRM).  pause() should not return. */
           alarm(2);
           pause();
           
           exit(EXIT_FAILURE);
       }
       
       /* At this point we are executing as the child process */
       parent = getppid();
       
       /* Cancel certain signals */
       signal(SIGCHLD,SIG_DFL); /* A child process dies */
       signal(SIGTSTP,SIG_IGN); /* Various TTY signals */
       signal(SIGTTOU,SIG_IGN);
       signal(SIGTTIN,SIG_IGN);
       signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */
       signal(SIGTERM,SIG_DFL); /* Die on SIGTERM */
       
       /* Change the file mode mask */
       umask(0);
       
       /* Create a new SID for the child process */
       sid = setsid();
       if (sid < 0) {
           syslog( LOG_ERR, "unable to create a new session, code %d (%s)",
                   errno, strerror(errno) );
           exit(EXIT_FAILURE);
       }
       
       /* Change the current working directory.  This prevents the current
          directory from being locked; hence not being able to remove it. */
       if ((chdir("/")) < 0) {
           syslog( LOG_ERR, "unable to change directory to %s, code %d (%s)",
                   "/", errno, strerror(errno) );
           exit(EXIT_FAILURE);
       }
       
       /* Redirect standard files to /dev/null */
       freopen( "/dev/null", "r", stdin);
       freopen( "/dev/null", "w", stdout);
       freopen( "/dev/null", "w", stderr);
       
       /* Tell the parent process that we are A-okay */
       kill( parent, SIGUSR1 );
   }
   
   int main( int argc, char *argv[] ) {
       /* Initialize the logging interface */
       openlog( DAEMON_NAME, LOG_PID, LOG_LOCAL5 );
       syslog( LOG_INFO, "starting" );
       
       /* One may wish to process command line arguments here */
       
       /* Daemonize */
       daemonize( "/var/lock/subsys/" DAEMON_NAME );
       
       /* Now we are a daemon -- do the work for which we were paid */
       
       
       /* Finish up */
       syslog( LOG_NOTICE, "terminated" );
       closelog();
       return 0;
   }

[edit] References

[edit] See also

[edit] External links

Personal tools