[英]Why MUST detach from tty when writing a linux daemon?
當我嘗試使用C在linux下編寫一個守護進程時,我被告知我應該在fork代碼塊之后添加以下代碼:
/* Preparations */
...
/* Fork a new process */
pid_t cpid = fork();
if (cpid == -1){perror("fork");exit(1);}
if (cpid > 0){exit(0);}
/* WHY detach from tty ? */
int fd = open("/dev/tty", O_RDWR);
ioctl(fd, TIOCNOTTY, NULL);
/* Why set PGID as current PID ? */
setpgid(getpid(), 0);
我的問題是:是否有必要進行上述操作?
您必須取消與守護進程的關聯,以避免發送與終端操作相關的信號(如終端會話結束時的SIGHUP以及可能的SIGTTIN和SIGTTOU)。
但請注意,使用TIOCNOTTY ioctl
與終端解除關聯的方式基本上已經過時。 你應該使用setsid()
代替。
守護程序離開其原始進程組的原因是不接收發送到該組的信號。 請注意, setsid()
還會將您的流程置於其自己的流程組中。
另一個答案是明確的,技術上是正確的(所以我相應地投票)。
另一個答案是: “不,不要編寫守護自己的代碼。”
而是使用一個過程監督框架(如daemontools或runit或launchd )來處理這個問題。
傳統的UNIX服務器是自我守護的,因此可以解決許多問題:當前工作目錄,進程組和會話獨立性,信號掩碼和處置,文件系統root,特權,umask,打開文件描述符等。
但是,大多數或所有這些進程屬性都是通過exec()
繼承的,這意味着服務器進程通常可以“生成”所需的進程組,工作目錄,root等。幾乎不需要自己做所有事情,雖然您經常仍需要自己管理特權操作和特權撤銷。
(實際上,我認為編寫自我守護程序存在長期風險。鍋爐板“后台”程序被復制和粘貼並匆忙移植和擴展,程序員花時間在輔助代碼上而不是程序的主要目的上。 )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.