The daemon is also commonly referred to as the Deamon process, which is a background service process in Linux. It is a long-lived process, usually independent of the control terminal and periodically performs some sort of task, or waits to handle certain occurrences
Steps to write the daemon:
1. Create a child process, and the parent process exits.
Here is a problem, because the parent process exits before the child process, causing the child process to have no parent process, thus becoming an orphan process, in Linux, each time the system discovers an orphan process, it will automatically be adopted by the 1th process (init process), so that the original child process is the INIT process of the child process
The implementation code is as follows:
Pid=fork ();
if (pid>0)
{
Exit (0);//Parent process exits
}
2. create a new session in a child process
Here's a process group. The concept of Session period
Process group: A collection of one or more processes that uniquely identifies a process group by the process group ID
Session Period: The session is a collection of one or more process groups, and the first process in the session is called the conversation leader
The function Setsid () is used to create a new session and serve as the conversation group leader with the following functions
1. Let the process get rid of the control of the original session
2. Get the process out of control of the original process group
3. Let the process please control the original control terminal
pid_t setsid (void)
Successful return to process group ID, failed return-1;
3. change when current working directory ChDir ();
Because the child process created with fork inherits the current working directory of the parent process, because the file system in which the current directory is located cannot be unloaded while the process is running, this is a lot of trouble for later use, and the usual practice is to have "/" as the current working directory of the current daemon
4. Reset File permission mask umask (0)
Setting the file permissions to 0 can enhance the daemon's flexibility
5. Close the file descriptor
As with the file mask, the new child process with the fork function inherits some open files from the parent process, which may never be accessed by the daemon, but consumes resources as well, and may cause the file system that resides on it to fail to unload
int num;
Num=getdtablesize ();//Gets the current process file descriptor size
for (int i=0;i<num;i++)
{
Close (i);
}
Examples are as follows:
void Deamon_mode (FILE *fp)
{
pid_t pid;
PID = fork ();
if (PID < 0) {
Perror ("Fail to Fork");
Exit (Exit_failure);
}
if (PID > 0) {
Exit (exit_success);
}
Create a new session
if (Setsid () < 0) {
Perror ("Fail to Fork");
Exit (Exit_failure);
}
Resetting the file mask
Umask (0);
Change the working directory of the process
ChDir ("/");
Close the unwanted file descriptor
Close (0);
Close (1);
Close (2);
redirect
Dup2 (fp->_fileno,0);
Dup2 (fp->_fileno,1);
Dup2 (fp->_fileno,2);
Return
}
A.out 0 (non-daemon) log.txt
A.. Out 1 (daemon) log.txt
int main (int argc, const char *argv[])
{
int FD;
FILE *LOG_FP;
int mode;
if (ARGC < 3) {
fprintf (stderr, "Usage:%s < mode > <log file>!\n", argv[0]);
Exit (Exit_failure);
}
mode = Atoi (argv[1]);
if (mode) {
LOG_FP = fopen (argv[2], "a");
if (log_fp = = NULL) {
fprintf (stderr, "Fail to open%s:%s!\n", Argv[2],strerror (errno));
Exit (Exit_failure);
}
Deamon_mode (LOG_FP);
}else{
LOG_FP = stderr;
}
FD = open ("Test", O_wronly | O_trunc | o_creat,0666);
if (FD < 0) {
fprintf (LOG_FP, "Fail to open%s:%s!\n", "Test", Strerror (errno));
Exit (Exit_failure);
}
fprintf (LOG_FP, "open success!\n");
Fflush (LOG_FP);
while (1)
;
return 0;
}
The above main implementation of a print log of a function, if the daemon, through the daemon print log to Log.txt, otherwise non-daemon, print to the screen
There may be a redirect dup2 here.
First Look at the man Handbook
Both DUP and dup2 can be used to copy an existing file descriptor. Often used to redirect the process of STDIN, STDOUT, STDERR.
int dup (int filedes); The function returns a new descriptor, which is a copy of the descriptor passed to it, and returns 1 if an error occurs. The new file descriptor returned by the DUP must be the smallest value in the currently available file descriptor. The new file descriptor returned by this function shares the same file data structure as the parameter filedes.
int dup2 (int filedes, int filedes2) Similarly, the function returns a new file descriptor and returns 1 if an error occurs. Unlike the DUP, dup2 can specify the value of the new descriptor with the Filedes2 parameter. If the filedes2 is already open, turn it off first. If Filedes equals Filedes2, DUP2 returns FILEDES2 without closing it. Similarly, the returned new file descriptor shares the same file data structure as the parameter filedes.
int main (int argc, const char *argv[])
{
FILE *FP;
fp = fopen (argv[1], "a");
Close (0);
Close (1);
Close (2);
#if 1
Dup2 (fp->_fileno,0);
Dup2 (fp->_fileno,1);
Dup2 (fp->_fileno,2);
#endif
printf ("Default Hello!\n");
fprintf (stdout, "stdout Hello!\n");
fprintf (stderr, "stderr Hello!\n");
Fflush (stdout);
while (1)
;
return 0;
}
Compile and run A.out Log.txt
View Cat Log.txt
The output to the control terminal should be output to the Log.txt.
In fact, the corresponding log processing there are several more commonly used:
Openlog/syslog/closelog, relatively simple, look and know!
Explore daemons and their error log processing