sub become_daemon { die "Can't fork" unless defined (my $child = fork); exit 0 if $child; # parent dies; setsid(); # become session leader open(STDIN, "</dev/null"); open(STDOUT,">/dev/null"); open(STDERR,">&STDOUT"); chdir '/'; # change working directory umask(0); # forget file mode creation mask $ENV{PATH} = '/bin:/sbin:/usr/bin:/usr/sbin'; $SIG{CHLD} = \&reap_child; return $$; }
Una sesión es un conjunto de procesos que comparten la misma terminal. En cualquier instante solo un grupo de procesos del conjunto tiene el privilegio de leer/escribir en la terminal. Decimos que estos procesos están en foreground y que el resto de los procesos están en background. Estos procesos en foreground juegan un papel especial en el manejo de señales generadas por los caracteres de entrada.
Un grupo de sesión está relacionado pero no es exactamente lo mismo que un grupo de procesos. Un grupo de procesos es un conjunto de procesos que han sido lanzados por un padre común y se caracterizan mediante un entero (el PID del grupo) que es el PID del ancestro común.
Cuando una terminal resulta asociada con una sesión, el grupo de procesos
en foreground se establece como el grupo de procesos
del lider de sesión. La terminal asociada con una sesión
es conocida como terminal controlada.
La terminal controlada es heredada por los
hijos generados durante un fork
.
La terminal controlada
para una sesión es asignada por el lider de sesión de
una manera que es dependiente de la implementación.
Los procesos normales no pueden modificar la terminal
controlada; solo el proceso lider puede
hacerlo.
Si un proceso pertenece al grupo de procesos en foreground de su
terminal puede leer y escribir en ella; sin embargo, un proceso en el grupo de
procesos en background que intente leer o escribir en su terminal dará lugar
a la generación de una señal a su grupo de procesos14.1.
Las señales son SIGTTIN
(21) para
la lectura y SIGTTOU
(22) para la escritura.
SIGTTIN
= SIG
-TT
-IN
.
La llamada a setsid crea una nueva sesión y un nuevo grupo de procesos. El efecto total es que el proceso hijo es ahora independiente de la shell y de la terminal. Con esto conseguimos que la finalización de la shell o el cierre de la terminal no conlleven la muerte del proceso.
La llamada a setsid
falla si el proceso
era ya un lider de sesión. Esta es una de las razones para que
hayamos matado al padre y confiado la ejecución del programa
al hijo.
STDIN
STDOUT
y STDERR
al dispositivo nulo.
Se completa de esta forma el paso anterior,
impidiendo el acceso del daemon a la terminal y que sus salidas se mezclen
con las de la terminal.
La máscara de usuario es usada por open
para establecer
los permisos iniciales de un fichero recién creado.
Los permisos presentes en la máscara se desactivan.
La siguiente sesión con el depurador muestra
el funcionamiento:
pp2@nereida:~$ perl -wde 0 main::(-e:1): 0 DB<1> umask 0000 DB<2> open f, '>/tmp/tutu' # Open por defecto usa un mode 0666 DB<3> !!ls -ltr /tmp | tail -1 # 0666 and not 000 = 0666 -rw-rw-rw- 1 pp2 pp2 0 2008-05-14 10:01 tutu DB<4> umask 0777 # 0666 and not 0777 = 000 DB<5> open f, '>/tmp/tutu1' DB<6> !!ls -ltr /tmp | tail -1 ---------- 1 pp2 pp2 0 2008-05-14 10:01 tutu1 DB<7> umask 0022 DB<8> open f, '>/tmp/tutu2' DB<9> !!ls -ltr /tmp | tail -1 # 0666 and not 0022 = 0644 -rw-r--r-- 1 pp2 pp2 0 2008-05-14 10:02 tutu2 DB<10> umask 0027 DB<11> open f, '>/tmp/tutu3' # 0666 and not 0027 = 0640 DB<12> !!ls -ltr /tmp | tail -1 -rw-r----- 1 pp2 pp2 0 2008-05-14 10:06 tutu3
PATH
al mínimo número de directorios necesario
Casiano Rodríguez León