函数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