函數void os_daemonize(void) 將當前進程變成後臺進程即放棄終端。一開始不理解爲什麼要兩次fork,後來查網上資料得知,兩次fork是爲了防止第一個子進程打開終端。首次fork使父進程退出,子進程繼承了父進程的進程組ID,但具有一個新的進程ID,這就保證了子進程不是一個進程組的首進程。調用s e t s i d以創建一個新對話期,並使子進程成爲了首進程。再次使用fork,使父進程(第一次fork的子進程)終止,第二個子進程作爲精靈進程繼續運行。這樣就保證了該精靈進程不是對話期首進程,防止了它取得終端控制。
void os_daemonize(void)
{
if (daemonize) {
pid_t pid;
if (pipe(fds) == -1)
exit(1);
pid = fork();
if (pid > 0) {
uint8_t status;
ssize_t len;
close(fds[1]);
again:
len = read(fds[0], &status, 1);
if (len == -1 && (errno == EINTR))
goto again;
if (len != 1)
exit(1);
else if (status == 1) {
fprintf(stderr, "Could not acquire pidfile: %s\n", strerror(errno));
exit(1);
} else
exit(0);
} else if (pid < 0)
exit(1);
close(fds[0]);
qemu_set_cloexec(fds[1]);
setsid();
pid = fork();
if (pid > 0)
exit(0);
else if (pid < 0)
exit(1);
umask(027);
signal(SIGTSTP, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
}
}
轉自:http://hi.baidu.com/jyoeiken/item/9303a44a82135be91381da83