Veja como Stevens acha que você deve demonizar:
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();
}
A maioria das pessoas tem duas perguntas sobre este código:
Por que
setsid()
está no primeiro filho?
Por que fazer de
fork()
novo?
Por que setsid () está no primeiro filho?
De acordo com Stevens, setsid()
ele faz três coisas importantes:
O processo se torna o líder da sessão da nova sessão, que contém apenas o processo de chamada. (PID = SID)
. (PID = SID = PGID)
.
setsid()
, .
, setsid()
, (PID = PGID), fork()
, , ( ).
setsid()
, . , , .
fork() ?
:
,
init
, . Unix ,fork()
. , , ,init
, ,waitpid()
,fork()
.fork()
waitpid()
, . , , , -init
, ,init
SIGCLD, ,init
waitpid()
.
System V
fork()
- . System V: AIX, Solaris HP-UX,fork()
, .
?
, , wait/waitpid()
, ( - !). wait/waitpid()
pid
, . .
, - . , busybox - 2005 , - , init
. , , waitpid
, .
:
,
,
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».