Unix/Linux程式設計-建立守護程序
阿新 • • 發佈:2018-12-21
建立守護程序
#include <fcntl.h> #include <sys/resource.h> #include <syslog.h> #include <unistd.h> #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> // 守護程序通過 syslog 輸出的日誌資訊記錄在 /var/log/syslog 日誌檔案中 // 建立守護程序 void daemonize(const char *cmd) { int i, fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; // 1. 清除建立檔案掩碼 umask(0); // 2. 獲取最大檔案描述符 if(getrlimit(RLIMIT_NOFILE, &rl) < 0) { printf("%s: cannot get file limit\n", cmd); return; } // 3. 成為脫離控制終端的會話組長 if((pid = fork()) < 0) { printf("%s: cannot fork\n", cmd); return; } else if(pid != 0) // 父程序退出 { exit(0); } setsid(); // 4. 確保將來啟動守護程序不會分配控制終端 sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if(sigaction(SIGHUP, &sa, NULL) < 0) { printf("%s: cannot ignore SIGHUP\n", cmd); return; } // 再次產生子程序,使其不會成為會話首程序,防止取得控制終端 if((pid = fork()) < 0) { printf("%s: cannot fork", cmd); return; } else if(pid != 0) // 父程序退出 { exit(0); } // 5. 工作目錄切換為根目錄,這樣防止檔案系統被解除安裝 if(chdir("/") < 0) { printf("%s: cannot change directory to /", cmd); return; } // 6. 關閉所有開啟的檔案 if(rl.rlim_max == RLIM_INFINITY) { rl.rlim_max = 1024; } for(i = 0; i < rl.rlim_max; i++) { close(i); } // 7. 將檔案描述符0,1,2指向 /dev/null fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); // 8. 初始化日誌檔案 openlog(cmd, LOG_CONS, LOG_DAEMON); if(fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexcepted file descriptor %d %d %d", fd0, fd1, fd2); exit(1); } // 以上是使程序成為守護程序 // 以下的工作才是這守護程序要做的工作 i = 1; while (1) { syslog(LOG_INFO, "test - %d\n", i++); sleep(2); } }