Overview
Daemons are processes that need to run in the background for a long period of time and are not controlled by the terminal, normally the daemon runs automatically at system startup, shuts down automatically when the server shuts down, and the daemon name usually ends with D, such as sshd, xinetd, Crond, ATD, and so on.
Daemon Programming rules
Call Umask to set the file mode creation mask to a known value (usually 0)
Call fork () to create a new process, which will be the future daemon
Then exit the parent process to ensure that the child process is not the process group leader
Call Setsid to create a new session
Session: is a collection of one or more process groups, usually a session begins to log on with the user and terminates when the user exits. During this time, all processes run by the user belong to this session period.
Change the current directory of the process to the root directory (if the current directory is the directory of the daemon, the current directory cannot be uninstalled, it is the working directory of the Daemon.) )
Close file descriptors that are no longer needed
REDIRECT standard input, standard output, standard error to/dev/null
Setsid
pid_t setsid (void);
Setsid () creates a new sessionif the calling process is not a process group leader. thecalling ProcessIs the leader of theNew Session, theProcess Group leaderof theNew Process Group, and has no controlling terminal. The process group ID and session ID of the The calling process is set to the PID of the calling process. The calling process is the only process in this new process group and the new session.
/* When the calling process is not the leader of a process group, SETSID creates a new session; The caller process is the only process in this session, and is the leader of the process group; the caller process ID is the group ID and the ID of the session period. Cannot call Setsid function with Process group leader */
Example: int main () { pid_t pid = fork (); if (PID = =-1) err_exit ("fork Error"); else if (pid! = 0) exit (exit_success);// /See what this section of code changes before and after the comment// pid_t id = setsid ();/ if (id = =-1)/ / err_exit ("Setsid error");// else// cout << "new Session ID =" << ID << endl; cout << "getpid =" << getpid () << Endl; cout << "Getpgid =" << Getpgid (Getpid ()) << Endl; return 0;}
RETURN VALUE
On success, the (new) session ID of the calling process is returned. On Error, (pid_t)-1 was returned, and errno is set to indicate the error.
Daemon API in Linux
int daemon (int nochdir, int noclose);
Parameters:
Nochdir:=0 changing the current directory to "/"
Noclose:=0 REDIRECT standard input, standard output, standard error to "/dev/null"
DESCRIPTION
the daemon () function is for programs wishing to detach themselves from the controlling terminal and run in the background as System daemons. if nochdir is zero, daemon () changes the calling process ' S current working directory to the root directory ("/"); otherwise, the current working directory is left Unchanged. if noclose is zero, daemon () redirects standard input, standard output and standard error to /dev/null; otherwise, no changes are made to these file descriptors.
Example: Write your own daemon function (a relatively simple example) bool Mydaemon (bool Nochdir, bool noclose) { umask (0); pid_t pid = fork (); if (PID = =-1) err_exit ("fork Error"); else if (pid! = 0) //parent exit (0); Setsid (); if (Nochdir = = 0) chdir ("/"); if (Noclose = = 0) { int i; for (i=0; i < 3; ++i) Close (i); Open ("/dev/null", O_RDWR); It is equivalent to pointing the No. 0 file descriptor to/dev/null DUP (0);//No. 0 File Description assigned value to the idle file descriptor 1 dup (0);//To describe the value of file No. 0 to the free file descriptor of 2 } , assigned. return true;} Test int main (int argc, char *argv[]) { mydaemon (0, 0);//0 means make changes (current directory, file descriptor), 1 means do not change printf ("Test ... \ n"); while (true) { sleep (1); } return 0;}
A more classic and perfect example, from "Apue" #include "apue.h" #include <syslog.h> #include <fcntl.h> #include <sys/ Resource.h>bool Mydaemon (const char *cmd); int main (int argc, char *argv[]) {Mydaemon ("Xiaofang"); while (true) {sleep (1); } return 0;} BOOL Mydaemon (const char *cmd) {umask (0); Get Maximum number of file descriptors. Rlimit RLT; if (Getrlimit (RLIMIT_NOFILE,&RLT) < 0) {err_quit ("%s:can ' t get file limit", cmd); }//become a session leader to lose controlling TTY. pid_t pid = fork (); if (PID = =-1) {err_quit ("%s:can ' t fork", CMD); } if (pid! = 0)//parent {exit (0); } setsid (); Ensure future opens won ' t allocate controlling ttys. struct Sigaction sa; Sa.sa_handler = sig_ign; Sigemptyset (&sa.sa_mask); sa.sa_flags = 0; if (Sigaction (Sighup,&sa,null) < 0) {Err_quit ("%s can ' t ignore SIGHUP", cmd); } if ((PID = fork ()) < 0) {ERR_quit ("%s:can ' t fork", CMD); } else if (pid! = 0)//second Parent {exit (exit_success); }//change the current working directory to the root if (ChDir ("/") < 0) {err_quit ("%s:can ' t change D Irectory to/", CMD); }//close all open File description if (Rlt.rlim_max = = rlim_infinity) {Rlt.rlim_max = 1024; } for (unsigned int i = 0; i < Rlt.rlim_max; ++i) {Close (i); }//attach file descriptors 0, 1, and 2 to/dev/null. int fd0 = open ("/dev/null", O_RDWR); int fd1 = DUP (0); int fd2 = DUP (0); Initialize the log file. Openlog (Cmd,log_cons,log_daemon); if (fd0! = 0 | | Fd1! = 0 | | Fd2! = 0) {syslog (Log_err, "Unexpected file descriptors%d%d%d", FD0,FD1,FD 2); Exit (Exit_failure); } return true;
Linux process Practice (5)-Daemon process