OriginalMadera
Cuando traté de escribir un demonio en Linux usando C, me dijeron que debería agregar el siguiente código después tenedor bloque de código:
/* Preparations */
...
/* Fork a new process */
pid_t cpid = fork();
if (cpid == -1){perror("fork");exit(1);}
if (cpid > 0){exit(0);}
/* WHY detach from tty ? */
int fd = open("/dev/tty", O_RDWR);
ioctl(fd, TIOCNOTTY, NULL);
/* Why set PGID as current PID ? */
setpgid(getpid(), 0);
Mi pregunta es: ¿Es obligatorio hacer las operaciones anteriores?
Adán Zalcman
Debe desasociar su proceso daemon de la terminal para evitar que se le envíen señales relacionadas con el funcionamiento de la terminal (como SIGHUP cuando finaliza la sesión de la terminal, así como potencialmente SIGTTIN y SIGTTOU).
Sin embargo, tenga en cuenta que la forma de desvincularse del terminal utilizando TIOCNOTTY ioctl
está en gran parte obsoleto. Deberías usar setsid()
en cambio.
La razón por la que un daemon abandona su grupo de procesos original es no recibir señales enviadas a ese grupo. Tenga en cuenta que setsid()
también coloca su proceso en su propio grupo de procesos.
-
+1. Advertencia: incluso después de setsid(2) puede ser posible adquirir una terminal de control si no se tiene cuidado (fork() de nuevo u O_NOCTTY).
– almohada
8 de enero de 2012 a las 16:34
-
¿Tu puedes colaborar en esto? ¿Por qué el proceso en segundo plano no puede simplemente ignorar esas señales?
– Serguéi Ponomarev
31 de enero de 2019 a las 0:46
almohada
La otra respuesta es clara y técnicamente correcta (así que voté a favor en consecuencia).
Otra respuesta es: “No, no escribas código que se demonice a sí mismo”.
En su lugar, utilice un marco de supervisión de procesos (como Daemon Tools o ejecutarlo o lanzado) que se encarga de esto por usted.
El servidor UNIX tradicional se autodemoniza y, como tal, se preocupa por muchas cosas: el directorio de trabajo actual, el grupo de procesos y la independencia de la sesión, las máscaras y la disposición de las señales, la raíz del sistema de archivos, los privilegios, umask, los descriptores de archivos abiertos, etc.
Sin embargo, la mayoría o todos estos atributos de proceso se heredan a través de un exec()
lo que significa que un proceso de servidor normalmente puede “nacer” con el grupo de procesos deseado, el directorio de trabajo, la raíz, etc. Hay poca necesidad de hacer todo usted mismo, aunque a menudo aún tendrá que administrar las operaciones privilegiadas y la revocación de privilegios usted mismo.
(De hecho, yo diría que existe un riesgo a largo plazo al escribir programas que se autodemonizan. Las rutinas de “fondo” repetitivas se copian y pegan y se transfieren y amplían apresuradamente, y el programador dedica tiempo a código auxiliar en lugar de al propósito principal del programa. )
-
¡Gran respuesta! La demonización debe ser la elección de la persona que llama, no forzada por la aplicación en sí. Y para la persona que llama, hay muchas herramientas existentes, no es necesario reinventarlas en la aplicación.
– Erki Aring
16 de febrero de 2017 a las 10:50
Creo que parte de la razón es que no se espera que un demonio escriba la salida o lea la entrada. Si tuviera que iniciar, por ejemplo, un servidor HTTP en una sesión SSH, no esperaría una salida de advertencia aleatoria más adelante en la sesión.
– John Chadwick
8 de enero de 2012 a las 12:48
@JohnChadwick Lo que estás diciendo es, de hecho, una de las cosas que quieres hacer mientras te transformas en un demonio, pero lo logras cerrando stdin, stdout y stderr. Te desconectas del terminal para evitar ciertas señales (ver las respuestas a continuación).
– Adam Zalcman
8 de enero de 2012 a las 13:01
¿Puedes “no aceptar” mi respuesta y aceptar la de @AdamZalcman en su lugar? Él hace un trabajo mucho mejor que yo. Y tiene toda la razón sobre setsid(), deberías usar eso.
– fge
8 de enero de 2012 a las 13:05
@AdamZalcman Oh, cierto, en realidad me olvidé de cerrar std*. Estaba pensando que cambiar la ID del grupo de procesos impedía todas las señales relevantes, pero eso tendría mucho menos sentido, al menos en el caso de SIGHUP.
– John Chadwick
8 de enero de 2012 a las 13:06