守護程式是脫離終端並在後臺執行的程式。守護程式脫離終端是為了避免程式在執行過程中的資訊在任何終端上顯示,並且程式也不會被任何終端所產生的中斷資訊打擾。
守護程式一般生存週期都很長。一般都是默默的在後臺做一些事情,使用者不會直接感受到它的存在。
建立守護程式的步驟
1 與終端脫離
建立子程式,父程式退出。
2 在子程式中建立新會話
意義在於:讓守護程式獨立
讓程式擺脫原會話的控制
讓程式擺脫原程式組的控制
讓程式擺脫原控制終端的控制
那麼,在建立守護程式時為什麼要呼叫setsid函式呢?由於建立守護程式的第一步呼叫了fork函式來建立子程式,再將父程式退出。由於在呼叫了fork函式時,子程式全盤拷貝了父程式的會話期、程式組、控制終端等,雖然父程式退出了,但會話期、程式組、控制終端等並沒有改變,因此,這還不是真正意義上的獨立開來,而setsid函式能夠使程式完全獨立出來,從而擺脫其他程式的控制。setsid函式用於建立一個新會話,併成為該會話組的組長。
3 改變當前目錄為根目錄
釋放目錄
4 重設檔案許可權掩碼
增強守護程式的靈活性
5 關閉檔案描述符
釋放資源
6 守護程式的退出處理
接收Kill訊號,終止自己。
signal(SIGTERM, sigterm_handler);
View Code
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <string.h> #define MAXFILE 65535 int g_running; void sigterm_handler(int arg) { g_running = 0; } int main(int argc, char **argv) { pid_t pid; int i; int fd; printf("%s %d\n", argv[1], sizeof(argv[1])); pid = fork(); if (pid<0) { perror("first fork"); exit(1); } if (pid>0) //exit parent { exit(0); } else { setsid(); chdir("/"); umask(0); for (i=0; i<MAXFILE; i++) close(i); signal(SIGTERM, sigterm_handler); g_running = 1; while (g_running) { if ( (fd=open("/tmp/daemon.log", O_WRONLY | O_CREAT | O_APPEND, 0600)) < 0) { perror("open"); exit(1); } write(fd, argv[1], strlen(argv[1])); write(fd, "\n", 1); close(fd); sleep(5); } } return 1; }