In Unix and other multitasking computer operating systems, a daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user. Alternate terms for daemon are service (Microsoft Windows NT), subsystem (IBM z/OS), server virtual machine (IBM VM), ghost job (XDS UTS).
Systems often start 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 udevd on some GNU/Linux systems), run scheduled tasks (like cron), and perform a variety of other tasks.
In a strictly technical sense, a Unix-like system process is a daemon when its parent process terminates and the daemon is assigned 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.
In a word, a daemon has two major characteristics which distinguish a daemon from other normal processes. It runs in background, and it has no direct interactive control interface.
The common method for a process to become a daemon involves:
SYNOPSIS
#include <unistd.h>
int daemon(int nochdir, int noclose);
nochdir == 0 => chdir to ‘/’
noclose == 0 => close all inherited files
A daemon should do one thing, and do it well. That one thing may be as complex as managing hundreds of mailboxes on multiple domains, or as simple as writing a report and calling sendmail to mail it out to an admin.
Daemons should never have direct communication with a user through a terminal. In fact, a daemon shouldn't communicate directly with a user at all. All communication should pass through some sort of interface (which you may or may not have to write), which can be as complex as a GTK+ GUI, or as simple as a signal set.
To conclude, we have to plan job and interface for a daemon.
When a daemon starts up, it has to do some low-level housework to get itself ready for its real job. This involves a few steps:
One Golden Principle: Program Defensively!
//Example 1 (use daemon(3) library function to create a daemon) #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> int main(int argc, char *argv[]) { assert(argc == 3); int nochdir = atoi(argv[1]); int noclose = atoi(argv[2]); printf("Start Test Daemon\n"); int ret = daemon(nochdir, noclose); if (ret < 0) exit(EXIT_FAILURE); while(1) { sleep(1); printf("Test Daemon Running ...\n"); } printf("End Test Daemon\n"); exit(EXIT_SUCCESS); }
It seems that a daemon(3) is a simple encapsulation of forking off the parent process, change the file mode mask, creating a unique session ID, changing the current working directory and closing the standard file descriptors.
//Example 2 (use fork, umask, setsid, chdir, close, syslog …) #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <assert.h> #include <time.h> #include <string.h> #define LOG_FILE "/var/log/test_daemon.log" #define LOCK_FILE "/var/lock/test_daemon" static void CQ_log(FILE *fp, const char *msg) { assert(fp != NULL); assert(msg != NULL); struct tm *current_time = NULL; char *time_string = NULL; time_t t = time(NULL); current_time = gmtime(&t); /* the return value of gmtime is statically allocated, no need for free */ assert(current_time != NULL); time_string = asctime(current_time); assert(time_string != NULL); fwrite(time_string, sizeof(char), strlen(time_string)+1, fp); fwrite(msg, sizeof(char), strlen(msg), fp); fwrite("\n", sizeof(char), strlen("\n"), fp); fflush(fp); } int main(void) { /* process ID and session ID */ pid_t pid, sid; /* create a lock file to prevent the daemon from running twice */ int lock_fd = open(LOCK_FILE, O_RDWR | O_CREAT | O_EXCL, 0640); if (lock_fd < 0) { exit(EXIT_FAILURE); } /* fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } /* change the file mode mask */ umask(0); /* open log here */ FILE* fp_log = fopen(LOG_FILE, "a"); if (fp_log == NULL) { exit(EXIT_FAILURE); } /* create a new sid for child process */ sid = setsid(); if (sid < 0) { CQ_log(fp_log, "FAILURE: create a new session id"); exit(EXIT_FAILURE); } /* change the current working directory */ if ((chdir("/"))<0) { CQ_log(fp_log, "FAILURE: chdir to / failed"); exit(EXIT_FAILURE); } /* close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* daemon specific initialization goes here */ CQ_log(fp_log, "Start Initializing Test Daemon"); CQ_log(fp_log, "End Initializing Test Daemon"); /* the big loop */ while(1) { /* do something here */ CQ_log(fp_log, "Test Daemon Running ..."); sleep(10); } exit(EXIT_SUCCESS); }
root@localhost :/home/James/mypro/Linux-Pro/daemon# cat /var/log/test_daemon.log
Wed Jun 13 07:52:47 2012
Start Initializing Test Daemon
Wed Jun 13 07:52:47 2012
End Initializing Test Daemon
Wed Jun 13 07:52:47 2012
Test Daemon Running ...
root@localhost :/home/James/mypro/Linux-Pro/daemon# ./test_daemon
root@localhost :/home/James/mypro/Linux-Pro/daemon# echo $?
1
http://en.wikipedia.org/wiki/Daemon_(computer_software)
man daemon
man 3 setsid
man start-stop-daemon
http://www-theorie.physik.unizh.ch/~dpotter/howto/daemonize
http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
http://wenku.baidu.com/view/73a4771b227916888486d77a.html