POSIXデーモン化が難しい理由


スティーブンスがあなたが悪魔化すべきだと考える方法は次のとおりです。

void daemonize(const char *cmd) {
	if ((pid = fork()) < 0)
		err(1, "fork fail");
	else if (pid != 0) /* parent */
		exit(0)
	
	/* child A */
	setsid()
 
	if ((pid = fork()) < 0)
		err(2, "fork fail");
	else if (pid != 0) /* child A * /
		exit(0)
	
	/* child B (grandchild) */
	do_daemon_stuff();
}
      
      



ほとんどの人は、このコードについて2つの質問があります。





  1. なぜsetsid()



    最初の子供にあるのですか?





  2. なぜまたやるのfork()







最初の子にsetsid()があるのはなぜですか?

スティーブンスによると、setsid()



それは3つの重要なことをします:





  1. プロセスは、呼び出しプロセスのみを含む新しいセッションのセッションリーダーになります。(PID = SID)





  2. . (PID = SID = PGID)





  3. . setsid()



    , .





, setsid()



, (PID = PGID), fork()



, , ( ).





setsid()



, . , , .





fork() ?

:





  1. , init



    , . Unix , fork()



    . , , , init



    , , waitpid()



    , fork()



    . fork()



    waitpid()



    , . , , , - init



    , , init



    SIGCLD, , init



    waitpid()



    .





  2. System V fork()



    - . System V: AIX, Solaris HP-UX, fork()



    , .





?

, , wait/waitpid()



, ( - !). wait/waitpid()



pid



, . .





, - . , busybox - 2005 , - , init



. , , waitpid



, .





:









  1. ,





  2. , wait/waitpid







, , , :





  • kernel reaper , SIGCHLD (OpenBSD).





  • exit()



    , SIGCHLD, , (XNU/OSX)





, . SIGCHLD, fork



setsid



. SIGCHLD, , wait



.





static void signal_handler(int sig) {
	int stat;
	wait(&stat);
}


void main(void) {
    struct sigaction sigact;
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGCHLD, &sigact, (struct sigaction *)NULL);
 
	if ((pid = fork()) < 0)
		err(1, "fork fail");
	else if (pid != 0)
		do_parent_stuff();
	else {
		setsid()
		do_child_stuff();
	}
}
      
      




« C».





- « C Windows». C Windows, exe-. " " .





- « C».





- « C Windows».








All Articles