En la receta que te he puesto están descritos los pasos necesarios para crear un demonio:
Traducido:
1.- Si eres paranoico y estás corriendo como root, chroot a un directorio seguro:
Using perl Syntax Highlighting
chroot("/var/daemon")
or die "Couldn't chroot to /var/daemon: $!";Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
2.- fork() una vez, y deja que el padre termine:
Using perl Syntax Highlighting
$pid = fork;
exit if $pid;
die "Couldn't fork: $!" unless defined($pid);Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
3.- Cierra los tres manejadores de ficheros estándares reabriéndoles hacia /dev/null:
Using perl Syntax Highlighting
for my $handle (*STDIN, *STDOUT, *STDERR) {
open($handle, "+<", "/dev/null")
|| die "can't reopen $handle to /dev/null: $!";
}Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
4.- Disóciate de la terminal que estás usando que se usó para arrancar y deja de formar parte del grupo de procesos del que fuimos miembros:
Using perl Syntax Highlighting
use POSIX
;
POSIX
::setsid( )
or die "Can't start a new session: $!";Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
5.- Atrapa señales fatales, activando una bandera para indicar que necesitamos una forma amable de terminar:
Using perl Syntax Highlighting
$time_to_die = 0;
sub signal_handler
{
$time_to_die = 1;
}
$SIG{INT
} = $SIG{TERM
} = $SIG{HUP
} = \&signal_handler;
# trap or ignore $SIG{PIPE}Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
6.- Cubre tu código actual con un bucle:
Using perl Syntax Highlighting
until ($time_to_die) {
# ...
}Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
(Luego sigue una explicación larga de estos pasos y por qué)
Como ves, se trata de una serie de reglas para desligar al proceso demonio del que fuera su padre, su grupo de procesos, de la terminal que lo arrancó y de los canales de entrada y salida que su padre le abrió. Luego, capturas las señales fatales para saber cuándo tienes que morir. Y finalmente, el programa entra en un bucle sin fin, atendiendo a sus tareas, hasta que le dicen que se tiene que terminar.
Eso es lo que no he visto en tu código (al menos, de forma clara. Quizás me equivoque).
Quizás pase algo tan sencillo como que el hijo que crea el demonio para atender a las peticiones no cierra la conexión.
En ese caso, quizás tengas que usar shutdown() en lugar de close(), como indica la receta 17.9 (cerrar un
socket después de hacer un fork()):
Imagine a server that wants to read its client's request until end-of-file, and then send an answer. If the client calls close, that socket is now invalid for I/O, so no answer would ever come back. Instead, the client should use shutdown to half-close the connection.
que quiere decir:
Imagina un servidor que quiere leer las peticiones de su cliente hasta el fin-del-fichero, y entonces envía una respuesta. Si el cliente llama a close(), este socket es ahora inválido para E/S, así que ninguna respuesta regresará. En lugar de eso, el cliente debería usar shutdown para medio-cerrar la conexión.