創建 Daemon 程式
Daemon 的原意其實就是小精靈(或是小惡魔),一般人是看不見的。而 Daemon 程式是指常駐在 Linux(或 Unix/Unix-Like)作業系統背景中執行的行程,無法被使用者直接操作或控制。這些 Daemon 可能是個 Server 在等待與處理 Client 端的請求,也可能是系統的維護程式。
行程在執行過程中將自己轉換為 daemon 一般而言要經過以下幾個步驟:
- fork() 後終止父行程,和呼叫的終端機(TTY)脫離關係
- setsid(), 成為會話組長(session leader)
- 忽略 SIGHUP 信號
- 再一次 fork() 並終止父行程
- 變更工作目錄(working directory)設定為根目錄(/)
- 將 umask 權限設置為 0
- 關閉所有檔案(file description),包含標準輸入,輸出與錯誤輸出(std in, std out and std err)。
- 將訊息記錄於log
以下簡單的程式修改自 Richard Stevens 書中的範例。
#include <stdlib.h>
#include <syslog.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAXFD 64
void
daemon_init(const char *pname, int facility)
{
int i;
pid_t pid;
if ( (pid = fork()) != 0)
exit(0); /* parent terminates */
/* 1st child continues */
setsid(); /* become session leader */
signal(SIGHUP, SIG_IGN);
if ( (pid = fork()) != 0)
exit(0); /* 1st child terminates */
/* 2nd child continues */
chdir("/"); /* change working directory */
umask(0); /* clear our file mode creation mask */
for (i=0; i<MAXFD; i++)
close(i);
openlog(pname, LOG_PID, facility);
}
int main()
{
int ii = 10;
daemon_init("TEST", 0);
while(ii) {
syslog(LOG_INFO, "daemon example ... %d", ii--);
sleep(10);
}
exit(0);
}
即便現在 Linux 標準函式庫已經有函式 int daemon(int nochdir, int noclose); 可以經由呼叫後輕鬆的轉換為 daemon 程式。但基於要了解箇中原理與運用的靈活性,還是建議自己寫寫比較踏實。
延伸閱讀
- Unix network programming. volume1. 2/e – Richard Stevens
- Linux Daemon Writing HOWTO