2012-03-17 wcdj
Many services are enabled during Linux/Unix boot. These services are called daemon processes ). A daemon is a process that disconnects from the control terminal and periodically executes a task or waits for processing certain events in the background, the exit terminal is used to prevent the process information displayed on any terminal during execution and the process will not be terminated by any terminal interruption information.
General steps for creating a daemon:
(1) create a child process and exit the parent process.
In order to exit the parent process from the control terminal, all subsequent work is completed by the child process. In Linux, the parent process exits before the child process, causing the child process to become an orphan process. When the system discovers an orphan process, it is automatically adopted by process 1 (init, in this way, the original sub-process will become the sub-process of the INIT process.
PS-Ef | grep procname: view the parent-child relationship of a process using PID/ppid
(2) create a new session in the sub-process
Use the setsid function.
MAN 2 setsid view description of the setsid Function
Setsid-creates a session and sets theprocess group ID
# Include <unistd. h>
Pid_t setsid (void );
Setsid () creates a new session if thecalling process is not a process group leader. the calling process is theleader of the new session, the process group leader of the new process group, and has no controlling TTY. the process group ID and session ID
The callingprocess are set to the PID of the calling process. The Calling process will bethe only process in this new process group and in this new session.
Process Group: A collection of one or more processes. A process group is uniquely identified by a process group ID. In addition to the process id pid, the Process Group ID is also a required attribute of a process. Each process group has a leader process. The process ID of the leader process is equal to the Process Group ID, and the process group ID is not affected by the exit of the leader process.
Functions of setsid: Creates a new session and acts as the group leader. Calling setsid has three functions
(A) freeing the process from the control of the original session;
(B) freeing the process from the control of the original process group;
(C) freeing the process from the control of the original control terminal;
Purpose of using the setsid Function: The fork function is called in the first step of daemon creation to create a child process and then exit the parent process. When the fork function is called, the child process copies the session period, process group, and control terminal of the parent process. Although the parent process exits, however, the session period, process group, and control terminal have not changed. Therefore, this is not truly independent. After using the setsid function, the process can be completely independent, thus getting rid of the control of other processes.
(3) change the current directory to the root directory.
The child process created using fork inherits the current working directory of the parent process. In the process running, the file system of the current directory cannot be uninstalled, which will cause a lot of trouble for future use. Therefore, the common practice is to make the root directory "/" as the current working directory of the daemon. In this way, the above problems can be avoided. If you have special requirements, you can change the current working directory to another path. To change the working directory, use the chdir function.
(4) resetting the File Permission mask
File Permission mask: blocks the corresponding bits in the file permission. For example, if a File Permission mask is 050, the file group owner's read and executable permissions are blocked (corresponding to binary: rwx, 101 ). Because the child process created by the fork function inherits the File Permission mask of the parent process, it brings a lot of trouble for the child process to use files. Therefore, setting the File Permission mask to 0 (that is, without blocking any permissions) can enhance the flexibility of the daemon. The UMASK function is used to set the File Permission mask. The general usage is umask (0 ).
(5) disable file descriptors
The child process created with fork will also inherit some opened files from the parent process. These opened files may never be read or written by the daemon, But they consume the same system resources and may cause the file system to be unmounted. After being called using setsid, the daemon has lost contact with its control terminal. Therefore, the characters entered from the terminal cannot reach the daemon. The daemon uses conventional methods (such as printf) the output characters cannot be displayed on the terminal. Therefore, the three files with the file descriptor 0, 1, and 2 (standard input, standard output, and standard error output) have lost value and should be disabled.
(6) daemon exit
When you need to stop a daemon externally, you usually use the kill command to stop the daemon. Therefore, the daemon must be encoded to process the signal sent by kill, so that the process Exits normally.
The following is a simple implementation:
# Include <stdio. h> # include <stdlib. h> # include <string. h> # include <fcntl. h> // open # include <sys/types. h> # include <sys/STAT. h> # include <unistd. h> # include <sys/Wait. h> # include <signal. h ># define maxfile 65535 volatile sig_atomic_t _ running = 1; int FD; // signal handlervoid sigterm_handler (INT Arg) {_ running = 0;} int main () {pid_t PID; char * Buf = "this is a daemon, wcdj \ n";/* shield some signals related to control terminal operations * prevent control terminal Exited or suspended due to interference **/signal (SIGINT, sig_ign); // terminal signal (sighup, sig_ign); // connect to and stop signal (sigquit, sig_ign ); // exit signal (sigpipe, sig_ign) from the terminal; // write data signal (sigttou, sig_ign) to the pipeline without a read process; // The background program tries to write the signal (sigttin, sig_ign); // The background program attempts to read signal (sigterm, sig_ign); // terminate // test // sleep (20); // try cmd :. /Test &; kill-s sigterm PID // [1] fork child process and exit father processpid = fork (); If (PID <0) {perror ("fork er Ror! "); Exit (1);} else if (pid> 0) {exit (0);} // [2] Create a New sessionsetsid (); // [3] Set current pathchar szpath [1024]; If (getcwd (szpath, sizeof (szpath) = NULL) {perror ("getcwd "); exit (1);} else {chdir (szpath); printf ("set current path succ [% s] \ n", szpath );} // [4] umask 0 umask (0); // [5] Close useless fdint I; // for (I = 0; I <maxfile; ++ I) for (I = 3; I <maxfile; ++ I) {close (I) ;}// [6] Set termianl Signals Ignal (sigterm, sigterm_handler); // open file and set RW limitif (FD = open ("OUTFILE", o_creat | o_wronly | o_append, 0600) <0) {perror ("open"); exit (1);} printf ("\ ndaemon begin to work ..., and use kill-9 PID to terminate \ n "); // do something in loopwhile (_ running) {If (write (FD, Buf, strlen (BUF ))! = Strlen (BUF) {perror ("write"); close (FD); exit (1);} usleep (1000*1000 ); // 1 s} Close (FD); // print dataif (FD = open ("OUTFILE", o_rdonly) <0) {perror ("open "); exit (1);} Char szbuf [1024] = {0}; If (read (FD, szbuf, sizeof (szbuf) =-1) {perror ("read"); exit (1);} printf ("read 1024 bytes: \ n % s \ n", szbuf); close (FD ); return 0;}/* gcc-wall-g-o test. c ps ux | grep-V grep | grep test tail-f outfile kill-s sigterm PID */
Refer:
[1] daemon
[2]
Compile a Linux/Unix daemon
[3] Linux signal processing function
[4]
The usage of sig_atomic_t in Linux signal mask Function