守護程序是一種純粹的後台程序,與執行前環境完全隔離,包括未關閉的檔案描述符、控制終端、會話、程序組、工作目錄以及檔案建立掩碼等
很多守護程序是父程序 fork 產生,所以會繼承所有的父程序位址空間中的環境,所以必須在守護程序誕生之初,斷絕這些相關環境,當然,守護程序也可以在 linux 系統啟動時從啟動指令碼 /etc/rc.d 中啟動,也可以由 crontab 啟動
事實上,守護程序與普通程序的編寫並沒有特別大的區別
(1)程序從建立他的父程序那裡繼承了檔案建立掩碼,它可能會修改守護程序建立的檔案的訪問位。因此需要呼叫:umask(0)
(2)呼叫fork(),然後是父程序退出exit()。這樣做實現了以下兩點:第一,如果該守護程序是通過shell命令啟動的,那麼父程序終止使得shell認為該命令已執行完畢。第二,子程序繼承了父程序的程序組id,但有乙個新的程序id,這就保證了子程序不是組長程序。
(3)呼叫setsid()以建立乙個新會話,使呼叫程序(a)成為新會話的首程序(b)成為乙個新程序組的組長程序(c)沒有控制終端
(4)將當前目錄更改為根目錄。呼叫int chdir (const char *path);
(5)關閉開啟的檔案描述符。程序從建立它的父程序那裡繼承了開啟的檔案描述符,如不關閉,將會浪費系統資源。可以通過open_max()和getrlimit()來判斷最高檔案描述符值,並關閉直到該值的所有檔案描述符。
(6)重定向標準輸入、標準輸出、錯誤輸出
示例
#include
#include
#include
#include // for exit
#include // for sigaction
#include // for syslog
#include // for umask
#include
void daemonize (const
char *cmd)
//(2)呼叫fork(),然後是父程序退出exit()
if ((pid = fork()) < 0)//
else
if (pid != 0)
//(3)呼叫setsid()建立乙個新會話
// 1. 脫離控制終端
// 2. 成為組長程序
// 3. 成為會話組首個程序
setsid();
// 忽略 sighup 訊號
// 當終端退出,會傳送該訊號給會話組長程序,預設處理方式為退出
sa.sa_handler = sig_ign;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(sighup, &sa, null) < 0)
// 再次 fork 讓守護程序不再擔當會話組長,防止他重新開啟終端
if ((pid = fork()) < 0)
if (pid != 0)
if (chdir("/") < 0)//(4)將當前目錄更改為根目錄
// (5)關閉所有檔案描述符
if (rl.rlim_max == rlim_infinity)
rl.rlim_max = 1024;
for (i=0; i// 重定向標準輸入、標準輸出、錯誤輸出到 /dev/null(5)
fd0 = open("/dev/null", o_rdwr);
fd1 = dup(0);
fd2 = dup(0);
openlog(cmd, log_cons, log_daemon);
if (fd0 != 0 || fd1 != 1 || fd2 != 2)
while (1)
}int main (int argc, char *argv)
UNIX程式設計 13 守護程序
1.守護程序的程式設計規則 1 用umask將檔案模式建立遮蔽字設定為0 2 呼叫fork,然後使父程序退出 3 呼叫setsid建立乙個新會話 4 將當前工作目錄更改為根目錄 5 關閉不再需要的的檔案描述符 6 某些守護程序開啟 dev null使其具有檔案描述符0,1,2,例 初始化乙個守護程序...
第13章守護程序總結
1 編寫守護程序基本規則 1 umake 0 將檔案模式建立遮蔽字設定為0 2 fork之後,父程序exit 3 子程序呼叫setsid 4 更改工作目錄chdir 5 關閉所有開啟的檔案描述符 6 在 dev null上開啟檔案描述符1,2,3 2 守護程序出錯處理 產生日誌訊息的三種方式 1 核...
守護程序及守護程序輸出
1 建立乙個輸出程式 2 建立乙個守護程序 1 建立乙個輸出程式 守護程序不與終端聯絡,所以,需要另外建立乙個程式用於輸出。也可以直接使用 bin echo example daemon help.cc include int main int argc,char argv else if argc...