《Unix環境高級編程》初始化一個守護進程的調用,cmd可為守護進程名。
?
void daemonize( const char *cmd) { int i, fd0, fd1, fd2; pid_t pid; struct rlimit r1; struct sigaction sa;
/* 設置文件模式創建屏蔽字為0,因為繼承得來的文件模式創建屏蔽字可能會拒絕設置某些權限。 */ umask(0);
/* 獲取最大文件描述符。 */ if (getrlimit(RLIMIT_NOFILE, &r1) < 0) { err_sys(" %s: In demonize(), can't get file limit ", cmd); }
/*
* 父進程退出,第一個子進程繼承了父進程的進程組ID,但該子進程有新的進程ID,
* 這就保證了該子進程不是進程組的組長進程。為setsid準備了條件(調用setsid的進程
* 不能是進程組的組長進程)。
*/ if ((pid = fork()) < 0) { err_sys(" %s: In demonize(), can't fork ", cmd); } else if (pid != 0) { exit (0); }
/*
* 創建新會話,使第一個子進程即當前進程(因為父進程已退出)成為新會話的首進程。
* 也使第一個子進程成為新進程組的組長進程, 沒有控制終端 。
*/ setsid();
/*
* 確保將來的操作不分配終端(主要針對UNIX系統V派生的系統,當會話首進程打開
* 第一個尚未與上一個會話相關聯的終端設備時,UNIX系統V派生的系統會將此作為控制
* 終端分配給此會話。這假定會話首進程在調用open時沒指定O_NOCTTY標志。)
*/ sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGHUP, &sa, NULL) < 0) { err_sys(" %s:In demonize(), can't ignore SIGHUP "); } if ((pid = fork()) < 0) { err_sys(" %s:In demonize(), sencond can't fork ", cmd); } else if (pid != 0) { exit (0); }
/* 改變工作目錄為根目錄 */ if (chdir(" / ") < 0) { err_sys(" %s:In demonize(), can't change directory to / ", cmd) }
/* 關閉所有打開的文件描述符 */ if (r1.rlim_max == RLIM_INFINITY) { r1.rlim_max = 1024; } for (i = 0; i < r1.rlim_max; i++) { close (i); }
/* 0 1 2描述符指向/dev/null */ fd0 = open (" /dev/null ", O_RDWR); fd1 = dup(0); fd2 = dup(1);
/* 初始化系統日志 */ openlog(cmd, LOG_CONS, LOG_DAEMON); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, " unexpected file descriptiors %d %d %d ", fd0, fd1, fd2); exit (1); } }
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
